コード例 #1
0
        private void ApplyEvent(Event @event)
        {
            switch (@event.Data)
            {
            //转帐开始
            case TransferStarted msg:
                //转换成等待贷方确认
                _behavior.Become(AwaitingDebitConfirmation);
                break;

            //借方扣除
            case AccountDebited msg:
                //转换成等待借方确认
                _behavior.Become(AwaitingCreditConfirmation);
                break;

            //贷方拒绝
            case CreditRefused msg:
                _behavior.Become(RollingBackDebit);
                break;

            //贷方存入
            case AccountCredited _:
            //借方回滚
            case DebitRolledBack _:
            //转帐失败
            case TransferFailed _:
                _processCompleted = true;
                break;
            }
        }
コード例 #2
0
        public async Task ReceiveAsync(IContext context)
        {
            switch (context.Message)
            {
            case Started _:
                context.SetReceiveTimeout(5.Minutes());
                persistence = Persistence.WithEventSourcing(eventStore, context.Self.Id, ApplyEvent);
                await persistence.RecoverStateAsync();

                if (pattern == null)
                {
                    behavior.Become(New);
                }
                else
                {
                    behavior.Become(Created);
                }
                break;

            case ReceiveTimeout _:
                context.Self.Stop();
                break;

            default:
                await behavior.ReceiveAsync(context);

                break;
            }
        }
コード例 #3
0
        Task Disconnected(IContext context)
        {
            switch (context.Message)
            {
            case (Connect, IPEndPoint endpoint): {
                _log.LogInformation("Attempting to connect to {endpoint}:{port}", endpoint.Address, endpoint.Port);
                _socket.Connect(endpoint);
                _log.LogInformation("Connection estabished");

                _pollThread.Start((_cancellationTokenSource.Token, context));
                _behaviour.Become(Connected);

                if (context.Parent != null)
                {
                    context.Send(context.Parent, (SocketConnected));
                }

                // Transmit protocol header to start handshake process...
                _log.LogDebug("Sending protocol header");
                var buffer = new ArrayBufferWriter <Byte>(initialCapacity: 8);
                ProtocolHeader.Default.Serialize(buffer);
                _socket.Send(buffer.WrittenSpan);
                _log.LogDebug("Transmitted {bytes} bytes", buffer.WrittenSpan.Length);
                return(Done);
            }

            default: return(Done);
            }
        }
コード例 #4
0
 Task Unstarted(IContext context)
 {
     switch (context.Message)
     {
     case Started _: {
         SpawnSocketAgent(context);
         _behaviour.Become(Disconnected);
         break;
     }
     }
     return(Done);
 }
コード例 #5
0
        Task AwaitStart(IContext context)
        {
            switch (context.Message)
            {
            case Started _: {
                _behaviour.Become(AwaitConnectionStart);
                return(Done);
            }

            default: return(Done);
            }
        }
コード例 #6
0
 public Task ReceiveAsync(IContext context)
 {
     // any "global" message handling here
     switch (context.Message)
     {
     case HitWithHammer _:
         context.Respond("Smashed!");
         _behavior.Become(Smashed);
         return(Actor.Done);
     }
     // if not handled, use behavior specific
     return(_behavior.ReceiveAsync(context));
 }
コード例 #7
0
        /// <summary>
        /// 关
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private Task Off(IContext context)
        {
            switch (context.Message)
            {
            case PressSwitch _:
                context.Respond("打开");
                _behavior.Become(On);
                break;

            case Touch _:
                context.Respond("凉的");
                break;
            }
            return(Actor.Done);
        }
コード例 #8
0
 public MetroBikeShareActor()
 {
     _metroBikeShareApi = RestClient.For <IMetroBikeShareApi>("https://bikeshare.metro.net");
     _stationActors     = new Dictionary <string, PID>();
     _behavior          = new Behavior();
     _behavior.Become(Refreshing);
 }
コード例 #9
0
        async Task <object> Off(object message)
        {
            switch (message)
            {
            case PressSwitch _:
                await behavior.Become(On);

                return("Turning on");

            case Touch _:
                return("Cold");

            default:
                return(Unhandled);
            }
        }
コード例 #10
0
        protected void ValidatingCommandBehavior()
        {
            DefaultBehavior();

            Command <CommandStateActor.Accepted>(a =>
            {
                Behavior.Become(ProcessingCommandBehavior, nameof(ProcessingCommandBehavior));

                Log.Debug("Executing command. {@m}", ExecutionContext);
                _aggregateCommandsHandler.ExecuteAsync(State,
                                                       ExecutionContext.Command)
                .ContinueWith(t =>
                {
                    ExecutionContext.ProducedState = t.Result;
                    return(ExecutionContext.ProducedState.GetUncommittedEvents());
                })
                .PipeTo(Self);
            });
            Command <CommandStateActor.Rejected>(a =>
            {
                var commandAlreadyExecutedException = new CommandAlreadyExecutedException();
                PublishError(commandAlreadyExecutedException);
                Behavior.Become(AwaitingCommandBehavior, nameof(AwaitingCommandBehavior));
                // throw commandAlreadyExecutedException;
                Stash.UnstashAll();
            });
            CommandAny(StashMessage);
        }
コード例 #11
0
        private Task Off(IContext context)
        {
            switch (context.Message)
            {
            case PressSwitch _:
                context.Respond("Turning on");
                _behavior.Become(On);
                break;

            case Touch _:
                context.Respond("Cold");
                break;
            }

            return(Task.CompletedTask);
        }
コード例 #12
0
        public async Task pop_behavior_should_restore_pushed_behavior()
        {
            var behavior = new Behavior();

            behavior.Become(ctx =>
            {
                if (ctx.Message is string)
                {
                    behavior.BecomeStacked(ctx2 =>
                    {
                        ctx2.Respond(42);
                        behavior.UnbecomeStacked();
                        return(Actor.Done);
                    });
                    ctx.Respond(ctx.Message);
                }
                return(Actor.Done);
            });
            PID pid = SpawnActorFromFunc(behavior.ReceiveAsync);

            var reply = await Context.RequestAsync <string>(pid, "number");

            var replyAfterPush = await Context.RequestAsync <int>(pid, null);

            var replyAfterPop = await Context.RequestAsync <string>(pid, "answertolifetheuniverseandeverything");

            Assert.Equal("number42answertolifetheuniverseandeverything", $"{reply}{replyAfterPush}{replyAfterPop}");
        }
コード例 #13
0
        private void ApplyEvent(Event obj)
        {
            switch (obj.Data)
            {
            case Started started:
                _behavior.Become(Ordering);
                break;

            case Order order:
                _behavior.Become(Ordering);
                break;

            case Ship ship:
                _behavior.Become(OrderComplete);
                break;
            }
        }
コード例 #14
0
        private Task Stopped(IContext context)
        {
            switch (context.Message)
            {
            case PlayMovieMessage msg:
                _currentlyWatching = msg.MovieTitle;
                ColorConsole.WriteLineYellow($"User is currently watching '{_currentlyWatching}'");
                _behavior.Become(Playing);
                break;

            case StopMovieMessage msg:
                ColorConsole.WriteLineRed("Error: cannot stop if nothing is playing");
                break;
            }
            ColorConsole.WriteLineCyan("UserActor has now become Stopped");

            return(Actor.Done);
        }
コード例 #15
0
        public Task ConnectedAsync(IContext context)
        {
            switch (context.Message)
            {
            case RemoteTerminate msg:
            {
                _watched.Remove(msg.Watcher.Id);
                //create a terminated event for the Watched actor
                var t = new Terminated
                {
                    Who = msg.Watchee
                };
                //send the address Terminated event to the Watcher
                msg.Watcher.SendSystemMessage(t);
                break;
            }

            case EndpointTerminatedEvent _:
            {
                foreach (var(id, pid) in _watched)
                {
                    //create a terminated event for the Watched actor
                    var t = new Terminated
                    {
                        Who = pid,
                        AddressTerminated = true
                    };
                    var watcher = new PID(ProcessRegistry.Instance.Address, id);
                    //send the address Terminated event to the Watcher
                    watcher.SendSystemMessage(t);
                }

                _behavior.Become(TerminatedAsync);
                break;
            }

            case RemoteUnwatch msg:
            {
                _watched[msg.Watcher.Id] = null;

                var w = new Unwatch(msg.Watcher);
                Remote.SendMessage(msg.Watchee, w, -1);
                break;
            }

            case RemoteWatch msg:
            {
                _watched[msg.Watcher.Id] = msg.Watchee;

                var w = new Watch(msg.Watcher);
                Remote.SendMessage(msg.Watchee, w, -1);
                break;
            }
            }
            return(Actor.Done);
        }
コード例 #16
0
 Task Unstarted(IContext context)
 {
     switch (context.Message)
     {
     case Started _: {
         _behaviour.Become(Running);
         break;
     }
     }
     return(Done);
 }
コード例 #17
0
ファイル: Copier.cs プロジェクト: mallickhruday/Orleankka
 async Task Become(Receive other)
 {
     try
     {
         await behavior.Become(other);
     }
     catch (Exception)
     {
         Activation.DeactivateOnIdle();
         throw;
     }
 }
コード例 #18
0
        private Task On(IContext context)
        {
            switch (context.Message)
            {
            case Started _:
                break;

            case RouteStateOn msg:
                Console.WriteLine("Received on while already in on state");
                break;

            case RouteStateOff msg:
                _behavior.Become(On);
                break;

            default:
                context.Forward(_normalFlow);
                break;
            }

            return(Actor.Done);
        }
コード例 #19
0
 public AggregateActor(IAggregateCommandsHandler <TAggregate> handler,
                       ISnapshotsPersistencePolicy snapshotsPersistencePolicy,
                       IConstructAggregates aggregateConstructor,
                       IConstructSnapshots snapshotsConstructor,
                       IActorRef customHandlersActor) : base(aggregateConstructor, snapshotsConstructor, snapshotsPersistencePolicy)
 {
     _aggregateCommandsHandler = handler;
     _publisher                    = Context.System.GetTransport();
     _customHandlersActor          = customHandlersActor;
     _domainEventProcessEntry      = new ProcessEntry(Self.Path.Name, AggregateActorConstants.PublishingEvent, AggregateActorConstants.CommandExecutionCreatedAnEvent);
     _domainEventProcessFailEntry  = new ProcessEntry(Self.Path.Name, AggregateActorConstants.CommandExecutionFinished, AggregateActorConstants.CommandRaisedAnError);
     _commandCompletedProcessEntry = new ProcessEntry(Self.Path.Name, AggregateActorConstants.CommandExecutionFinished, AggregateActorConstants.ExecutedCommand);
     Behavior.Become(AwaitingCommandBehavior, nameof(AwaitingCommandBehavior));
 }
コード例 #20
0
        private void ApplyEvent(Event @event)
        {
            switch (@event.Data)
            {
            case TransferStarted msg:
                _behavior.Become(AwaitingDebitConfirmation);
                break;

            case AccountDebited msg:
                _behavior.Become(AwaitingCreditConfirmation);
                break;

            case CreditRefused msg:
                _behavior.Become(RollingBackDebit);
                break;

            case AccountCredited _:
            case DebitRolledBack _:
            case TransferFailed _:
                _processCompleted = true;
                break;
            }
        }
コード例 #21
0
        protected override async Task <object> HandleCommand(Command cmd)
        {
            var events = ((IEnumerable <Event>) await Behavior.Fire(cmd)).ToArray();

            await Store(events);
            await Apply(events);

            if (Behavior.Current != State)
            {
                await Behavior.Become(State);
            }

            return(events);
        }
コード例 #22
0
        private void TransitingProcessBehavior()
        {
            IMessageMetadataEnvelop        processingEnvelop = null;
            IReadOnlyCollection <ICommand> producedCommands  = null;
            IActorRef processingMessageSender = null;

            Receive <IMessageMetadataEnvelop>(messageEnvelop =>
            {
                _log.Debug("Transiting process by {@message}", messageEnvelop);

                processingEnvelop       = messageEnvelop;
                processingMessageSender = Sender;
                var pendingState        = (TState)State.Clone();
                Behavior.Become(() => AwaitingTransitionConfirmationBehavior(pendingState), nameof(AwaitingTransitionConfirmationBehavior));
                Process.Transit(pendingState, messageEnvelop.Message)
                .PipeTo(Self);
            });

            void AwaitingTransitionConfirmationBehavior(TState pendingState)
            {
                Receive <IReadOnlyCollection <ICommand> >(transitionResult =>
                {
                    _log.Debug("Process was transited, new state is {@state}", pendingState);
                    producedCommands = transitionResult;
                    var cmd          = new SaveStateCommand <TState>(Id,
                                                                     pendingState,
                                                                     GetMessageId(processingEnvelop));
                    //will reply back with CommandExecuted
                    _stateAggregateActor.Tell(new MessageMetadataEnvelop <SaveStateCommand <TState> >(cmd, processingEnvelop.Metadata));
                });
                Receive <AggregateActor.CommandExecuted>(c =>
                {
                    State = pendingState;
                    processingMessageSender.Tell(new ProcessTransited(producedCommands, processingEnvelop.Metadata,
                                                                      _producedCommand,
                                                                      State));
                    _log.Debug("Process dispatched {count} commands {@commands}", producedCommands?.Count ?? 0, producedCommands);

                    Behavior.Become(AwaitingMessageBehavior, nameof(AwaitingMessageBehavior));
                    pendingState            = null;
                    processingMessageSender = null;
                    processingEnvelop       = null;
                    producedCommands        = null;
                });

                Receive <Status.Failure>(f => FinishWithError(processingEnvelop, processingMessageSender, f.Cause));

                StashingMessagesToProcessBehavior("process is waiting for transition confirmation");
            }
        }
コード例 #23
0
        private async void ApplyEvent(Event obj)
        {
            switch (obj.Data)
            {
            case Started started:
                _behavior.Become(Ordering);
                _pid.Tell(new Order {
                    OrderNo = "DJ000012352", Total = 1524631.25m, OrderTime = DateTime.Now
                });
                break;

            case Order order:
                _behavior.Become(OrderComplete);
                _pid.Tell(new Ship {
                    Address = "东京中央区茅埸町PMO", Mobile = "13453467144", Shiptime = DateTime.Now, Name = "桂素伟", OrderNo = order.OrderNo
                });
                break;

            case Ship ship:
                await RemoteSend(ship);

                break;
            }
        }
コード例 #24
0
        private void FinishWithError(IMessageMetadataEnvelop processingMessage, IActorRef messageSender, Exception error)
        {
            _log.Error(error, "Error during execution of message {@message}", processingMessage);

            var processorType = Process?.GetType() ?? typeof(TState);
            var fault         = (IFault)Fault.NewGeneric(processingMessage.Message, error.UnwrapSingle(), Id, processorType);

            var faultMetadata = MessageMetadataExtensions.CreateChild(processingMessage.Metadata, (string)fault.ProcessId, _exceptionOnTransit);

            _publisher.Publish(fault, faultMetadata);

            messageSender.Tell(new ProcessFault(fault, processingMessage.Metadata));

            Behavior.Become(AwaitingMessageBehavior, nameof(AwaitingMessageBehavior));
            ExecutionContext.Clear();
        }
コード例 #25
0
        private Task StoreMessages(IContext context)
        {
            switch (context.Message)
            {
            case Data data:
                _pending.Add(data);
                break;

            case Trigger _:
                _pending.ForEach(msg => context.Send(_dataConsumer, msg));
                _pending.Clear();
                _behaviour.Become(ForwardMessages);
                break;
            }

            return(Task.CompletedTask);
        }
コード例 #26
0
        public async Task ReceiveAsync(IContext context)
        {
            switch (context.Message)
            {
            case Started msg:
                _behavior.Become(Starting);
                await _persistence.RecoverStateAsync();

                break;
                // ...
            }
            await _behavior.ReceiveAsync(context);
        }
コード例 #27
0
        private void CreatingProcessBehavior()
        {
            Receive <CreateNewProcess>(c =>
            {
                _log.Debug("Creating new process instance from {@message}", c);
                var pendingState = _processStateFactory.Create(c.Message.Message);

                ExecutionContext.StartNewExecution(pendingState, c.Message, Sender);

                var cmd = new CreateNewStateCommand <TState>(ExecutionContext.PendingState.Id, ExecutionContext.PendingState);
                //will reply with CommandExecuted
                _stateAggregateActor.Tell(new MessageMetadataEnvelop <ICommand>(cmd, ExecutionContext.ProcessingMessage.Metadata));
                Behavior.Become(AwaitingCreationConfirmationBehavior, nameof(AwaitingCreationConfirmationBehavior));
            });

            void AwaitingCreationConfirmationBehavior()
            {
                Receive <Status.Failure>(f => FinishWithError(ExecutionContext.ProcessingMessage, ExecutionContext.ProcessingMessageSender, f.Cause));

                //from state aggregate actor after persist
                Receive <AggregateActor.CommandExecuted>(c =>
                {
                    _log.Debug("Process instance created by message {@processResult}", ExecutionContext.ProcessingMessage);

                    var pendingStateId = ExecutionContext.PendingState.Id;
                    if (Id != pendingStateId)
                    {
                        _log.Debug("Redirecting message to newly created process state instance, {id}", pendingStateId);
                        var redirect = new MessageMetadataEnvelop(new ProcessRedirect(pendingStateId, ExecutionContext.ProcessingMessage), ExecutionContext.ProcessingMessage.Metadata);
                        //requesting redirect from parent - persistence hub
                        Context.Parent.Tell(redirect, ExecutionContext.ProcessingMessageSender);
                        Behavior.Become(AwaitingMessageBehavior, nameof(AwaitingMessageBehavior));
                        ExecutionContext.Clear();
                        return;
                    }

                    State = ExecutionContext.PendingState;
                    Self.Tell(ExecutionContext.ProcessingMessage, ExecutionContext.ProcessingMessageSender);
                    Behavior.Become(TransitingProcessBehavior, nameof(TransitingProcessBehavior));
                    ExecutionContext.Clear();
                });
                StashingMessagesToProcessBehavior("process is waiting for process instance creation");
            }
        }
コード例 #28
0
        protected virtual void AwaitingCommandBehavior()
        {
            DefaultBehavior();

            Command <IMessageMetadataEnvelop>(m =>
            {
                Monitor.Increment(nameof(CQRS.Command));
                var cmd  = (ICommand)m.Message;
                var name = cmd.Id.ToString();
                Log.Debug($"Received command {cmd.Id}");
                var actorRef = Context.Child(name);
                ExecutionContext.Validator       = actorRef != ActorRefs.Nobody ? actorRef : Context.ActorOf <CommandStateActor>(name);
                ExecutionContext.Command         = cmd;
                ExecutionContext.CommandMetadata = m.Metadata;
                ExecutionContext.CommandSender   = Sender;
                ExecutionContext.Validator.Tell(CommandStateActor.AcceptCommandExecution.Instance);

                Behavior.Become(ValidatingCommandBehavior, nameof(ValidatingCommandBehavior));
            }, m => m.Message is ICommand);
        }
コード例 #29
0
        private void InitializingBehavior()
        {
            ExecutionContext.IsInitializing = true;

            _stateActorSelection.ResolveOne(TimeSpan.FromSeconds(10))
            .PipeTo(Self);

            Receive <Status.Failure>(f => throw new CannotFindProcessStatePersistenceActor(ProcessStateActorSelection));
            Receive <IActorRef>(r =>
            {
                _stateAggregateActor = r;
                _stateAggregateActor.Tell(new GetProcessState(Id));
            });
            Receive <ProcesStateMessage <TState> >(ss =>
            {
                State = ss.State;
                ExecutionContext.IsInitializing = false;
                Behavior.Become(AwaitingMessageBehavior, nameof(AwaitingMessageBehavior));
            });
            StashingMessagesToProcessBehavior("process is initializing");
        }
コード例 #30
0
        private void AwaitingMessageBehavior()
        {
            Stash.Unstash();

            Receive <IMessageMetadataEnvelop>(env =>
            {
                if (env.Message is ProcessRedirect redirect)
                {
                    _log.Debug("Received redirected message");
                    Self.Tell(redirect.MessageToRedirect, Sender);
                    Behavior.Become(TransitingProcessBehavior, nameof(TransitingProcessBehavior));
                    return;
                }

                if (State == null)
                {
                    Self.Tell(new CreateNewProcess(env), Sender);
                    Behavior.Become(CreatingProcessBehavior, nameof(CreatingProcessBehavior));
                }
                else
                {
                    if (Id != GetProcessId(env.Message))
                    {
                        _log.Error("Received message {@message} "
                                   + "targeting different process. Process will not proceed.",
                                   env);

                        FinishWithError(env, Sender, new ProcessIdMismatchException());
                        return;
                    }

                    Self.Tell(env, Sender);
                    Behavior.Become(TransitingProcessBehavior, nameof(TransitingProcessBehavior));
                }
            });
            ProxifyingCommandsBehavior();
        }