river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Patricia Shanahan <p...@acm.org>
Subject Re: TaskManager progress
Date Fri, 23 Jul 2010 03:27:15 GMT
Gregg Wonderly wrote:
> I'm thinking more and more that this runAfter business should really be 
> a O(1) thing.  If runAfter() is implemented to return true, can not that 
> decision be made at the time of enqueue?  It just looks like so much of 
> this is spread around to so few actual users in the current API.  As I 
> look over the usages, there is some fuzzy logic involved in some cases 
> where the sequence number is used for ordering.  In a couple of other 
> cases, there is a specific task that another task wants to run after.  

I am generally concerned about sequence number ordering, not just at 
this level but in reading about Jini generally. The problem is what to 
do if message n has already been processed when message m, m<n, arrives.

> In the end, it seems like the API should be
> something more like
> TaskManager.addAfter( Task myTask, Task dependedOnTask );

That does not cover all the current cases, and would require multiple 
modules to keep their own Task lists and do the scans themselves.

For example, with the current system we can deal with 
many-reader-single-writer rules. A write has to wait for any access to 
the same "address". A read has to wait for writes to the same "address". 
Reads do not have to wait for each other.

> and, there would be something like
> TaskManager.addWithSequencer( Task myTask, new Sequencer() {
>     public void runAfter( List<Task> lst, int cnt ) {
>         // search lst and return result
>     }
> });
> So that simple checks can be made for "hasSequencer".  The first
> case could just result in a call like
> TaskManager.addWithSequencer( Task myTask, new Sequencer() {
>     public void runAfter( List<Task> lst, int cnt ) {
>         int idx = lst.indexOf( dependedOnTask );
>         return idx >= 0 && idx < cnt;
>     }
> });
> This would remove all of the abiguity and calling into the "return 
> false" implementations.  You could tell at the point of the add(), what 
> sequencing was going to apply, no searching back into the implementation 
> class.

The more I think about it the more I feel TaskManager represents a 
coincidental coupling between two logically distinct modules:

1. A sequencer whose business is determining whether a task is runnable.

2. A thread pool whose business is allocation of runnable tasks to threads.

Separating these functions might allow different types of sequencer, 
including a trivial one for cases in which there are no sequencing 
requirements. In some cases, tasks may be being allocated to the same 
TaskManager to share a thread pool even if they have no sequence 

That said, some of the code I've read suggests that I can probably make 
the sequencing more efficient by putting it in a utility module than it 
would be if every using module implemented it separately.


View raw message