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 wrote a small crate for using async/await syntax with actix. It also makes the "AtomicResponse" type obsolete by providing a more ergonomic mechanism to achieve the same thing. I think it would be nice to have as part of actix itself.
The basic idea is to use scoped TLS (at least until custom future contexts are supported) to store the actor and its context.
There are three functions:
FutureInterop::interop_actor()
This is equivalent to the into_actor() method except that it populates the TLS slots with the actor and the context before polling the inner future. There's also a boxed variant of this function.
with_ctx
This takes a closure and immediately calls it, passing in mutable references to the actor and context obtained from the TLS slots to that closure.
critical_section
This takes a future/async block and uses ctx.wait() to make sure it has exclusive access to the actor state while it is running. It returns a future itself so you can seamlessly demarcate blocks of code within an async/await block as being critical sections.
Example:
implHandler<Request>forMyActor{typeResult = ResponseActFuture<Self,Result<Response,()>>;fnhandle(&mutself,msg:Request,_ctx:&mutContext<Self>) -> Self::Result{asyncmove{// Modify the actor state in some waywith_ctx(|a:&mutSelf, _| a.mutate());
... <some async code> ...// Run some code with exclusive access to the actorlet result = critical_section::<Self,_>(async{// Put the actor into an inconsistent state.// We don't want this visible outside the critical section.with_ctx(|a:&mutSelf, _| a.begin_mutation());
... <some async code> ...// Make everything consistent againOk(with_ctx(|a:&mutSelf, _| a.end_mutation()))}).await;
... <some async code> ...// Return a resultresult}.interop_actor_boxed(self)}}
Some things which are very hard to do right now are made much easier in this pattern (for example, when only half of a message handler needs to run atomically). Also, all of the normal futures combinators can be used, rather than the more limited set exposed under actix::fut.
Currently the crate relies on a patch to scoped_thread_local which hasn't been merged yet, which is why I haven't published it. However, except for scoped-tls this crate itself does not require any unsafe code at all.
The text was updated successfully, but these errors were encountered:
Could the new Generator Resume Arguments feature be used to replace with_ctx? At moixa we make heavy use of ActorFutures and it would be really nice to get the benefits of async/await syntax.
Potentially, but the type bounds will be very complicated, so even if generator resume arguments are added to the language, it doesn't necessarily mean that they'll be able to express the required lifetimes.
I wrote a small crate for using async/await syntax with actix. It also makes the "AtomicResponse" type obsolete by providing a more ergonomic mechanism to achieve the same thing. I think it would be nice to have as part of actix itself.
The basic idea is to use scoped TLS (at least until custom future contexts are supported) to store the actor and its context.
There are three functions:
FutureInterop::interop_actor()
This is equivalent to the
into_actor()
method except that it populates the TLS slots with the actor and the context before polling the inner future. There's also a boxed variant of this function.with_ctx
This takes a closure and immediately calls it, passing in mutable references to the actor and context obtained from the TLS slots to that closure.
critical_section
This takes a future/async block and uses
ctx.wait()
to make sure it has exclusive access to the actor state while it is running. It returns a future itself so you can seamlessly demarcate blocks of code within an async/await block as being critical sections.Example:
Some things which are very hard to do right now are made much easier in this pattern (for example, when only half of a message handler needs to run atomically). Also, all of the normal futures combinators can be used, rather than the more limited set exposed under
actix::fut
.Currently the crate relies on a patch to
scoped_thread_local
which hasn't been merged yet, which is why I haven't published it. However, except forscoped-tls
this crate itself does not require any unsafe code at all.The text was updated successfully, but these errors were encountered: