Here's the official sample of using PipeTo() in Akka.NET:
Receive<BeginProcessFeed>(feed =>
{
//instance variable for closure
var senderClosure = Sender;
SendMessage(string.Format("Downloading {0} for RSS/ATOM processing...", feed.FeedUri));
//reply back to the sender
_feedFactory.CreateFeedAsync(feed.FeedUri).PipeTo(senderClosure);
});
The question is why should we use Sender closure here? Why not to use just:
_feedFactory.CreateFeedAsync(feed.FeedUri).PipeTo(Sender);
In this sample and in the docs it's said it's mandatory to use closure here. But I don't see any reasons to do so.
If we used ContinueWith() it's reasonable to use closure inside the continuation, but not as PipeTo() parameter.
Do I miss something?
Two things to understand here:
Sender is not a static property. Sender is actually a function on the IActorContext that returns the sender of the current message being processed. The value returned changes every time the context gets a new message from the mailbox.
PipeTo is a continuation, and when that continuation executes on the threadpool, calling Sender will access the exact same IActorContext object that started the task. There is no guarantee that the current Sender in the context is the same, because of new message(s) being pushed into the actor for processing since the task started.
So we cache the value of Sender in a local variable to guarantee that we're aiming PipeTo at the correct IActorRef whenever it executes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With