Stephen McConnell wrote:

Antti Koivunen wrote:

<snip/>

Also, although it makes little difference in practise, we have to acknowledge the following:

if ( context.hasEntry(KEY) ) {
obj = context.get(KEY); // Could throw NoSuchEntryException
// if the entry was just removed.
}

But this isn't really an issue, so let's include hasEntry for convenience.


Its not an issue because the container will never let it happen. If the context object has released a referecne, and it invoked get a second time, the handler just builds another or returns a pooled reference or whatever. The thing is that the container makes sure that hasEntry alway corresponds with the reality of a get().
OK, I know this sounds like nitpicking, but how would you ensure this implementation-wise (using a ThreadLocal?). Consider the following:

if ( context.hasEntry( KEY ) ) {
Thread.sleep(100000);
// Is the entry still there even if someone decided to do
// container management and mess up the context?
}

The Thread.sleep() above could be GC kicking in. The point is that I don't want any loose contracts in the core. A call to context.hasEntry() cannot indefinitely block management operations on a particular component, even if context.get() isn't called.

<snip/>

There is a real scalability issue. Think about a deployed enterprise application; there might be one configuration change a month and 10 000 calls to suspend() and resume().


In this sort of a scenario I would take a lot more control over container/component contract (via extensions for example) - get the container to provide some specific change handler that provides the details of what features need updating - if any. I'm also assuming that suspension/resumption will only occur in order to introduce a change of state from the container (i.e. one a month). I'm not looking at suspend/resume suporting any other semantics. Keep in mind that suspension of one component implies suspension of all components that are consuming services from the target. Once the target is resumed, the dependent service can resume - however - the behaviour of the service may have changed as a result of new state. From this point of view - I don't see 10,000 calls to suspend/resume (or perhaps I don't want to imagine 10,000 calls to suspend/resume given the implications on associated components).
OK, I misunderstood the contract. I thought Handle.access()/release() would trigger resume()/suspend() (~ one HTTP request), but obviously this is not the case. The semantics you describe above are, in fact, asynchronous in nature, and I can see why they're important for component assembly. Thanks for clearing this out!


Looking at this purely for the context point of view - things are manageble, but configuration changes are a lot more complicated. I've through about a number of scenarios such as a component registering listeners on particular notes - etc. but it always ends up icky. A simpler solution could be to simply tag artifacts as modified and then just redo configuration, contextualization, etc. The component could do something like:

public void reconfigure( Configuration config ) throws ConfigurationException
{
if( config.isModifiedSince( m_timestamp ) )
{
// configuration contains a modified value so we need
// check any volatile children
}

m_timestamp = new Date();
}
I think we could make this even simpler and more generic, e.g.

  void resume( Object[] theKeysOfTheChangedContextEntries );

One of the changed entries could be an instance of Configuration.

(: A ;)
--
Antti Koivunen (Mr.) <[EMAIL PROTECTED]>


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to