You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've found a few issues in ListenableFuture.kt with respect to Future's interface contract and with cancellation propagation:
Propagation of cancellation through asListenableFuture() is unidirectional; cancellation should be bidirectionally cooperative for any chain of Deferred and/or LF<> through transformation
Cancellation of a Future from asListenableFuture() through future.setFuture(someCancelledFuture) is broken; this should cancel future and doesn't
Future's happens-after contract with isCancelled() is (I think) broken in some cases, but this is hard to nail down; a Future can never return true from any more than one call to Future.cancel(), but I think the current asListenableFuture()Future can
Cancelling asListenableFuture() without interruption doesn't propagate to the deferred without interruption, which seems wrong? It's possible to cleanly cancel in this case.
Cancelling a Deferred with a CancellationException cause won't propagate the cause to an asListenableFuture() created from the Deferred - the cause and message are lost
Most of these subtler semantics aren't documented; there are some strange intersections between of what Job cancellation means and what Future cancellation means
These corner cases matter when using .guava as a migration layer in codebases where other implementations of Future or ListenableFuture/AbstractFuture are present. This is especially true for production code relying on cancel() behaviour to perform atomic work, or to efficiently clean up servlets or other somewhat-long-running tasks.
I've nailed down the problematic properties with unit tests. I've got a PR fixing them and documenting .guava pending.
There's an existing discussion on some related semantics around await() that don't address asListenableFuture() but do intersect a bit.
From the Guava perspective, the PR's semantics are "more correct" for ListenableFuture semantics, and should be a no-op or an improvement for Deferred semantics. There are some optimizations around atomic reads, too.
The text was updated successfully, but these errors were encountered:
I've found a few issues in
ListenableFuture.kt
with respect toFuture
's interface contract and with cancellation propagation:asListenableFuture()
is unidirectional; cancellation should be bidirectionally cooperative for any chain ofDeferred
and/orLF<>
through transformationFuture
fromasListenableFuture()
throughfuture.setFuture(someCancelledFuture)
is broken; this should cancelfuture
and doesn'tFuture
's happens-after contract withisCancelled()
is (I think) broken in some cases, but this is hard to nail down; a Future can never return true from any more than one call toFuture.cancel()
, but I think the currentasListenableFuture()
Future
canasListenableFuture()
without interruption doesn't propagate to the deferred without interruption, which seems wrong? It's possible to cleanly cancel in this case.Deferred
with aCancellationException
cause won't propagate the cause to anasListenableFuture()
created from theDeferred
- the cause and message are lostJob
cancellation means and whatFuture
cancellation meansThese corner cases matter when using
.guava
as a migration layer in codebases where other implementations ofFuture
orListenableFuture
/AbstractFuture
are present. This is especially true for production code relying oncancel()
behaviour to perform atomic work, or to efficiently clean up servlets or other somewhat-long-running tasks.I've nailed down the problematic properties with unit tests. I've got a PR fixing them and documenting
.guava
pending.There's an existing discussion on some related semantics around
await()
that don't addressasListenableFuture()
but do intersect a bit.From the Guava perspective, the PR's semantics are "more correct" for
ListenableFuture
semantics, and should be a no-op or an improvement forDeferred
semantics. There are some optimizations around atomic reads, too.The text was updated successfully, but these errors were encountered: