Created
February 19, 2015 13:33
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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