Thanks for the comments - just a quick reply to some of the many
good points (will get a bigger reply out later):

> From: news [mailto:[EMAIL PROTECTED] On Behalf Of Leo Simons
> 
> >     public interface ComponentMonitor {
> >         public void statusChange (Status status);
> >     }
> 
> the objection someone raised to this one is that it breaks 
> IoC because 
> it is a way for a component to tell the container to do 
> something. The 
> obvious way around that is to make the monitor active and have it use 
> polling, ie in my example it was:
> 
>    /** m_monitor runs a seperate thread which polls for status */
>    m_monitor.monitor( runnable, runner, m_component );

It is IoC, because the container tells the component - "Hey, when you
get a problem, I want to hear about it via this thing!"

(Consider how the military works: You don't expect the squad leader to
"poll" his soldiers - you expect the soldiers to report to him without
being prodded.)

Like Phoenix's requestShutdown() method - IoC doesn't mean that there's
no flow of information from the component to the container, just that
*the
container has the final word* regarding what is actually *done* with the
information.

I have no problem with your use of lookup() to obtain a monitor. Perhaps
even more in line would be to use the Context for this, though. (Or are
we getting rid of that one in favor of the ServiceManager?)

Regarding the multitude of status messages - I don't think that will be
any help. I don't really want to have one component notify every other
component that they're broken, because there's usually nothing the
other components can do about it.

It just removes the image I have in my mind of a component as "an
interface that I can get from a service manager that *just works*".
And I really like that. What complex things happen behind the interface
I don't want to care about! So the SocketManager throws a 
ServerPortInUseException - right, what does the RequestHandler do? Open
its own server socket? It degenerates *quickly*...

> There's an open question: why is there a neccessary and sufficient set

> of conditions for deviating from the usual approach of applying strict

> IoC? 

Strict IoC means that the container has the final word regarding what
actions are taken. We're *not* deviating in the slightest.

((((

Just throwing more into the mess - multithreading:

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

   private ServerSocket m_socket;
   private Monitor m_monitor;

   private Worker m_worker;
   private ConnectionHandler m_handler;

   public void configure( Configuration conf )
     throws ConfigurationException
   {
     m_port = conf.getChild("port").getValueAsInteger( DEFAULT_PORT );
     m_backlog = conf.getChild("backlog")
         .getValueAsInteger( DEFAULT_BACKLOG );
     m_address = conf.getChild("address").getValue( DEFAULT_ADDRESS );
   }

   /**
    * @avalon.dependency type="Executor"
    * @avalon.dependency type="ConnectionHandler"
    * @avalon.dependency type="Monitor"
    */
   public void service( ServiceManager sm ) throws ServiceException
   {
     m_executor = sm.Lookup( Executor.ROLE );
     m_handler = sm.lookup( ConnectionHandler.ROLE );
     m_monitor = sm.lookup( Monitor.ROLE );
   }

   public void initialize() throws Exception
   {
     m_socket = getNewServerSocket();
   }

   public void start() throws Exception
   {
     for( int i = 0; i < m_numThreads; i++ ) {
         m_executor.execute( new Worker() );
     }
   }

   public void stop()
   {
     m_executor.interruptAndStopAll(); // Does this method even exist?
   }

   public void dispose()
   {
     try { m_socket.close(); }
     catch( IOException ioe ) {}
   }

   protected void getNewServerSocket()
   {
     InetAddress address = InetAddress.getByName( m_address );
     ServerSocket socket =
         new ServerSocket( m_port, m_backlog, m_address );

     return socket;
   }

   private class Worker implements Runnable
   {
       private boolean running = false;

       public void stop()
       {
         running = false;
       }
       public void run()
       {
         running = true;

         while(running)
         {
           if(Thread.isInterrupted())
           {
             running = false;
             break; // die
           }

           try
           {
             Socket socket = m_socket.accept(); // block
             m_handler.handle( socket ); // delegate
           }
           catch( Throwable t )
           {
             m_monitor.statusChange( new Status( e ) );
                 // notify others
           }
         }
       }
   }
}

))))

/LS


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

Reply via email to