-
Notifications
You must be signed in to change notification settings - Fork 530
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
resume
/callback
in cont
, async
, etc. should return a Boolean
#3553
Comments
I think this is a good idea. I suspect it would('ve) make fixing #3603 almost trivial. (I assume the semantics would be that if a cancel won, the callback would return false.) Something worth thinking about is how would this affect |
To answer my own question: I don't think this should affect |
I've started working on this (#3917), and the desired semantics are not entirely clear. What should Any ideas? |
Really? I would say that's a bug. If But it depends what you mean by "right after this". If you mean steps after the |
Well, how about something like this: new Cont[IO, Int, String] {
def apply[F[_]](implicit F: Cancelable[F]) = { (resume, get, lift) =>
lift(IO(resume(Right(42)))) >> F.canceled >> get.map(_.toString)
}
} With the current implementation this self-cancels (I think this is expected). But I think it could be cancelled at any of the I think the point is, that currently when |
Ok, thanks, I see your point now.
I think semantically the |
I'm not sure that helps with the "lost value" problem. For example, let's see def apply[G[_]](implicit G: MonadCancel[G, Throwable]) = { (resume, get, lift) =>
G.uncancelable { poll =>
lift(k(resume)) flatMap {
case Right(a) => G.pure(a)
case Left(Some(fin)) => G.onCancel(poll(/*HERE*/get), lift(fin))
case Left(None) => get
}
}
} Let's say, that Arguably, this is a "bug" in |
Hmm, thanks for writing that out. Actually if I understand correctly, this seems to be a very general problem (not specific to
Currently there is no way to have a cancelable |
dumb-idea-of-the-day poll(/*HERE*/get) what if we just disallowed cancelation there (i.e. change the implementation of |
Yeah. Although, I suspect that if we can solve it for Also worth noting, that this whole problem only occurs, if
Yeah, I thought about that, but that has... consequences. If we look at this: poll(/*1*/ x /*2*/) The point |
Yeah, honestly that seems fine to me 🤷 but I won't claim to foresee all the consequences :) |
Bolded the relevant bit here. So in this scenario, whoever called IO.async(cb => IO(/* things that call cb */ Some(IO(/* finalizer */)))) Okay so if the code at In some cases, this isn't reliably possible without sacrificing other system properties, so instead what often happens is people treat this as a nondeterminism (even though it isn't one) and dodge the recovery by instantiating But overall, this is something that users can cleanly respond to, unlike the cancelable gap at the end of |
That is a very good point. (It would be "nicer", if the return value could give this information directly, but I'm beginning to think that might not be possible.) Now the question is: could we build something (useful) with both the |
So, about never cancelling (observing cancellation?) right inside poll, i.e., poll(/* we never cancel HERE */ x) It is possible. In my draft PR (#3917), I did it (not in a very elegant way, as it's just an experiment for now). It seems to work. A few things needed fixing (notably in Edit: of course, this is yet another violation of the functor laws I think. The existing one is for |
This
Boolean
should be similar to theBoolean
returned when completing aDeferred
i.e. it should indicate that this invocation of theresume
/callback
is the one and only one that actually completed the callback. Everyone else should getfalse
.This information about whether the callback succeeded would help avoid leaks in various concurrent state machines. Here are two that I encountered recently:
Console#readLine
cancelable #3465 (comment)The text was updated successfully, but these errors were encountered: