예제 #1
0
        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();
            }
        }
예제 #2
0
        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)));
        }
예제 #3
0
        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);
        }