void Enqueue(PersistenceRequest request) { _buffer.AddLast(new BufferEntry { Request = request, Sender = Sender }); if (!_flushRequested) { Self.Tell(new FlushBufferCommand(), Self); _flushRequested = true; } }
void Ready() { SetReceiveTimeout(_options.CommandProcessorIdleTimeout); Receive<ProcessorCommand>(async c => { // ensure the timeout hasn't expired if (c.Timeout.IsExpired) { Sender.Tell(new CommandTimeout(c.CommandID)); return; } try { await Validate(c.Command); await _commandHandlers.Handle(c.Command); } // handle command rejections catch (RejectException ex) { Sender.Tell(new CommandRejected(c.CommandID, ex.Reasons)); return; } // handle unexpected exceptions catch (Exception ex) { Sender.Tell(new CommandFailed(c.CommandID, ex)); return; } if (_unpersistedEvents.Count > 0) { var request = new PersistenceRequest(_unpersistedEvents.ToList()); // command processors don't need to wait for persistence, so // we delegate it to a worker and move on to wait for new commands // the worker will wait for responses and notify the sender var props = PersistenceWorker.CreateProps(request.PersistenceID, c.CommandID, Sender, _options.CommandProcessorPersistenceTimeout); var worker = Context.ActorOf(props); // send the request on behalf of the worker and let it wait for responses _writer.Tell(request, worker); // clear the unpersisted events _unpersistedEvents.Clear(); } }); Receive<ReceiveTimeout>(_ => StopSelf()); }
public void Writer_tells_persistedevents_to_dispatcher_in_order() { var dispatcher = CreateTestProbe(); var writer = CreateWriter(writer: MockEventStore.SuccessfulWriter(), dispatcher: dispatcher); var request = new PersistenceRequest(new[] { new UnpersistedEvent("a", new SampleEvent3()), new UnpersistedEvent("a", new SampleEvent1()), new UnpersistedEvent("a", new SampleEvent2()) }); writer.Tell(request); dispatcher.ExpectMsg<IPersistedEvent<SampleEvent3>>(); dispatcher.ExpectMsg<IPersistedEvent<SampleEvent1>>(); dispatcher.ExpectMsg<IPersistedEvent<SampleEvent2>>(); dispatcher.ExpectNoMsg(50); }
private async Task HandleRequest(PersistenceRequest request) { try { await WriteEvents(request); Sender.Tell(new PersistenceSuccess(request.PersistenceID)); } catch (UnexpectedStreamSequenceException) { Sender.Tell(new UnexpectedStreamSequence(request.PersistenceID)); } catch (DuplicatedEntryException) { Sender.Tell(new DuplicatedEntry(request.PersistenceID)); } catch (Exception ex) { Sender.Tell(new PersistenceFailure(request.PersistenceID, ex)); } }
protected async Task WriteEvents(PersistenceRequest request) { var events = request.Events; // serialize the events into raw events var rawEvents = UnpersistedRawEvent.FromUnpersistedEvents(events, _serializer); // writes all events to the store await _writer.WriteStreamAsync(request.Stream, request.ExpectedStreamSequence, rawEvents); // publishes the events in the order they were sent for (int i = 0, len = events.Count; i < len; i++) { var e = events[i]; var re = rawEvents[i]; var persistedEvent = PersistedEventFactory.FromUnpersistedEvent(re.GlobalSequence, e); // publish to the event stream _dispatcher.Tell(persistedEvent); } }
public void Writer_does_not_publish_to_event_stream() { var dispatcher = CreateTestProbe(); var writer = CreateWriter(writer: MockEventStore.SuccessfulWriter(), dispatcher: dispatcher); var request = new PersistenceRequest(new[] { new UnpersistedEvent("a", new SampleEvent3()), new UnpersistedEvent("a", new SampleEvent1()), new UnpersistedEvent("a", new SampleEvent2()) }); var probe = CreateTestProbe(); Sys.EventStream.Subscribe(probe, typeof(IPersistedEvent)); writer.Tell(request); probe.ExpectNoMsg(TimeSpan.FromMilliseconds(500)); }