Im new to akka.net and i have learned that in order to use the async and await pattern you would have to use the Ask() Method but as far as im understanding it , you can only await a task only if you fire a method within that actor or some object method, but is it possible to await a task that sends a message to another actor ?
let me illustrate by a simple example :
lets say ActorA received an Message and he needs some informations from ActorB, ActorA code would like this :
class ActorA :ReceiveActor
{
public ActorA ()
{
Receive<string>(Message => ActorB.Ask<string>());
}
}
lets say i want to stall waiting for a reply from actor B. i dont want to process any other messages. ActorB listens for the request, process the message and then finnally replies.
the thing is when ActorB replies it must reply of the form ActorA.tell(replymessage), and this way ActorA might never get to process the reply because the replyMessage should go to ActorA mailbox.
Am i missing something !
If you need request-response messaging in Akka.NET, you can use the Ask
keyword and ReceiveAsync
:
class ActorA :ReceiveActor
{
public ActorA ()
{
ReceiveAsync<string>(async message => {
var resp = await ActorB.Ask<string>("some input");
// do some work
});
}
}
This will have your actor asynchronously wait until it receives a response before it moves on - but it's worth noting that this will block your actor from processing any other messages prior to the await
call completing.
If you wanted to use one-way messaging to allow for interleaving of messages, you could also write it this way:
class ActorA :ReceiveActor
{
public ActorA ()
{
Receive<MessageType>(message => {
// some work
ActorB.Tell("some command");
});
Receive<string>(message => {
// receive response from ActorB
});
}
}
The difference is, there's no timeout or verification that the sender processed the message and sent a reply in the second model. But, it also requires fewer allocations and it allows ActorA
to keep processing other messages in the background while the work is being done.
You can use either approach - I'd recommend the first if you absolutely need to guarantee that the message gets processed.