You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Ryan Shaw <ry...@silveregg.co.jp> on 2002/02/12 04:47:55 UTC

Avoiding disposal of unreleased components at system shutdown

Hello,

I have a question about the disposal of unreleased components 
at system shutdown.

Currently, it seems that when the ExcaliburComponentManager is 
disposed, it loops through all of its ComponentHandlers and calls 
dispose on each of them. The dispose implementation in 
ThreadSafeComponentHandler then simply stops and disposes the 
ThreadSafeComponent it is handling.

This seems flawed to me. Consider the following situation: 

MyComponent uses DataSourceComponent. Specifically, it obtains 
a reference to DataSourceComponent when it is initialized, and 
then when it is disposed uses it to write some state information
to a database and releases it.

DataSourceComponent is ThreadSafe, so ExcaliburComponentManager uses 
ThreadSafeComponentHandler to manage a single instance of it.

The system is shut down, which disposes the ExcaliburComponentManager.
It loops through its ComponentHandlers in no guaranteed order, so
maybe DataSourceComponent is disposed before MyComponent, ** even 
though MyComponent has not yet released DataSourceComponent **.

Thus MyComponent cannot be disposed of correctly.

If my analysis is correct, ThreadSafeComponentHandler needs to keep
reference counts, and ExcaliburComponentManager needs to check that
handlers are disposable before actually disposing them. Or maybe
the m_componentMapping could be checked at dispose() to ensure that
only released components are disposed, and a warning could be logged 
if all released components have been disposed and there are still
unreleased components? (At that point ECM could "force" disposal of
the unreleased components.) In the example above, this would force users
to release MyComponent at system shutdown before disposing of
the ExcaliburComponentManager to avoid warnings.

What do you think?

Ryan
 

 

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Berin Loritsch <bl...@apache.org>.
Ryan Shaw wrote:
> Paulo wrote:
> 
> |||       /** Releases all not-yet-released components.  */
> |||       public void releaseAll();
> 
> actually, isn't this A Bad Thing?
> 
> if something like releaseAll() were public, any 
> Composable could release all the Components being
> managed.


That is why releaseAll should have a Token.  That Token scopes the components
that are released.

Granted, I would rather have the release mechanism on the Token object,
that way there is no chance of a BadTokenException to be thrown, or possible
resource leakage by managing several tokens.

Granted, the Token approach *can* be applied regardless of what the manager
interface is (as long as the manager has a release(Object) method).  Example:

public interface ServiceManager
{
     Object lookup(Object key); // can be Query or String based role
     boolean hasResource(Object key); // can be Query or String based role
     void release(Object resource);
}

public final class Token
{
     private final ServiceManager m_manager;
     private final Buffer         m_resources;

     public Token( ServiceManager manager )
     {
         m_manager = manager;
         m_resources = new VariableSizedBuffer();
     }

     public void register(Object resource)
     {
         m_resources.add( resource );
     }

     public void releaseAll()
     {
         int size = m_resources.size();

         for (int i = 0; i < size; i++)
         {
             m_manager.release( m_resources.remove() );
         }
     }
}


The usage would be something like this:

class Example extends Servicable
{
      ServiceManager m_manager;
      Token          m_token;

      void service( ServiceManager manager )
      {
          m_manager = manager;
          m_token = new Token( manager );
      }

      void criticalSection()
      {
          Parser parser = (Parser) m_manager.lookup(Parser.ROLE);
          m_token.register( parser );

          Transformer transformer = (Transformer) m_manager.lookup(Transformer.ROLE);
          m_token.register( transformer );

          // do the critical stuff

          m_token.releaseAll();
      }
}


As you can see, we can still have a Token approach--regardless of what the
interface gives us.  While I would rather have the Manager initialize the
Token with the ServiceManager and the associated services (only exposing a
public releaseAll() method)--it can be done nonetheless.

-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: Avoiding disposal of unreleased components at system shutdown

Posted by Stephen McConnell <mc...@apache.org>.
Ryan Shaw [mailto:ryan@silveregg.co.jp]
> Paulo wrote:
> 
> |||       /** Releases all not-yet-released components.  */
> |||       public void releaseAll();
> 
> actually, isn't this A Bad Thing?
> if something like releaseAll() were public, any 
> Composable could release all the Components being
> managed.

Yep.
You need something like 

    public void release( Object token );

Cheers, Steve.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Ryan Shaw <ry...@silveregg.co.jp>.
Paulo wrote:

|||       /** Releases all not-yet-released components.  */
|||       public void releaseAll();

actually, isn't this A Bad Thing?

if something like releaseAll() were public, any 
Composable could release all the Components being
managed.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Ryan Shaw <ry...@silveregg.co.jp>.
Paulo wrote:

||| As I mentioned before, in my "ComponentManager" I keep track of 
||| components using a token.
||| 
||| <description snipped>

Yeah, that is what I initially was thinking about doing. But I 
wanted something compatible with the current CM interface.
That's what I liked about Peter's proposal; we wouldn't have to
change the interface to include a token.

I like the releaseAll() methods though. We should still be able
to add those using Peter's strategy.
 
||| > -----Original Message-----
||| > From: Peter Donald [mailto:peter@apache.org]
||| > Sent: Thursday, February 14, 2002 8:53 AM
||| > To: Avalon Developers List
||| > 
||| > 
||| > > ...
||| > >
||| > > how would the container know which components had looked up which
||| > > other components?
||| > >
||| > > suppose component X looks up component Y but never releases it.
||| > >
||| > > when disposing of X, the container knows that Y is "checked out"
||| > > but it doesn't necessarily know that X is the component that has
||| > > it checked out.
||| > 
||| > Well some implementations do track it - I think I made the 
||| > phoenix one do it 
||| > - or at least I was planning to make it do it ;) 
||| > 
||| > Everytime there is a call to lookup() your ComponentManager marks which 
||| > component was requested. You make sure that you have a separate 
||| > ComponentManager instance for each component (probably all 
||| > inheriting from a 
||| > central ComponentManager). When that component gets shutdown you 
||| > end up with 
||| > a list of components that it requested. 
||| > 
||| > Thus you know that which ones are still checked out by the dead 
||| > component :) 
||| > That make sense ?
||| > 
||| > -- 
||| > Cheers,
||| > 
||| > Pete
||| > 
||| > -------------------------------------------------------------
||| > |  Egoism is the drug that soothes the pain of stupidity.   |
||| > -------------------------------------------------------------
||| 
||| 
||| --
||| To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
||| For additional commands, e-mail: <ma...@jakarta.apache.org>
||| 
||| 

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Ryan Shaw <ry...@silveregg.co.jp>.
Peter wrote:

||| Everytime there is a call to lookup() your ComponentManager marks which 
||| component was requested. You make sure that you have a separate 
||| ComponentManager instance for each component (probably all inheriting from a 
||| central ComponentManager). When that component gets shutdown you end up with 
||| a list of components that it requested. 

i see...clever. i'm going to see if i can get something like this working.

thanks,

ryan

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: Avoiding disposal of unreleased components at system shutdown

Posted by Paulo Gaspar <pa...@krankikom.de>.
As I mentioned before, in my "ComponentManager" I keep track of 
components using a token. The interface goes (essentially) like
this:

  public class ComponentManager
  {
      /** Requests an object with a given key offering a token
       *  to identify the "set" this component belongs to.
       */
      public Object lookup(Object token, Object key);

      /** Release a previously requested component.  */
      public void release(Object component);

      /** Releases all not-yet-released components belonging 
        * to the set identified by token.
        */
      public void releaseAll(Object token);
  
      /** Releases all not-yet-released components.  */
      public void releaseAll();
  }


Obviously, any component can allocate another component from
the ComponentManager (cm) like this:

  public void initialize()
  {
      ...
      m_auxComp1 = cm.lookup(this, key1);
      m_auxComp2 = cm.lookup(this, key2);
      ...
  }

...and release them all it like this:

  public void dispose()
  {
      ...
      cm.releaseAll(this);
      ...
  }

Supposing that all components follow this convention to get
other components, the container can also release all the
components in a similar way:

  cm.releaseAll(comp1);
  someHowKillIt(comp1);

...and to really release everything, you still have:
  
  cm.releaseAll();

Would this be enough?


Have fun,
Paulo Gaspar


> -----Original Message-----
> From: Peter Donald [mailto:peter@apache.org]
> Sent: Thursday, February 14, 2002 8:53 AM
> To: Avalon Developers List
> 
> 
> > ...
> >
> > how would the container know which components had looked up which
> > other components?
> >
> > suppose component X looks up component Y but never releases it.
> >
> > when disposing of X, the container knows that Y is "checked out"
> > but it doesn't necessarily know that X is the component that has
> > it checked out.
> 
> Well some implementations do track it - I think I made the 
> phoenix one do it 
> - or at least I was planning to make it do it ;) 
> 
> Everytime there is a call to lookup() your ComponentManager marks which 
> component was requested. You make sure that you have a separate 
> ComponentManager instance for each component (probably all 
> inheriting from a 
> central ComponentManager). When that component gets shutdown you 
> end up with 
> a list of components that it requested. 
> 
> Thus you know that which ones are still checked out by the dead 
> component :) 
> That make sense ?
> 
> -- 
> Cheers,
> 
> Pete
> 
> -------------------------------------------------------------
> |  Egoism is the drug that soothes the pain of stupidity.   |
> -------------------------------------------------------------


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Peter Donald <pe...@apache.org>.
On Thu, 14 Feb 2002 17:34, Ryan Shaw wrote:
> Peter wrote:
> ||| > As long as components are looked up and released in the initialize
> ||| > and dispose methods you shouldn't be able to get into any circular
> ||| > dependency problems.
> |||
> ||| Theres no need to ever release the components if you are using it in
> ||| this fashion. The container can record which components are requested
> ||| and automatically release them when destroying the component (this is
> ||| what phoenix does because it makes it easier for block writer).
>
> how would the container know which components had looked up which
> other components?
>
> suppose component X looks up component Y but never releases it.
>
> when disposing of X, the container knows that Y is "checked out"
> but it doesn't necessarily know that X is the component that has
> it checked out.

Well some implementations do track it - I think I made the phoenix one do it 
- or at least I was planning to make it do it ;) 

Everytime there is a call to lookup() your ComponentManager marks which 
component was requested. You make sure that you have a separate 
ComponentManager instance for each component (probably all inheriting from a 
central ComponentManager). When that component gets shutdown you end up with 
a list of components that it requested. 

Thus you know that which ones are still checked out by the dead component :) 
That make sense ?

-- 
Cheers,

Pete

-------------------------------------------------------------
|  Egoism is the drug that soothes the pain of stupidity.   |
-------------------------------------------------------------

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Ryan Shaw <ry...@silveregg.co.jp>.
Peter wrote:

||| > As long as components are looked up and released in the initialize and
||| > dispose methods you shouldn't be able to get into any circular
||| > dependency problems.
||| 
||| Theres no need to ever release the components if you are using it in this 
||| fashion. The container can record which components are requested and 
||| automatically release them when destroying the component (this is what 
||| phoenix does because it makes it easier for block writer).

how would the container know which components had looked up which
other components? 

suppose component X looks up component Y but never releases it.

when disposing of X, the container knows that Y is "checked out" 
but it doesn't necessarily know that X is the component that has
it checked out.

unless you are suggesting the interface be changed to include a
callback reference to the requesting component.

ryan


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Peter Donald <pe...@apache.org>.
On Thu, 14 Feb 2002 12:53, Leif Mortenson wrote:
> I don't think that you can start things up with circular dependencies.
>  If Component A obtaines a reference to Component B in A's initialize
> method, that will work.  But if B also tries to obtain a reference to
> Component A that will fail because A has not yet been initialized.  (I
> think that it actually creates another copy of Compnent A which in turn
> creates a second copy of B etc... Going into an infinite loop... ??  I
> ran into this creating the datasource.cluster package.)

You should not be able to create circular references but it can happen unless 
you go out of your way to stop it. At different stages both ECm and phoenix 
have had similar problems with circular references creeping in.

> As long as components are looked up and released in the initialize and
> dispose methods you shouldn't be able to get into any circular
> dependency problems.

Theres no need to ever release the components if you are using it in this 
fashion. The container can record which components are requested and 
automatically release them when destroying the component (this is what 
phoenix does because it makes it easier for block writer).

-- 
Cheers,

Pete

*-----------------------------------------------------------------------*
PROGRAM: n.  a magic spell cast over a computer allowing it to turn
one's input into error messages.  v.t.  to engage in a pastime similar
to banging one's head against a wall, but with fewer opportunities for 
reward.
*-----------------------------------------------------------------------*

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Berin Loritsch <bl...@apache.org>.
Leif Mortenson wrote:
> 
> 
> Peter Donald wrote:
> 
>> On Wed, 13 Feb 2002 19:57, Leif Mortenson wrote:
>>
>>> Wouldn't it also be possible just to keep track of the number of lookups
>>> - releases.  Then when you want to dispose the ComponentManager go into
>>> a loop.  Call dispose on any components whose count is 0. Disposing them
>>> should release other components.  Repeat.  If you reach a point where
>>> you don't have any components with a count of 0, then this is an error
>>> and a warning should be displayed before going ahead and disposing the
>>> rest of them.
>>>
>>
>> Yep ... but it is a strategy I recall from my C++/COM days which I 
>> still shudder at ;) I remember quite a few cases where I had to debug 
>> each others code because components where forced to be shutdown and 
>> couldn't gracefully go down. Especially when there is circular 
>> dependencies that creep in without you noticing ;)
>>
> I don't think that you can start things up with circular dependencies. 
> If Component A obtaines a reference to Component B in A's initialize 
> method, that will work.  But if B also tries to obtain a reference to 
> Component A that will fail because A has not yet been initialized.  (I 
> think that it actually creates another copy of Compnent A which in turn 
> creates a second copy of B etc... Going into an infinite loop... ??  I 
> ran into this creating the datasource.cluster package.)
> 
> As long as components are looked up and released in the initialize and 
> dispose methods you shouldn't be able to get into any circular 
> dependency problems.


Keep in mind that the ECM uses the Lifestyle interfaces (ThreadSafe, SingleThreaded,
and Poolable).  If the instance is ThreadSafe, the component instance never changes.
That might work for you.  Also, SingleThreaded (the default) creates a new instance
per request--probably not what you want.  Lastly, Poolable has a pool of components
that it will pull the instance from.

In the case outlined above, If one of the components is ThreadSafe, you won't
get an infinite loop of instance creation.  It will happen if it is either ThreadSafe
or SingleThreaded.

That is why many components (at least in Cocoon world) wait until run-time to actually
get the component--everything is initialized then.


-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Leif Mortenson <le...@silveregg.co.jp>.

Peter Donald wrote:

>On Wed, 13 Feb 2002 19:57, Leif Mortenson wrote:
>
>>Wouldn't it also be possible just to keep track of the number of lookups
>>- releases.  Then when you want to dispose the ComponentManager go into
>>a loop.  Call dispose on any components whose count is 0. Disposing them
>>should release other components.  Repeat.  If you reach a point where
>>you don't have any components with a count of 0, then this is an error
>>and a warning should be displayed before going ahead and disposing the
>>rest of them.
>>
>
>Yep ... but it is a strategy I recall from my C++/COM days which I still 
>shudder at ;) I remember quite a few cases where I had to debug each others 
>code because components where forced to be shutdown and couldn't gracefully 
>go down. Especially when there is circular dependencies that creep in without 
>you noticing ;)
>
I don't think that you can start things up with circular dependencies. 
 If Component A obtaines a reference to Component B in A's initialize 
method, that will work.  But if B also tries to obtain a reference to 
Component A that will fail because A has not yet been initialized.  (I 
think that it actually creates another copy of Compnent A which in turn 
creates a second copy of B etc... Going into an infinite loop... ??  I 
ran into this creating the datasource.cluster package.)

As long as components are looked up and released in the initialize and 
dispose methods you shouldn't be able to get into any circular 
dependency problems.

>>This way the ComponentManager takes care of the dependencies on its own
>>without requiring the developer to set up their dependencies correctly.
>>
>
>True it is easier in shortterm and much less complex.
>
Ryan is writing a patch to fix the problems we are having and will 
submit that so you can try it out before it gets committed.

Cheers,
Leif



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Peter Donald <pe...@apache.org>.
On Wed, 13 Feb 2002 19:57, Leif Mortenson wrote:
> Wouldn't it also be possible just to keep track of the number of lookups
> - releases.  Then when you want to dispose the ComponentManager go into
> a loop.  Call dispose on any components whose count is 0. Disposing them
> should release other components.  Repeat.  If you reach a point where
> you don't have any components with a count of 0, then this is an error
> and a warning should be displayed before going ahead and disposing the
> rest of them.

Yep ... but it is a strategy I recall from my C++/COM days which I still 
shudder at ;) I remember quite a few cases where I had to debug each others 
code because components where forced to be shutdown and couldn't gracefully 
go down. Especially when there is circular dependencies that creep in without 
you noticing ;)

> This way the ComponentManager takes care of the dependencies on its own
> without requiring the developer to set up their dependencies correctly.

True it is easier in shortterm and much less complex.

-- 
Cheers,

Pete

----------------------------------------------------
"The only way to discover the limits of the possible 
is to go beyond them into the impossible." 
                             -Arthur C. Clarke
----------------------------------------------------

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Leif Mortenson <le...@silveregg.co.jp>.

Peter Donald wrote:

>On Tue, 12 Feb 2002 14:47, Ryan Shaw wrote:
>
>>I have a question about the disposal of unreleased components
>>at system shutdown.
>>
>..snip...
>
>>In the example above, this would force users
>>to release MyComponent at system shutdown before disposing of
>>the ExcaliburComponentManager to avoid warnings.
>>
>>What do you think?
>>
>
>It is a problem and the way I would solve it was being able to specify 
>dependencies between services. So service 1 can depend on service2 and so 
>forth and then you can explicitly determine the order that it is acceptable 
>to shutdown things. At least thats the way Phoenix does it ;)
>
Wouldn't it also be possible just to keep track of the number of lookups 
- releases.  Then when you want to dispose the ComponentManager go into 
a loop.  Call dispose on any components whose count is 0. Disposing them 
should release other components.  Repeat.  If you reach a point where 
you don't have any components with a count of 0, then this is an error 
and a warning should be displayed before going ahead and disposing the 
rest of them.

This way the ComponentManager takes care of the dependencies on its own 
without requiring the developer to set up their dependencies correctly.

Leif



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Avoiding disposal of unreleased components at system shutdown

Posted by Peter Donald <pe...@apache.org>.
On Tue, 12 Feb 2002 14:47, Ryan Shaw wrote:
> I have a question about the disposal of unreleased components
> at system shutdown.
..snip...
> In the example above, this would force users
> to release MyComponent at system shutdown before disposing of
> the ExcaliburComponentManager to avoid warnings.
>
> What do you think?

It is a problem and the way I would solve it was being able to specify 
dependencies between services. So service 1 can depend on service2 and so 
forth and then you can explicitly determine the order that it is acceptable 
to shutdown things. At least thats the way Phoenix does it ;)

-- 
Cheers,

Pete

---------------------------------------------------
"Marriage, Friends, Religon -- these are the demons 
you must slay in order to suceed in business.." 
                 -- Mr. Burns, The Simpsons 
---------------------------------------------------

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>