avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Re: seperation of concerns applied: Thread Management
Date Thu, 09 Oct 2003 15:46:27 GMT
Leo Simons wrote:

<snip type="all types of useful things"/>

> 
> ==========
> Conclusion
> ==========
> We started of with a design issue: making thread management for 
> components simpler. We did some preliminary analysis and came up with a 
> very ugly solution. Through the application of COP, IoC and SoC, and 
> some heavy refactoring, we've arrived at a much better solution to our 
> problem. Along the way, we found out that we don't want thread 
> management for our components, but rather execution management.
> 
> Our new solution does not require modification of Avalon-Framework, fits 
> naturally with the average needs of Startable components, results in a 
> codebase which is largely reusable, allows advanced monitoring, error 
> recovery, load balancing, and various other things to happen 
> transparently inside advanced containers.
> 
> Clearly, COP/IoC/SoC are a winning combination when it comes to 
> facilitating reusable and keeping compact but evolvable frameworks!

You know, this is the line of thinking I had when I designed the CommandManager
in the Event package.  Maybe it could be made more generic or something, but
here me out.

I did not introduce the ThreadMonitor type of interface, but the COmmandManager
hides one or more Executors.  The main interface to it is an event Queue.
The Queue accepts Commands (an object that performs an action) and processes
them in the order received.  The Executor it uses can be a PooledExecutor (as
is now the case).  Anyhoo, there are more than one command type available.
THere is a DelayedCommand which will execute after a certain period of time.
There is also a RepeatedCommand which will keep repeating the command in the
system until the number of repeats is exhausted.  This gives the illusion of
a long running thread without occupying the thread for the full time.

In essence, we get a natural thread slicing in our system.

To rewrite your connection handling code a little it would look something like
this:

/** @avalon.component type="SocketServer" */
class ThreadedSocketServer implements SocketServer,
     Servicable, Configurable, Initializable, Startable
{
   public final static int DEFAULT_PORT = 80;
   public final static String DEFAULT_ADDRESS = "localhost";
   private int m_port;
   private String m_address;

   private Queue m_executor;

   private ServerSocket m_socket;
   private Worker m_worker;
   private ConnectionHandler m_handler;

   public void configure( Configuration conf )
     throws ConfigurationException
   {
     m_port = conf.getChild("port").getValueAsInteger( DEFAULT_PORT );
     m_address = conf.getChild("address").getValue( DEFAULT_ADDRESS );
   }
   /**
    * @avalon.dependency type="Queue"
    * @avalon.dependency type="ConnectionHandler"
    */
   public void service( ServiceManager sm ) throws ServiceException
   {
     m_executor = sm.Lookup( Queue.ROLE );
     m_handler = sm.lookup( ConnectionHandler.ROLE );
   }

   public void initialize() throws Exception
   {
     m_socket = getServerSocket();
     m_worker = new Worker();
   }

   public void start() throws Exception
   {
     m_executor.execute( m_worker );
   }

   public void stop()
   {
     m_worker.stop();
   }

   private class Worker implements RepeatedCommand  {
       public int getNumberOfRepeats() { return -1; } // don't stop

       public long getDelay() { return 0; } // start immediately

       public long getInterval() { return 100; } // every 100ms

       public void execute() throws Exception
       {
           Socket socket = m_socket.accept(); // block
           m_handler.handle( socket ); // delegate
       }
   }
}

Isn't it so much cleaner when you don't have to worry about the looping
code yourself?  Not to mention, other commands can share the same thread.
Now this does throw a monkey wrench in your ThreadMonitor type process.
That monkey wrench is that with this system, a thread is not tied to a
component.  The command is.

If a thread dies, it can be removed and handled accordingly.  The
associated component does not need to restart, the ThreadManager that the
CommandManager uses will restart the thread, and give it the command that
did not run.

Granted, the CommandManager still has some rough edges, but I also believe
it has some advantages too.  Whadayathink?

-- 

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


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Mime
View raw message