-
Notifications
You must be signed in to change notification settings - Fork 521
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change async_
to be uncancelable
#3205
Change async_
to be uncancelable
#3205
Conversation
Published as @armanbilge we should try to canary this around the ecosystem to see what impact it has. |
async_
's cancelation semanticsasync_
to be uncancelable
Well, it broke broke fs2-io JVM/Native.
And also fs2-io Node.js.
It will probably break browser JS stuff too. |
New snapshot: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change definitely breaks some stuff downstream, but in my experiments it's only broken "FFI" code using async_
, and these were things I expected to break, precisely because I didn't understand how they were working in the first place (which is how I stumbled on this issue).
Since cancelation is not the happy-path, I expect there will be other downstream issues that won't surface in happy-path-focused test suites.
Nonetheless, personally I am eager to move forward with this.
@armanbilge How far did we canary this? Just Fs2, or were we able to try it out in further-downstream things as well? |
I also tried it out in my browser integration projects (fs2-dom etc.) but not further than that, since those projects are where all the I suspect blaze will get hit by this. Maybe worth opening an issue there. |
I think we need a snapshot of fs2 which contains this change in order to move forward with the ecosystem canary. |
I put up an FS2 PR in typelevel/fs2#3063 and can publish a snapshot of that after I rig my faraday cage 😇 |
This PR fundamentally changes the semantics of
async_
andasync
with respect to nullary finalizers. Specifically,async_
's only mode of operation, which is equivalent to whenasync
producesNone
from its registration action. For example:Previously, this corresponded to a semantic in which
foo
was cancelable and did not activate a finalizer, similar toflatMap
(and indeed, most effect stages). Unfortunately, this was also a form of backpressure corruption and, in some cases, a resource leak. For example,foo
above is not in fact cancelable since we have provided no mechanism for removing the callback from the map. Treating it as cancelable would be a form of resource leak, sincecb
would be orphaned within thethingy
register.The correct way to avoid this situation is for
thingy
to define anunregister
method (as most such mechanisms do in practice):With this adjustment,
foo
can be safely canceled, and when we do so it will removecb
fromthingy
, cleaning up and backpressuring the canceling fiber.This PR changes the semantics of
async
whenNone
is produced to be uncancelable. Since no finalizer has been provided, the asynchronous effect is now considered to be uninterruptible, similar to howdelay
cannot be canceled for a similar reason. Thus, anyasync
which returnsNone
, anyasyncCheckAttempt
which returnsLeft(None)
, and allasync_
effects are now uncancelable.In most cases, the ideal way to adapt to this change is to simply provide a finalizer for your asynchronous constructor by producing
Some
instead ofNone
. When this is not possible, the uncancelability is likely to be the ideal default for avoiding memory leaks and retaining backpressure. In the rare cases where the previous semantics are desired, it is possible to restore them by producingSome(IO.unit)
as a finalizer. One such example is thenever
effect:Previously,
never
was defined asIO.async(_ => IO.pure(None)))
, but as that formulation is now uncancelable, it must be rewritten as shown above. In theory, this is a more explicit version, since it correctly expresses the fact thatnever
is cancelable and no actions need to be taken to release resources when it is canceled.Relates to #3199