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.
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.