[External] : Re: StructuredTaskScope and Futures
Florian Schmaus
flow at cs.fau.de
Wed Jan 4 18:08:41 UTC 2023
On 04/01/2023 18.03, Alan Bateman wrote:
> On 04/01/2023 16:48, Florian Schmaus wrote:
>> I always wondered if it would be helpful if StructuredTaskScope had
>>
>> List<V> results()
>> List<Throwable> exceptions()
>>
>> As Remi wrote, it is sometimes useful to inspect the failure cases,
>> e.g., to check if it was a sporadic or persistent failure. Similar, it
>> is sometimes good to have access to all results. For example to fall
>> back to other results in case a result is not usable.
>
> The intention with StructuredTaskScope is that the API defines a small
> number of subclasses that implement common policies and for it to be
> easy to extend to implement whatever collection or policy is
> appropriate. The subclass is meant to define the methods that make
> available the results or other outcome. The "Extending
> StructuredTaskScope" section in the class description has an example
> that collects all results, and a method to get the results as a stream.
> Once we get more experience and feedback in this area then it might be
> that the two "built-in" policies that aren't the best but for now I
> think it should be easy to implement other policies.
Agreed, it later occurred to me that this can be easily implemented by
a subclass of StructedTaskScope. And, as you wrote, it may be sensible
to ship those implementations with the runtime library one day.
> Just to put more context on this discussion - the issue with fork
> returning Future is the temptation to call Future::get and wait for the
> result whereas the intention with this API is to wait in
> StructuredTaskScope::join and then process the results or outcome.
If Future is replaced with Supplier, then you still have a get() method
to call, right? So the temptation is still there (even if arguably in a
weaker form). I am also not sure how one should map the 'throws'
declarations of Future::get() to Supplier.
Which leads to me ponder if it wouldn't be better if StructuredTaskScope
would orientate more on Cilk-ish semantic. That is, fork() would return
a StructuredTaskResult with a get() method that will immediately return
the result if invoked after a join(). And otherwise, if get() is invoked
before a join point, get() would throw. So users that could not resist
the temptation and misuse get() would get immediate feedback at run
time. And I think this would make life easier for static code analysis
tools to detect cases where get() is invoked before a join().
However, I am not sure about the performance penalty of such an design.
As it brings an additional synchronization between StructuredTaskScope
and StructuredTaskResult that probably does not exist in the current API.
As always, designing a good API is hard…
- Florian
More information about the loom-dev
mailing list