Dave:

First of the following line confirms that my initial assumptions about your
scenario was incorrect.

> [DEBUG  ] (kernel): shutdown event

The above means that the merlin kernel is automatically triggering shutdown
because as far as it is concerned, all component have been launched
successfully.

I'll explain this in a little more detail.  There are two modes of
execution:

  (a) server mode
  (b) execute mode

Using the command-line -execute option pushes merlin into execute mode as
opposed to the default server mode.  Under execute mode merlin will deploy
all components and on completion of the deployment cycle will automatically
trigger decommissioning of the system.  In you case you have started a
thread and your waiting for something to happen and in the meantime merlin
is busy working on taking you down.  This is normal behavior.

In effect, what you seem to me modeling is an executable process in which
case you should do all of your service interaction either in the
constructor, under initialize, or under the execute operation in the
framework's Executable interface.  You should not be using start/stop
semantics unless you are running a component in server mode.

Example of a component that does some activity and terminates:

/**
 * @avalon.component name="thing" lifecycle="singleton"
 * @avalon.attribute key="urn:composition:deployment.timeout" value="0"
 */
public class MyComponent implements MyListener
{

    private Boolean m_done = false;

   /**
    * @avalon.dependency type="OtherService"
    */
    public MyComponent( 
      Logger logger, ServiceManager manager )
    {
        OtherService service = 
          (OtherService) manager.lookup( "other" );
        logger.info( "starting time-consuming process" );
        service.startDoingYourStuff( this );
        while( !m_done )
        {
             try
             {
                  Thread.currentThread().sleep( 300 );
             }
             catch( Throwable whatever )
             {
                  // ignore
             }
        }

        // everything is done

        logger.info( "done time-consuming process" );        
        manager.release( service );
        logger.info( "bye-bye" );
    }

    public void notifyDone()
    {
        m_done = true;
    }
}

Warning - all of the above is from memory and it's late!  I.e. no
guarantees!

Cheers, Steve.



> -----Original Message-----
> From: David Leangen [mailto:[EMAIL PROTECTED]
> Sent: Saturday, July 31, 2004 22:29
> To: Avalon framework users
> Subject: RE: Using time-consuming services from a component
> 
> 
> Ok, most of this makes sense.
> 
> To be precise, this doesn't apply exactly to my situation. The difference
> is
> that ServiceA and ServiceB must NOT be dependent. They must be completely
> independent.
> 
> So, the "master" component should do something like this:
> 
>   Fire ServiceA
>   Wait for ServiceA to complete
>   Faire ServiceB
> 
> The way I've been attempting to wait for the completion of ServiceA is
> simply by using a listener/observer. This should work, right?
> 
> 
> Well, there's a problem, because the component won't wait for anything.
> 
> 
> I even tried a very basic case of what you described below. I made the
> component Runnable and started a new thread with a simple while loop. The
> component cleaned itself up before it was finished! If it did continue,
> then
> the logger got washed away in the process, which is not good.
> 
> So, either this should not be done (and your suggestion was wrong) or
> there
> is a bug. (Or I'm really tired and I'm overlooking something really
> obvious.)
> 
> 
> Here's a simple component. The sample output is below.
> 
> public class Component extends AbstractLogEnabled
>   implements Initializable, Serviceable, Startable, Disposable, Runnable
> {
>     private ServiceA m_serviceA = null;
>     private ServiceB m_serviceB = null;
> 
>     private Thread m_thread;
> 
>    /**
>     * Servicing of the component by the container during
>     * which service dependencies declared under the component
>     * can be resolved using the supplied service manager.
>     *
>     * @param manager the service manager
>     * @avalon.dependency type="ServiceA:1.0" key="serviceA"
>     * @avalon.dependency type="ServiceB:1.0" key="serviceB"
>     */
>     public void service( ServiceManager manager ) throws ServiceException
>     {
>         m_serviceA = (ServiceA) manager.lookup( "serviceAProvider" );
>         m_serviceB = (ServiceB) manager.lookup( "serviceBProvider" );
>     }
> 
>     public void initialize()
>     {
>         m_thread = new Thread(this);
>     }
> 
>     public void start()
>     {
>         m_thread.start();
>     }
> 
>     public void run()
>     {
>         long i = 0;
>         while(i < 500)
>         {
>             getLogger().info("Loop # " + i++);
>         }
>     }
> 
>     public void stop()
>     {
>     }
> 
>     public void dispose()
>     {
>     }
> 
> }
> 
> 
> And a part of the output:
> 
> <snip/>
> 
> [DEBUG  ] (project.Component.lifecycle): applying initialization
> [DEBUG  ] (project.Component.lifecycle): applying startup
> [DEBUG  ] (project.Component.lifecycle): component startup completed
> [DEBUG  ] (project.Component.lifecycle): incarnation complete
> [DEBUG  ] (project): commissioning of [Component] completed in 120
> milliseconds
> [INFO   ] (project.Component): Loop # 0
> [INFO   ] (project.Component): Loop # 1
> [INFO   ] (project.Component): Loop # 2
> 
> <snip/>
> 
> [INFO   ] (project.Component): Loop # 30
> [INFO   ] (project.Component): Loop # 31
> [DEBUG  ] (): commissioning of [project] completed in 320 milliseconds
> [INFO   ] (project.Component): Loop # 32
> [INFO   ] (project.Component): Loop # 33
> 
> <snip/>
> 
> [INFO   ] (project.Component): Loop # 153
> [INFO   ] (project.Component): Loop # 154
> [INFO   ] (project.Component): Loop # 155
> [DEBUG  ] (kernel): state: started
> [INFO   ] (project.Component): Loop # 156
> [INFO   ] (project.Component): Loop # 157
> [INFO   ] (project.Component): Loop # 158
> [INFO   ] (project.Component): Loop # 159
> 
> <snip/>
> 
> [INFO   ] (project.Component): Loop # 197
> [INFO   ] (project.Component): Loop # 198
> [INFO   ] (project.Component): Loop # 199
> [DEBUG  ] (kernel): shutdown event
> [DEBUG  ] (kernel): state: stopping
> [DEBUG  ] (kernel): state: decommissioning
> [DEBUG  ] (): decommissioning
> [DEBUG  ] (project): decommissioning
> [DEBUG  ] (project.Component.lifecycle): etherialization
> [INFO   ] (project.Component): Loop # 200
> [INFO   ] (project.Component): Loop # 201
> [INFO   ] (project.Component): Loop # 202
> [INFO   ] (project.Component): Loop # 203
> 
> <snip/>
> 
> [INFO   ] (project.Component): Loop # 281
> [INFO   ] (project.Component): Loop # 282
> [INFO   ] (project.Component): Loop # 283
> [INFO   ] (project.Component): Loop # 284
> [INFO   ] (project.Component): Loop # 285
> [DEBUG  ] (project.Component.lifecycle): applying shutdown
> [DEBUG  ] (project.Component.lifecycle): applying disposal
> [DEBUG  ] (kernel): state: stopped
> [DEBUG  ] (kernel): disposal
> [INFO   ] (project.Component): Loop # 286
> [INFO   ] (project.Component): Loop # 287
> [INFO   ] (project.Component): Loop # 288
> [INFO   ] (project.Component): Loop # 289
> [INFO   ] (project.Component): Loop # 290
> [INFO   ] (project.Component): Loop # 291
> [INFO   ] (project.Component): Loop # 292
> [INFO   ] (project.Component): Loop # 293
> [INFO   ] (project.Component): Loop # 294
> [INFO   ] (project.Component): Loop # 295
> [INFO   ] (project.Component): Loop # 296
> [INFO   ] (project.Component): Loop # 297
> 
> 
> And this is where it ends. As you can see, we don't get to the end!!
> 
> 
> 
> 
> 
> > -----Original Message-----
> > From: Niclas Hedhman [mailto:[EMAIL PROTECTED]
> > Sent: July 31, 2004 10:55
> > To: Avalon framework users
> > Subject: Re: Using time-consuming services from a component
> >
> >
> > On Saturday 31 July 2004 03:32, David Leangen wrote:
> > > Hello!
> > >
> > > I have created a component, as explained in the tutorials. Let's call
> it
> > > "Component". Component has two services, ServiceA and ServiceB. Both
> of
> > > these services take a while to complete, and should be executed in
> > > sequence, since ServiceB depends on the completion of ServiceA.
> > >
> > > I declare my services like this:
> >
> > You need to get your capitalization right !!! :o)
> >
> >
> > > 1. When I was using only ServiceA, I only had to make a call to
> > >    getStuff() in initialize(). At that time, I didn't really
> > >    stop to think about the mechanism. I would like to know
> > >    what actually fires off the service.
> >
> > Not sure what you are asking here.
> > Merlin will go through the life cycle methods of all components with the
> > activation set to 'startup', PLUS all the components that those
> > depends on.
> > For each component that are 'continuous' in the running, they
> > need to create
> > a thread (typically in initialize() ) and start the thread (typically in
> > start() ).
> >
> > > 2. How can I get Component to wait for the completion of
> > >    ServiceA so I can fire ServiceB?
> >
> > You should most probably declare a dependendency. If the ServiceB
> > instance
> > depends on ServiceA, then you are guaranteed that they are made
> > available in
> > correct order.
> >
> > > I tried making a direct call to serviceA.start(), but that
> > didn't work. I
> > > don't think that I should be making my service providers Runnable.
> >
> > Agreed. The service shouldn't be made a sub-interface of
> > Runnable. You can
> > make the component implement Runnable, and create a thread with
> > the component
> > instance as the Runnable.
> >
> > > So, there's something I'm not getting here...
> >
> > You will probably need something simple like this;
> >
> > /**
> >  * @avalon.component name="Comp1"
> >  *                   lifestyle="singleton"
> >  * @avalon.service type="org.hedhman.niclas.demo.ServiceA"
> >  */
> > public class Comp1
> >     implements Initializable, Startable, ServiceA,
> >                Runnable, ServiceB
> > {
> >     private Thread m_Thread;
> >     private Stuff  m_Stuff;
> >
> >     public void initialize()
> >     {
> >         m_Stuff = ...  // initialized through conf or params?
> >
> >         m_Thread = new Thread( this );
> >         // potentially more code, long time to complete
> >         // if too long, the deployment timeout needs to
> >         // be extended
> >     }.
> >
> >     public void start()
> >     {
> >         m_Thread.start();
> >     }
> >
> >     public void run()
> >     {
> >         // continuously running code
> >     }
> >
> >     public Stuff getStuff()
> >     {
> >         return m_Stuff;
> >     }
> > }
> >
> >
> > /**
> >  * @avalon.component name="Comp2"
> >  *                   lifestyle="singleton"
> >  * @avalon.service type="org.hedhman.niclas.demo.ServiceB"
> >  */
> > public class Comp2
> >     implements Serviceable, Initializable, ServiceB
> > {
> >     private ServiceA m_ServiceA;
> >
> >     /**
> >      * @avalon.dependency type="org.hedhman.niclas.demo.ServiceA"
> >      *                    key="serviceA"
> >      */
> >     public void service( ServiceManager man )
> >     {
> >         m_ServiceA = (ServiceA) man.lookup( "serviceA" );
> >     }
> >
> >     public void initialize()
> >     {
> >         // At this point, Merlin will guarantee that the
> >         // Comp1 has been initialized and there is Stuff that
> >         // can be retrieved.
> >         Stuff stuff = m_ServiceA.getStuff();
> >     }
> > }
> >
> >
> > I think this will help you on your way.
> >
> >
> > Niclas
> > --
> >    +------//-------------------+
> >   / http://www.bali.ac        /
> >  / http://niclas.hedhman.org /
> > +------//-------------------+
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]




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

Reply via email to