(NOT A CONTRIBUTION)
I thought about async-unwinding more and I think this is the starting point:
I think the ideal API would be a catch_unwind_async
, which takes a future and returns a future combinator that also includes the states to unwind the future if it panics. Then instead of wrapping their polls in catch_unwind
, executors would wrap the futures they spawn in catch_unwind_async
and poll those to completion. When entering the poll method of this combinator, a thread local flag is set to trigger the async unwinding path when panics happen. (If catch_unwind is called inside of this scope, the flag is set back to normal).
The question is whether or not it's possible to create the future combinator which unwinds a future. I really have no knowledge in that domain.
2 Likes
I was the original proposer the UnsafeFuture
- back then called CompletionFuture in an RFC I wrote.
My take on this is that the Future
doesn't necessary has to contain the cancel method. A graceful cancellation request could be provided to any code via an orthogonal mechanism. I proposed a standardized CancellationToken mechanism for this:
If that token/signal is injected via some standardized mechanims (thread-local or task-local variable), anything in the future could react on it and gracefully run the future to the completed state. The Future could continue to just have a single .poll
method, and another bonus is that the standardized cancellation signal can be shared between synchronous and asynchronous contexts.
Overall I think there's at least 3 orthogonal aspects, which however are all closely related:
- Async drop (or just something like an
IAsyncDisposable
as @scottmcm pointed out), plus potential extra tools to make it more likely to be called (let async
declarations, async defer
blocks, etc).
- Run to completion async fns - which would at least guarantee that code containing an
let async
binding would indeed run the destructure, instead of being short-circuited by any select!
or synchronous drop in the call-stack.
- Graceful cancellation signals
1 Like
I think that distinguishing syntactically between a completion future and a readiness future is an unnecessary burden that will probably cause a lot of trouble. I think having it be inferred like Send
and Sync
is probably the best choice.
Also poll_cancel
would be basically optional, because it has a sound default implementation. Using a method is probably better than using a global for cancellation.