public async Task Become(string behavior) { if (IsNull()) { throw new InvalidOperationException("Initial behavior should be set before calling Become"); } if (next != null) { throw new InvalidOperationException($"Become cannot be called again while behavior configuration is in progress.\n" + $"Current: {Current}, In-progress: {next.Name}, Offending: {behavior}"); } if (Current == behavior) { throw new InvalidOperationException($"Actor is already behaving as '{behavior}'"); } if (TimerService.IsExecuting()) { throw new InvalidOperationException($"Can't switch to '{behavior}' behavior. Switching behaviors from inside timer callback is unsafe. " + "Use Fire() to send a message and then call Become inside message handler"); } var action = RegisteredAction(behavior); next = new CustomBehavior(behavior); action(actor); var transition = new Transition(current, next); try { await actor.OnTransitioning(transition); await current.HandleDeactivate(transition); await current.HandleUnbecome(transition); current = next; await current.HandleBecome(transition); next = null; // now become could be re-entered ... await current.HandleActivate(transition); // ... and we can signal about successful transition await actor.OnTransitioned(transition); } catch (Exception exception) { await actor.OnTransitionFailure(transition, exception); actor.Activation.DeactivateOnIdle(); ExceptionDispatchInfo.Capture(exception).Throw(); } }
public async Task <object> Fire(object message) { Requires.NotNull(message, nameof(message)); if (TimerService.IsExecuting() || mocked) { RequestOrigin.Store(Current); return(await actor.Self.Ask <object>(message)); } return(await HandleReceive(message, new RequestOrigin(Current))); }
public async Task Become(string behavior) { if (IsNull()) { throw new InvalidOperationException("Initial behavior should be set before calling Become"); } if (next != null) { throw new InvalidOperationException($"Become cannot be called again while behavior configuration is in progress.\n" + $"Current: {Current}, In-progress: {next.Name}, Offending: {behavior}"); } if (Current == behavior) { throw new InvalidOperationException($"Actor is already behaving as '{behavior}'"); } if (TimerService.IsExecuting()) { throw new InvalidOperationException($"Can't switch to '{behavior}' behavior. Switching behaviors from inside timer callback is unsafe. " + "Use Fire() to send a message and then call Become inside message handler"); } var action = RegisteredAction(behavior); next = new CustomBehavior(behavior); action(actor); var transition = new Transition(current, next); await current.HandleDeactivate(transition); await current.HandleUnbecome(transition); current = next; await current.HandleBecome(transition); if (onBecome != null) { await onBecome(transition.To.Name, transition.From.Name); } next = null; // now become could be re-entered await current.HandleActivate(transition); }