Skip to content

Instantly share code, notes, and snippets.

@nvivo
Created February 19, 2015 13:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nvivo/432f55caa959afcb93a1 to your computer and use it in GitHub Desktop.
Save nvivo/432f55caa959afcb93a1 to your computer and use it in GitHub Desktop.
This is an implementation of an "async" UntypedActor. It works exactly like a UntypedActor, but support "await" calls inside the OnReceiveAsync method. Exceptions thrown during async execution are throw as regular exceptions and are handled by the supervisor, and no messages are processed during async operations.
public abstract class AsyncUntypedActor : UntypedActor, WithUnboundedStash
{
public IStash Stash { get; set; }
bool _awaiting;
readonly object AwaitingComplete = new object();
protected sealed override void OnReceive(object message)
{
if (_awaiting)
{
if (message == AwaitingComplete)
{
_awaiting = false;
Stash.UnstashAll();
return;
}
if (message is ExceptionDispatchInfo && Sender.Equals(Self))
{
_awaiting = false;
Stash.UnstashAll();
((ExceptionDispatchInfo)message).Throw();
}
Stash.Stash();
return;
}
var task = OnReceiveAsync(message);
if (task.IsFaulted)
ExceptionDispatchInfo.Capture(task.Exception.InnerException).Throw();
if (task.IsCompleted)
return;
var self = Self;
_awaiting = true;
task.ContinueWith(t =>
{
if (t.IsFaulted)
self.Tell(ExceptionDispatchInfo.Capture(t.Exception.InnerException), self);
else
self.Tell(AwaitingComplete, ActorRef.NoSender);
});
}
protected abstract Task OnReceiveAsync(object message);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment