/// <summary> /// Adds the specified message. /// The message must have a 'streamId' and an 'eventNumber' in the message header bag. /// The 'streamId' is the name of the stream to append the message to. /// The 'eventNumber' should be one greater than the last event in the stream. /// </summary> /// <param name="message">The message.</param> /// <param name="outBoxTimeout">The outBoxTimeout.</param> /// <returns>Task.</returns> public void Add(Message message, int outBoxTimeout = -1, IAmABoxTransactionConnectionProvider transactionConnectionProvider = null) { s_logger.LogDebug("Adding message to Event Store Outbox: {Request}", JsonSerializer.Serialize(message, JsonSerialisationOptions.Options)); var headerBag = message.Header.Bag; var streamId = ExtractStreamIdFromHeader(headerBag, message.Id); var eventNumber = ExtractEventNumberFromHeader(headerBag, message.Id); var numberOfPreviousEvent = eventNumber - 1; var eventData = EventStoreMessageWriter.CreateEventData(message); _eventStore.AppendToStreamAsync(streamId, numberOfPreviousEvent, eventData).Wait(); }
/// <summary> /// Awaitable add the specified message. /// </summary> /// <param name="message">The message.</param> /// <param name="outBoxTimeout">The time allowed for the write in milliseconds; on a -1 default</param> /// <param name="cancellationToken">Allows the sender to cancel the request pipeline. Optional</param> /// <returns><see cref="Task"/>.</returns> public async Task AddAsync(Message message, int outBoxTimeout = -1, CancellationToken cancellationToken = default(CancellationToken), IAmABoxTransactionConnectionProvider transactionConnectionProvider = null) { s_logger.LogDebug("Adding message to Event Store Outbox: {Request}", JsonSerializer.Serialize(message, JsonSerialisationOptions.Options)); var streamId = ExtractStreamIdFromHeader(message.Header.Bag, message.Id); var eventNumber = ExtractEventNumberFromHeader(message.Header.Bag, message.Id); var numberOfPreviousEvent = eventNumber - 1; var eventData = EventStoreMessageWriter.CreateEventData(message); await _eventStore.AppendToStreamAsync(streamId, numberOfPreviousEvent, eventData); }
/// <summary> /// Update a message to show it is dispatched /// </summary> /// <param name="id">The id of the message to update</param> /// <param name="dispatchedAt">When was the message dispatched, defaults to UTC now</param> /// <param name="args">Additional parameters required for search, if any</param> /// <param name="cancellationToken">Allows the sender to cancel the request pipeline. Optional</param> public async Task MarkDispatchedAsync(Guid id, DateTime?dispatchedAt = null, Dictionary <string, object> args = null, CancellationToken cancellationToken = default) { var stream = GetStreamFromArgs(args); StreamEventsSlice slice; var startPos = (long)StreamPosition.End; long? nextEventNumber = null; RecordedEvent resolvedEvent; bool found = false; do { slice = await _eventStore.ReadStreamEventsBackwardAsync(stream, startPos, 100, true); startPos = slice.NextEventNumber; if (nextEventNumber is null) { nextEventNumber = (await _eventStore.ReadStreamEventsBackwardAsync(stream, StreamPosition.End, 1, true)).LastEventNumber; } resolvedEvent = slice.Events.FirstOrDefault(e => e.Event.EventId == id).Event; if (resolvedEvent != null) { found = true; } } while (!found && !slice.IsEndOfStream); if (resolvedEvent is null) { return; } var message = EventStoreMessageReader.ConvertEventToMessage(resolvedEvent, stream, dispatchedAt, nextEventNumber.Value); var eventData = EventStoreMessageWriter.CreateEventData(message); await _eventStore.AppendToStreamAsync(stream, nextEventNumber.Value, eventData); }