Structured Concurrency yet again
Holo The Sage Wolf
holo3146 at gmail.com
Wed May 10 16:23:41 UTC 2023
> The problem is that unlike any other classes in java.util.concurrent, STS
is not thread safe by default, it requires to carefully implement any
subclasses in a thread safe way.
Yes, it is true, this is a result of the fact that structured concurrency
is designed to be similar, and to be easily integrated, with a imperative
style programming.
> the implementation provided by Holo may not work because [...]
All of those are of course true, to make it production ready you would need
to add locks, the moment you add locks you can also solve the O(n) problem.
> I would prefer to provide an API easier to use
Again, this is true. I would like to have as part of the default
implementations an implementation of STS that have a good Short-circuit
strategy as a parameter (and a Transformer is a nice to have as well)
> I believe that having a method join() that takes a function that takes a
stream is easier to use correctly
This is the first place I disagree with you. Before explaining more why I
disagree I need to point out, implementing a STS that have a `await(Stream
-> T) -> T method that works as you described is possible, and it is in
fact *extremely* similar to the example I have (±locks I omitted and data
structures), you can make it and use it everywhere (I'm aware that there
are nuances here, but I believe you can overcome them).
Now, I *strongly* against putting such implementation in the
j.u.concurrency, the API you described encourages a paradigm that is not
what the API is aiming for, what you really want to write is not
T result;
try (var scope = ...) { \\ 0
scope.fork(...); \\1
for (...) { \\ 2
scope.fork(...); \\ 3
}
result = scope.await(out -> out.flatMap(...)); \\4
}
But rather:
T result =
new StructuredTaskStream(...) \\ 0
.fork(...) \\ 1
.takeWhile(...) \\ 2
.fork(...) \\ 3
.flatMap(...); \\ 4
Which is a different paradigm, and indeed a different implementation of
structures concurrency **as long as** you guarantee that after the scope of
any terminating operator all of the tasks ended, successfully or otherwise.
Such API can work, and I know people who prefer that style, but this
doesn't change the fact that the STScope is not designed for this paradigm
On Wed, May 10, 2023, 18:01 <forax at univ-mlv.fr> wrote:
> ----- Original Message -----
> > From: "Alan Bateman" <Alan.Bateman at oracle.com>
> > To: "Holo The Sage Wolf" <holo3146 at gmail.com>, "Remi Forax" <
> forax at univ-mlv.fr>
> > Cc: "Ron Pressler" <ron.pressler at oracle.com>, "loom-dev" <
> loom-dev at openjdk.java.net>
> > Sent: Wednesday, May 10, 2023 3:03:11 PM
> > Subject: Re: Structured Concurrency yet again
>
> > On 10/05/2023 07:47, Holo The Sage Wolf wrote:
> >> The way to handle these cases is to put the logic after the task ends
> >> into the scope itself.
> >
> > Yes, extend STS and implement the policy in the subclass. The subclass
> > can define APIs to consume the outcome after join. Remi's example calls
> > for short circuiting after 3 tasks complete successfully or any task
> > fails with UnknownHostException, so easy to do.
>
> The problem is that unlike any other classes in java.util.concurrent, STS
> is not thread safe by default, it requires to carefully implement any
> subclasses in a thread safe way.
>
> By example, the implementation provided by Holo may not work because
> - it requires the implementations of FanLogic and the ShutdownStrategy to
> be thread safe given that they are created and used by different threads.
> - ConcurrentLinkedQueue.size() is O(n), not O(1) !
> - results() can not be protected by ensureOwnerAndJoined given it is
> accessed by the implementation of the ShutdownStrategy
> - you can have more than 3 results because a thread can be de-scheduled
> after the call to strategy.testResult() and before the call to
> results.add().
>
> Concurrency is really hard, harder than most people think.
>
> I would prefer to provide an API easier to use. I believe that having a
> method join() that takes a function that takes a stream is easier to use
> correctly.
>
> >
> > -Alan.
>
> Rémi
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20230510/fea832aa/attachment-0001.htm>
More information about the loom-dev
mailing list