Edgewall Software
Modify

Opened 13 years ago

Closed 11 years ago

#4190 closed enhancement (wontfix)

CORE - Provde an ICoreInit Extension Point with an post_init method

Reported by: ilias@… Owned by: Jonas Borgström
Priority: normal Milestone:
Component: general Version: devel
Severity: normal Keywords:
Cc: Branch:
Release Notes:
API Changes:

Description

It seems that within the __init__ method of a trac-component there is not yet every resource available (e.g. self.log.debug).

It would be nice to have something like an "ICoreInit" interface, which would provide several otpional methods.

Of main interest would be the "post_init" one (which would be called after all components are instantiated).

Attachments (0)

Change History (14)

in reply to:  description ; comment:1 by Christopher Lenz, 13 years ago

Resolution: worksforme
Status: newclosed

Replying to ilias@lazaridis.com:

It seems that within the __init__ method of a trac-component there is not yet every resource available (e.g. self.log.debug).

Incorrect, you can access self.env, self.log, and self.config. See Component member variables.

comment:2 by Noah Kantrowitz (coderanger) <coderanger@…>, 13 years ago

Also, not all components are created at once. The system waits until they are needed.

in reply to:  1 comment:3 by ilias@…, 13 years ago

Resolution: worksforme
Status: closedreopened

Replying to cmlenz:

Incorrect, you can access self.env, self.log, and self.config. See Component member variables.

class ComponentInitParticipantTest(Component):

    #implements(INavigationContributor)       

    def get_active_navigation_item(self, req):
        return 'dummy'
    def get_navigation_items(self, req):
        yield 'dummynav', 'dummy', 'dummy'

    def __init__(self):
        self.log.debug('from init')
        pass

init is not called, exept an when you enable the line "Implements", thus the component get's instantiated when navigation-items are collected. see the full context of the workaround.

If I like to participate at the initialization, an "ICoreInit" or similar would be needed, which provides a "post_init" and eventually an "pre_init" method (called before and after the component-initialization sequence).

class ComponentInitParticipantTest(Component):

    implements(ICoreInit)       

    def post_init(self):
        # do init stuff, as component is instantiated after initialization of core
        self.log.debug('from core-init')

    def __init__(self):
        self.log.debug('from init')
        pass

in reply to:  2 comment:4 by ilias@…, 13 years ago

Replying to Noah Kantrowitz (coderanger) <coderanger@yahoo.com>:

Also, not all components are created at once. The system waits until they are needed.

I understand. I had assumed that "self.log" is not available within "init", but then realized that "init" was not called (= component not instantiated).

That's one more reason for a construct like "ICoreInit".

comment:5 by Christopher Lenz, 13 years ago

As this would add initialization overhead, can you provide a reasonable use case why you'd need something like this?

in reply to:  5 ; comment:6 by ilias@…, 13 years ago

Replying to cmlenz:

As this would add initialization overhead, can you provide a reasonable use case why you'd need something like this?

Any use-case in which a core-user likes to take an action right after the core-initialization.

(btw: this is nothing special within component-models.)

the overhead would be minimal, as only components which register to the ICoreInit would introduce overhead.

A concrete use-case is this one, where I provide custom-navigation-orders (requested in #3695). Here I would simply implement the ICoreInit interface instead of using the workaround.

(In a first implementation, ICoreInit could be without any function. Any compomenent which implements ICoreInit would be instantiated immediately.)

I can provide a patch for this.

comment:7 by Noah Kantrowitz (coderanger) <coderanger@…>, 13 years ago

A simple work-around that is quite easy: implement IRequestFilter, and provide a null implementation. Filters are loaded (and initialized) as soon as the first request hits.

in reply to:  6 comment:8 by anonymous, 13 years ago

Replying to ilias@lazaridis.com:

Replying to cmlenz:

As this would add initialization overhead, can you provide a reasonable use case why you'd need something like this?

Any use-case in which a core-user likes to take an action right after the core-initialization.

Have you seen the IEnvironmentSetupParticipant interface, in source:trunk/trac/env.py? The environment_needs_upgrade method could be used to perform one time initializations once at environment startup.

comment:9 by ilias@…, 13 years ago

There are many possible workarounds, including dyna-patches etc. I use already an workaround which triggers on the first request (although the "environment_needs_upgrade" one would be more elegant).

But: my interested in this ticket is not to find a workaround.

My interest is that the trac core is extended, thus a workaround is not needed anymore.

comment:10 by Christian Boos, 12 years ago

Resolution: duplicate
Status: reopenedclosed

See #5010.

in reply to:  10 comment:11 by ilias@…, 11 years ago

Resolution: duplicate
Status: closedreopened

Replying to cboos:

See #5010.

#5010 deals with the environment level.

The currect issue affect the lower level, trac.core, independent of environments

See an implementation based on a workaround:

http://dev.lazaridis.com/base/browser/infra/tracx/tracx/core.py?rev=383

comment:12 by Christian Boos, 11 years ago

Resolution: duplicate
Status: reopenedclosed

I think the environment level is the right level for talking about "initialization".

What's the initialization at the core level anyway? The component instances are only created on first use, nothing more is done in core.py, there's no global initialization phase at that point.

Look rather at the Environment.__init__ method in env.py, here's where the initial load_components call is made and that's for the initialization phase. You can see that the IEnvironmentSetupParticipant components are then called. Further enhancements to this interface should be discussed in #5010. We can indeed imagine an environment_loaded method to complement the environment_created one. From there, you can load further components using load_components on the directory you want, or any other mean.

in reply to:  12 ; comment:13 by ilias@…, 11 years ago

Resolution: duplicate
Status: closedreopened

Replying to cboos:

I think the environment level is the right level for talking about "initialization".

What's the initialization at the core level anyway? The component instances are only created on first use, nothing more is done in core.py, there's no global initialization phase at that point.

And that's the topic of this ticket. Essentially this is a design defect.

Look rather at the `Environment.init

No need, as that's another layer, and thus another topic.

This ticket subject the core-level (or component-tlevel), not environment level

You can await some comments of other developers (which are external to trac), thus you understand the seperation ot those 2 layers.

Otherwise, you can of course close as "wontfix".

But: this is not a duplicate.

in reply to:  13 comment:14 by Christian Boos, 11 years ago

Resolution: wontfix
Status: reopenedclosed

Replying to ilias@lazaridis.com:

Replying to cboos:

What's the initialization at the core level anyway? The component instances are only created on first use, nothing more is done in core.py, there's no global initialization phase at that point.

And that's the topic of this ticket. Essentially this is a design defect.

Great, so you're welcome to reopen this ticket once you show us:

  • an alternative design (defect free, of course)
  • and a patch implementing the above design

Otherwise, you can of course close as "wontfix".

Sure. Thanks!

But: this is not a duplicate.

[Off-topic] Not in the strict sense, but we also use "duplicate" as a way to consolidate loosely related tickets when the envisioned fix for one will also take care of the others (#5010 - environment life cycle ⇒ deals with both shutdown and initialization of components).

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Jonas Borgström.
The resolution will be deleted.
to The owner will be changed from Jonas Borgström to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.