[concurrency-interest] CountedCompleters

Wolfgang Baltes wolfgang.baltes at laposte.net
Tue Apr 17 08:47:13 EDT 2012


Hi Doug,

thanks for the feedback. See inline.

By the way, I made a double mistake on the performance of 
quietlyJoinUnforked(). The performance degradation is negligible after 
all. I had tested it and found it to be good. Then I wrote my post and 
made some improvement, followed by another performance test. During this 
test something happened that caused a substantial delay, reason why I 
wrote the apology. But then this test turned out to be erroneous and 
further testing confirmed the initial results (no performance degradation).

W.

On 2012-04-17 13:32, Doug Lea wrote:
> Thanks for the suggestions!
>
> On 04/16/12 10:48, Wolfgang Baltes wrote:
>> 1: Symmetrically to onCompletion(), provide 
>> onExceptionalCompletion(Throwable).
>> This allows filtering exception propagation. There are cases where the
>> propagation of the exception is desired, and others where a 
>> corrective action is
>> taken instead, such as a retry.
>
> This is a good idea. One way to do it is to support
>   boolean onExceptionalCompletion(Throwable t, CountedCompleter c) {
>      return true; // default
>   }
> that returns false if the exception should not be further propagated
> to this task's completer. I had this (without a default) in several
> preliminary versions but left it out in attempt to further simplify API.
> But given that it can be done with a sensible default, it makes sense
> to reinstate it. I'll do this in next commit (which might not be for a
> week or so).

Glad to hear you will do this. This is the most important of my 
suggestions; it is the only one for which there is no work around at 
all. Thanks!
>>
>> 2: As a further enhancement to 1: enable any Throwable, including 
>> checked
>> exceptions.
>
> The issue boils down to where we'd like users to place exception
> code. In the current scheme, any task doing IO etc can do:
>   try {
>     io();
>   } catch(IOException ex) {
>      completeExceptionally(ex); // or throw new Error(ex)
>      return;
>   }
>
> ... as opposed to placing the call to compute() itself in
> a try/catch. My take is that the current scheme is a little
> easier and slightly more pleasant to use. Counter-examples
> would be welcome though.
>
This is what I do now. But there is already a try construct in the main 
worker thread loop, and this adds an extra try block. This requires some 
extra time to execute, which is even more annoying as it will be 
executed every time the task is run.
>> 3: Provide a method to join a task that is not forked and/or not 
>> completable,
>> while minimizing worker thread blocking.
>
> Whenever you find yourself wanting to do this, there are better
> alternatives that entail creating little trigger
> objects. See for example CCBoxedLongSort in
> http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/loops/
> I'll add some further examples sometime hopefully soon.
>
I am aware of the trigger object idea. You also use it in the class 
documentation for CountedCompleter. This assumes that every task can be 
split in a way as to isolate the trigger action into an "external sub 
task". This may be difficult/tricky to do when this occurs in a 
conditional or iteration constructs. In this case you would have to have 
your trigger circle back to the main task and deal with it in its 
onCompletion() method, or create longer task chains. I think this is 
possible in some cases, but difficult and awkward in others. At a 
minimum, it requires a lot of extra boilerplate code to just set up all 
the different tasks.
>
> -Doug
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>


More information about the Concurrency-interest mailing list