Search code examples
c++actorc++-actor-framework

Returning value from actor call


In C++ Actor framework I have an actor (lets suppose A) which calls another actor ( lets suppose B) and then the value of B has to be used in A's logic.

To make it more concrete the code is the following:

behavior B(event_based_actor* self) {
return {
    [=](const string& what) -> string {
        return what;
    }
};

behavior A(event_based_actor* self) {
return {
    [=](const string& what, const actor& buddy) -> string {
            self->request(buddy, std::chrono::seconds(10), what)
        .then(
            [=](string & data) {
                aout(self) << data << endl;
            }
          what = data // here I have to use data and thats the issue
           );
        return what;
    }
};

As can be seen in the code I have to use the data variable which is the result of the actor B outside the lambda and since I'm new to this any help would be appreciated.

And the actor B is called from another blocking actor.


Solution

  • This is not going to work. Event-based actors are nonblocking. The statement request(x).then(f) sends x to another actor and then stores f for handling the result. In other words, request(...).then(...) always returns immediately and f is executed at some later point in time. Setting what = data thus achieves nothing and you will always return the original what.

    What you are looking for are response promises. They allow you to delay the response. In your case:

    behavior A(event_based_actor* self) {
      return {
        [=](const string& what, const actor& buddy) -> result<string> {
          auto rp = self->make_response_promise();
          self->request(buddy, std::chrono::seconds(10), what)
          .then(
            [=](string& data) mutable {
              aout(self) << data << endl;
              rp.deliver(std::move(data));
            }
          );
          return rp;
        }
      };
    }
    

    You can read more about promises in the manual and there's also a full example included in CAF.