public void All_sync_handlers_performs_one_after_one() { Sys.InitLocalTransportExtension(); var delayActor = Sys.ActorOf(Props.Create(() => new EchoSleepActor(TimeSpan.FromMilliseconds(50), TestActor))); var catalog = new HandlersDefaultProcessor(); catalog.Add <BalloonCreated>(new SyncProjectionProcessor(delayActor)); catalog.Add <BalloonTitleChanged>(new SyncProjectionProcessor(delayActor)); catalog.Add <BalloonTitleChanged>(new SyncProjectionProcessor(delayActor)); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); actor.Tell(MessageMetadataEnvelop.New(new BalloonCreated("1", Guid.NewGuid().ToString()))); //in sync process we should wait for handlers execution //in same order as they were sent to handlers process actor ExpectMsg <MarkedHandlerExecutedMessage>(); ExpectMsg <IMessageMetadataEnvelop <DomainEvent> >(); //HandlersProcessActor should notify sender (TestActor) of initial messages that work is done ExpectMsg <AllHandlersCompleted>(); actor.Tell(MessageMetadataEnvelop.New(new BalloonTitleChanged("2", Guid.NewGuid().ToString()))); ExpectMsg <MarkedHandlerExecutedMessage>(); ExpectMsg <MarkedHandlerExecutedMessage>(); //HandlersProcessActor should notify next step - process actor that work is done ExpectMsg <IMessageMetadataEnvelop <DomainEvent> >(); ExpectMsg <AllHandlersCompleted>(); }
public void Condition_wait_end_should_be_true_on_B_and_C() { var sampleObjectsReceived = new object[] { MessageMetadataEnvelop.New(_messageB), MessageMetadataEnvelop.New(_messageC) }; Assert.True(Waiter.ConditionBuilder.StopCondition(sampleObjectsReceived)); }
public void Process_transition_raises_state_events() { _processActor.Ref.Tell(MessageMetadataEnvelop.New(new BalloonCreated("1", Guid.NewGuid().ToString(), DateTime.Now, _processId), MessageMetadata.Empty)); _localAkkaEventBusTransport.Subscribe(typeof(IMessageMetadataEnvelop), TestActor); FishForMessage <MessageMetadataEnvelop>(m => m.Message is ProcessManagerCreated <TestState>); FishForMessage <MessageMetadataEnvelop>(m => m.Message is ProcessReceivedMessage <TestState>); }
public void Process_change_state_after_transitions() { var domainEventA = new BalloonCreated("1", Guid.NewGuid().ToString(), DateTime.Now, _processId); _processActor.Ref.Tell(MessageMetadataEnvelop.New(domainEventA)); var msg = ExpectMsg <ProcessTransited>(); Assert.Equal(domainEventA.SourceId, ((TestState)msg.NewProcessState).ProcessingId); }
public void Given_no_processors_pipe_still_reply_with_completed_messages() { var catalog = new HandlersDefaultProcessor(); Sys.InitLocalTransportExtension(); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); var sampleAggregateCreatedEvent = new BalloonCreated("1", Guid.NewGuid().ToString()); actor.Tell(MessageMetadataEnvelop.New(sampleAggregateCreatedEvent, MessageMetadata.Empty)); //HandlersPipeActor should notify next step - process actor that work is done ExpectMsg <IMessageMetadataEnvelop <DomainEvent> >(); //HandlersPipeActor should notify sender (TestActor) of initial messages that work is done ExpectMsg <AllHandlersCompleted>(); }
public async Task ProcessManagerPipeActor_does_not_support_domain_event_inheritance() { var testProcessActor = Sys.ActorOf(Props.Create(() => new TestProcessActor(TestActor, Guid.NewGuid().ToString(), null))); var catalog = new ProcessesDefaultProcessor(); catalog.Add <BalloonCreated>(new SyncProcessManagerProcessor(testProcessActor)); var processPipeActor = Sys.ActorOf(Props.Create(() => new ProcessesPipeActor(catalog))); await processPipeActor.Ask <Initialized>(new Initialize(TestActor)); var msg = MessageMetadataEnvelop.New <DomainEvent>(new Inherited()); processPipeActor.Tell(msg); ExpectMsg <ProcessesTransitComplete>(); //process processor did not run due to error, but we received processing complete message ExpectNoMsg(TimeSpan.FromSeconds(1)); }
public void Process_actor_process_one_message_in_time() { var domainEventA = new BalloonCreated("1", Guid.NewGuid().ToString(), DateTime.Now, _processId); var domainEventB = new BalloonTitleChanged("2", Guid.NewGuid().ToString(), DateTime.Now, _processId); _processActor.Tell(MessageMetadataEnvelop.New(domainEventA, MessageMetadata.Empty)); _processActor.Tell(MessageMetadataEnvelop.New(domainEventB, MessageMetadata.Empty)); //A was received first and should be processed first var msg = ExpectMsg <ProcessTransited>(); Assert.Equal(domainEventA.SourceId, ((TestState)msg.NewProcessState).ProcessingId); //B should not be processed after A is completed var msgB = ExpectMsg <ProcessTransited>(); Assert.Equal(domainEventB.SourceId, ((TestState)msgB.NewProcessState).ProcessingId); }
public void CustomHandlerExecutor_does_not_support_domain_event_inheritance() { Sys.InitLocalTransportExtension(); var catalog = new HandlersDefaultProcessor(); catalog.Add <BalloonCreated>(new SyncProjectionProcessor(TestActor)); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); var msg = MessageMetadataEnvelop.New(new Inherited()); actor.Tell(msg); //processor did not run, but we pass message to process after ExpectMsg <MessageMetadataEnvelop <Inherited> >(); //processor did not run, but we received processing complete message ExpectMsg <AllHandlersCompleted>(); }
public void CustomHandlerProcessor_routes_events_by_type() { Sys.InitLocalTransportExtension(); var catalog = new HandlersDefaultProcessor(); catalog.Add <BalloonCreated>(new FireAndForgetActorMessageProcessor(TestActor)); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); actor.Tell(MessageMetadataEnvelop.New(new BalloonCreated("1", Guid.NewGuid().ToString()))); //TestActor as processor receives message for work ExpectMsg <MessageMetadataEnvelop <BalloonCreated> >(); //HandlersProcessActor should resend domain event to next step - process actor - for processing ExpectMsg <MessageMetadataEnvelop <BalloonCreated> >(); //HandlersProcessActor should notify sender (TestActor) of initial messages that work is done ExpectMsg <AllHandlersCompleted>(); }
public void Sync_and_async_handlers_performs_independent() { Sys.InitLocalTransportExtension(); var fastHandler = Sys.ActorOf(Props.Create(() => new EchoSleepActor(TimeSpan.FromMilliseconds(1), TestActor))); var slowHandler = Sys.ActorOf(Props.Create(() => new EchoSleepActor(TimeSpan.FromMilliseconds(500), TestActor))); var catalog = new HandlersDefaultProcessor(); //Slow handler will receive messages first. //Due to it is registered with async process policy //second handler (fast) will not wait for slow one and it will finish execution before slow handler catalog.Add <BalloonCreated>(new FireAndForgetActorMessageProcessor(slowHandler)); catalog.Add <BalloonCreated>(new SyncProjectionProcessor(fastHandler)); catalog.Add <BalloonTitleChanged>(new FireAndForgetActorMessageProcessor(slowHandler)); catalog.Add <BalloonTitleChanged>(new SyncProjectionProcessor(fastHandler)); var actor = Sys.ActorOf(Props.Create(() => new HandlersPipeActor(catalog, TestActor))); actor.Tell(MessageMetadataEnvelop.New(new BalloonCreated("1", Guid.NewGuid().ToString()))); actor.Tell(MessageMetadataEnvelop.New(new BalloonTitleChanged("1", Guid.NewGuid().ToString()))); ExpectMsg <MarkedHandlerExecutedMessage>((e, s) => e.ProcessingMessage.Message is BalloonCreated && s == fastHandler); ExpectMsg <IMessageMetadataEnvelop <BalloonCreated> >(); ExpectMsg <AllHandlersCompleted>(); //for balloon created ExpectMsg <MarkedHandlerExecutedMessage>((e, s) => e.ProcessingMessage.Message is BalloonTitleChanged && s == fastHandler); //HandlersProcessActor should notify next step - process actor that work is done ExpectMsg <IMessageMetadataEnvelop <BalloonTitleChanged> >(); //HandlersProcessActor should notify sender (TestActor) of initial messages that work is done ExpectMsg <AllHandlersCompleted>(); //slow fire and handlers will finish execution in undetermined order ExpectMsg <MarkedHandlerExecutedMessage>(); ExpectMsg <MarkedHandlerExecutedMessage>(); }
public async Task All_Processes_performs_linear_and_results_from_all_processes_are_gathered() { var processAId = Guid.NewGuid().ToString(); _output.WriteLine("Process A:" + processAId); var testProcessActorA = Sys.ActorOf(Props.Create(() => new TestProcessActor(TestActor, processAId, TimeSpan.FromMilliseconds(1000)))); var processBId = Guid.NewGuid().ToString(); _output.WriteLine("Process B:" + processBId); var testProcessActorB = Sys.ActorOf(Props.Create(() => new TestProcessActor(TestActor, processBId, TimeSpan.FromMilliseconds(50)))); var processCId = Guid.NewGuid().ToString(); _output.WriteLine("Process C:" + processCId); var testProcessActorC = Sys.ActorOf(Props.Create(() => new TestProcessActor(TestActor, processCId, TimeSpan.FromMilliseconds(50)))); var catalog = new ProcessesDefaultProcessor(); catalog.Add <BalloonCreated>(new SyncProcessManagerProcessor(testProcessActorA)); catalog.Add <BalloonTitleChanged>(new SyncProcessManagerProcessor(testProcessActorB)); catalog.Add <BalloonTitleChanged>(new SyncProcessManagerProcessor(testProcessActorC)); var balloonCreated = new BalloonCreated("1", Guid.NewGuid().ToString()); var balloonTitleChanged = new BalloonTitleChanged("2", Guid.NewGuid().ToString()); //var resultA = await catalog.Process(MessageMetadataEnvelop.New<DomainEvent>(balloonCreated)); //var resultB = await catalog.Process(MessageMetadataEnvelop.New<DomainEvent>(balloonTitleChanged)); var processPipeActor = Sys.ActorOf(Props.Create(() => new ProcessesPipeActor(catalog))); await processPipeActor.Ask <Initialized>(new Initialize(TestActor)); processPipeActor.Tell(MessageMetadataEnvelop.New <DomainEvent>(balloonCreated)); processPipeActor.Tell(MessageMetadataEnvelop.New <DomainEvent>(balloonTitleChanged)); //process pipe will process domain event linear on each message //but for don't wait for each message execution end, so first will complete process of second message - balloonTitleChanged //after process pipe will proceed with balloonTitleChanged event, pass it linear to two left process managers var transited = ExpectMsg <ProcessTransited>(TimeSpan.FromSeconds(600)); var testCommand = transited.ProducedCommands.OfType <TestCommand>().First(); Assert.Equal(processBId, testCommand.ProcessId); transited = ExpectMsg <ProcessTransited>(); testCommand = transited.ProducedCommands.OfType <TestCommand>().First(); Assert.Equal(processCId, testCommand.ProcessId); //after it process pipe is finished with ballon created message processing, gathering results //and sending it to commandPipe (testActor) var cmdB = ExpectMsg <MessageMetadataEnvelop <ICommand> >(); Assert.Equal(processBId, cmdB.Message.ProcessId); var cmdC = ExpectMsg <MessageMetadataEnvelop <ICommand> >(); Assert.Equal(processCId, cmdC.Message.ProcessId); //than it will report end of domain event processing ExpectMsg <ProcessesTransitComplete>(); //than slow processing of first message will finish //test process actors sends to us messages on complete //wait for test process actor transit on first event transited = ExpectMsg <ProcessTransited>(); testCommand = transited.ProducedCommands.OfType <TestCommand>().First(); Assert.Equal(processAId, testCommand.ProcessId); var cmdA = ExpectMsg <MessageMetadataEnvelop <ICommand> >(); Assert.Equal(processAId, cmdA.Message.ProcessId); //process pipe has only one handler for balloonCreated, so it will finish processing //and send us a message ExpectMsg <ProcessesTransitComplete>(); }