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; } }
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; } }
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); } }
Task Unstarted(IContext context) { switch (context.Message) { case Started _: { SpawnSocketAgent(context); _behaviour.Become(Disconnected); break; } } return(Done); }
Task AwaitStart(IContext context) { switch (context.Message) { case Started _: { _behaviour.Become(AwaitConnectionStart); return(Done); } default: return(Done); } }
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)); }
/// <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); }
public MetroBikeShareActor() { _metroBikeShareApi = RestClient.For <IMetroBikeShareApi>("https://bikeshare.metro.net"); _stationActors = new Dictionary <string, PID>(); _behavior = new Behavior(); _behavior.Become(Refreshing); }
async Task <object> Off(object message) { switch (message) { case PressSwitch _: await behavior.Become(On); return("Turning on"); case Touch _: return("Cold"); default: return(Unhandled); } }
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); }
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); }
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}"); }
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; } }
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); }
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); }
Task Unstarted(IContext context) { switch (context.Message) { case Started _: { _behaviour.Become(Running); break; } } return(Done); }
async Task Become(Receive other) { try { await behavior.Become(other); } catch (Exception) { Activation.DeactivateOnIdle(); throw; } }
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); }
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)); }
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; } }
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); }
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"); } }
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; } }
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(); }
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); }
public async Task ReceiveAsync(IContext context) { switch (context.Message) { case Started msg: _behavior.Become(Starting); await _persistence.RecoverStateAsync(); break; // ... } await _behavior.ReceiveAsync(context); }
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"); } }
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); }
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"); }
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(); }