[concurrency-interest] CompletableFuture in Java 8
viktor.klang at gmail.com
Wed Dec 3 18:32:50 EST 2014
On Wed, Dec 3, 2014 at 11:33 PM, thurstonn <thurston at nomagicsoftware.com>
> So, I'll put in my 2c (might not even be worth that).
> Would it really be so . . . unprincipled . . . to add a get() method to
> CompletionStage (and overloaded variants)?
I'd say so, given the experience I have with trying to get people of the
And if we didn't have `toCompletableFuture` and you sorely required it, it
is 1 utility method await:
def toCompletableFuture[R](stage: CompletionStage[R]): CompletableFuture[R]
val cf = new CompletableFuture<R>()
stage.whenComplete((r, e) => if (e != null) cf.completeExceptionally(e)
> Or at least an isDone() method
> (I'm assuming that that would *not* need to block, or wait)
What's the use-case, if you don't mind?
> I think that is what Josh is essentially advocating (cancel() is more
> problematic I agree).
> I guess I just think about writing tests; if you're going to expose
> CompletionStage as return types from API methods, the most simple and
> obvious way to test the implementation is:
> CompletionStage do(some-input)
> assert expected == do(...).get()
I hope that test cases don't use `assert` (keyword) but some kind of test
framework (JUnit, TestNG, or any other similar),
in which case it is, if not already present, straight-forward to do:
awaitAssert(5, SECONDS, do(…), equals(expected))
within(5, SECONDS, do(…), (result) -> equals(expected, result))
> Viktor's suggested work-around:
> val cf = new CompletableFuture<R>()
> stage.whenComplete((r, e) -> if (e != null) cf.completeExceptionally(e)
> is just evil IMHO.
Out of curiosity, what about it do you find evil?
> Although the CDL code that Doug references is even worse.
> What should the test code do, put in arbitrary Thread.sleeps()? Blecch
(Thread.sleep _is_ evil! :) ), No what it should do is to register a
completion signal to the CompletionStage and then add a timeout when to
fail the test-case. Does not need any blocking whatsoever SFAICS.
> And I think Josh's point that blocking (invoking get()) is *orthogonal* to
> the ability for a reader/consumer to *write* the value of a computation,
Now that I think we can all agree on. But that was not how he phrased it
> which is what the admittedly "escape hatch" of #toCompletableFuture()
> exposes, is correct.
> I'm not dismissing Viktor's concerns, and you can be sure that there would
> be engineers who would end up doing:
Trust me, they are more common than you think!
> CompletionStage cs1 = . . .
> result = cs1.get()
> CompletionStage cs2 = . . . (result)
> and so on (which might result in inter-engineer violent crimes).
With those unbounded waits you'll probably see an Ops-person or two join
into the fray.
> Maybe I just can't let go of bad habits, but although I admire the goal of
> *never block*, at least in the applications I write, I'm not sure if it's
> realistic (I'd love to eliminate side effects as well, but I need a
> database, or to write to a socket, etc).
I'm not sure there's any isomorphism between the necessity of side-effects
(keep in mind that the definition of blocking we're using here is limited
to putting a Thread into BLOCKED, WAITING or TIMED_WAITING states)
> Even Erlang apps block sometimes (cf. gen_server:call())
I'm unsure whether anybody has ever claimed Erlang to be fully non-blocking
> View this message in context:
> Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Concurrency-interest