Skip to content

Use of actor reference on Async Actor handle #308

Description

@Jonathas-Conceicao

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:

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:

    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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions