#308·actix

Use of actor reference on Async Actor handle

Author: Jonathas-ConceicaoCreated Jan 8, 2020Updated Nov 8, 2020

I'm trying implement some asynchronous actor response that uses the Actor's self reference on actix v0.9 but I can't get it to work on the account of some lifetime bounds error. I've separated a small example that contains the error:

rust
use actix::prelude::*;

#[derive(Message)]
#[rtype(result = "Result<usize, ()>")]
struct Msg;

struct MyActor;

impl Actor for MyActor {
    type Context = Context<Self>;
}

impl Handler<Msg> for MyActor {
    type Result = ResponseActFuture<Self, Result<usize, ()>>;

    fn handle(&mut self, _msg: Msg, _: &mut Context<Self>) -> Self::Result {
        Box::new(self.reply().into_actor(self))
    }
}

impl MyActor {
    async fn reply(&self) -> Result<usize, ()> {
        Ok(42)
    }
}

But this gives me the following error:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/main.rs:17:23
   |
17 |         Box::new(self.reply().into_actor(self))
   |                       ^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 16:5...
  --> src/main.rs:16:5
   |
16 | /     fn handle(&mut self, _msg: Msg, _: &mut Context<Self>) -> Self::Result {
17 | |         Box::new(self.reply().into_actor(self))
18 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:17:18
   |
17 |         Box::new(self.reply().into_actor(self))
   |                  ^^^^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
  --> src/main.rs:17:9
   |
17 |         Box::new(self.reply().into_actor(self))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected  `std::boxed::Box<(dyn actix::fut::ActorFuture<Actor = MyActor, Output = std::result::Result<usize, ()>> + 'static)>`
              found  `std::boxed::Box<dyn actix::fut::ActorFuture<Actor = MyActor, Output = std::result::Result<usize, ()>>>`

I've tried to implement this using the ActorFuture and the them combinator but I get similar errors, this is what I tried:

rust
    fn handle(&mut self, _msg: Msg, _: &mut Context<Self>) -> Self::Result {
        Box::new(
            async {}
                .into_actor(self)
                .then(|_, act, _| actix::fut::wrap_future(act.reply())),
        )
    }

The problem seams to be that I can only have static references for the future I return, but since the future will be handled by the Actor itself shouldn't it be able to use it's own reference?

Are there examples for asynchronously handling messages? I have only been able to find the doc example on ActorFuture, witch is even a little bit outdated; but it's a bit of a different context since that doesn't use a reference to the actor on the futures it chains.