avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Merging SEDA concepts in Avalon
Date Tue, 11 Dec 2001 20:21:43 GMT
I am going through SEDA to see what concepts we can merge into Avalon and
how to best do it.  I will start by some basic subsystems like ThreadPool
management.

It is important to note that SEDA ThreadPool management is done in an
application sepecific way, however we can still probably learn something.

Peter, since the ThreadPool implementation in Excalibur Scratchpad is
your baby, I would like you to comment:

The SEDA ThreadPool interfaces implementations:

class ThreadPool extends ProfilableIF {

     ThreadPool(StageWrapperIF stage,
                ManagerIF manager,
                Runnable runnable);

     ThreadPool(StageWrapperIF stage,
                ManagerIF manager,
                Runnable runnable,
                int initialThreads,
                int minThreads,
                int blockTime,
                int idleTimeThreshold);

     ThreadPool(StageWrapperIF stage,
                ManagerIF manager,
                Runnable runnable,
                int numThreads);

     void start();
     void stop();

     long getBlockTime() //queue block time;

     int timeToStop() //should thread exit?;

     String toString();

     String getName();

     int profileSize() //from ProfilableIF--return size of object;
}

class ThreadPoolController {

     ThreadPoolController(ManagerIF manager);
     ThreadPoolController(ManagerIF manager, int delay, int threshold);

     /** Register a thread pool with this controller, using the default queue threshold */
     void register(ThreadPool tPool, ProfilableIF metric);

     /** Register a thread pool with this controller, using the specified queue threshold
*/
     void register(ThreadPool tPool, ProfilableIF metric, int threshold);
}

interface ThreadManagerIF {
      void register(StageWrapperIF stage) //specify stage with this manager;
      void deregister(StageWrapperIF stage) //deregister stage with this manager;
      void deregisterAll() // stop manager and all threads managed by it;
}

The way it works is

(Simple ThreadPerProcessor Manager)
1) ThreadManager has a background thread for each processor to manage all the Stages.
2) When a Stage is registered with the ThreadManager, the background thread
    tells the stage to handle it's events (if any).

(ThreadPoolPerSourcePerStage Manager)
1) ThreadManager has a ThreadController to manage all the ThreadPools.
2) For each Source in a Stage,
    2.1) Create a new ThreadPool for the Stage passing in the reference to
         the stage, the manager, the background thread, and any limits to the
         ThreadPool size.
    2.2) The ThreadPool is registerred with the background thread and cached
         in a hashtable
    2.3) The ThreadPool, the Source Profile, and the threshold is registerred
         with the ThreadController.
    2.4) The ThreadPool is started.
3) The ThreadController initializes a background thread and starts it.
    3.1) Every loop of the controller, the ThreadPool sizes are adjusted
         3.1.1) For every ThreadPool, the ThreadController tests the Profile
                size against the threshold.
         3.1.2) If the number of Profilable elements is over the threshold,
                the ThreadController tells the ThreadPool to add another X
                Threads and starts them.
    3.2) The ThreadController background thread sleeps for "int delay"
         milliseconds.
4) The ThreadPool manages the actual threads for the pool.  All threads run
    the *same* Runnable registered with the pool.

This is contrasted with our current ThreadPool implementation:

interface ThreadPool {
     ThreadControl execute( Runnable work );
     ThreadControl execute( Executable work );
}

interface ThreadControl {
     void join( long milliseconds )
     void interrupt()
     void isFinished();
     Throwable getThrowable();
}

The difference is that The Avalon ThreadPool is designed for a pool of threads
doing disparate things--as opposed to a pool of threads doing the *same* thing.

The question I guess is what is more desirable?  In our model, it is easier to
do small asynchronous commands (Command pattern), while the other model lends
itself to longer running threads to help parallelism in tasks that must be
run in the background.

There are strengths to both approaches, and I wanted to get a feel for what was
more common.  For instance, I can see having a maintenance task running in the
background for the duration of the runtime.  In this case, the SEDA approach is
better because it allows the number of maintenance threads to grow with the
demand on the system (up to a threshold).  In other words, all maintenance is
performed in the same thread, and all events handled in the same thread.  As
that thread gets behind in processing the events in the queue, the ThreadController
adds another thread.

On the other hand, if I have a number of medium to long length tasks that
have to be processed asynchronously, the current ThreadPool approach is
better.  This is assuming that these maintenance tasks are few and far between.
The difference is that this type of approach can potentially grow to a
number of threads that is less than ideal.

The SEDA approach favors managing many small-to-medium length tasks with the
fewest number of threads.  The Avalon approach favors managing a few medium-to-
long length tasks.

What is the feeling regarding ThreadManager/ThreadController/ThreadPool
vs. ThreadPool/ThreadControl?

I like the idea of a high level ThreadManager that controls the background
processing of event queues.  It allows the ThreadManager policy to determine
wether it will use a ThreadPool or simply a finite number of threads.  Also,
the ThreadController idea is great for managing a group of ThreadPools.

The APIs I agree need to be cleaned up, and "Avalonized" so to speak.

-- 

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


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


Mime
View raw message