private async Task Tick(CancellationToken cancellationToken) { var eventMapping = new EventMapping(EventMapping.DiscoverEventNamesInAssembly(typeof(ClockHasTicked).Assembly)); var clockStreamId = new StreamId(ClockStreamId); var lastClockHasTicked = await _streamStore.ReadStreamBackwards( streamId : clockStreamId, fromVersionInclusive : StreamVersion.End, maxCount : 1, prefetchJsonData : true, cancellationToken : cancellationToken); if (!lastClockHasTicked.Messages.Any()) { await AppendClockHasTicked(cancellationToken, clockStreamId, eventMapping); } else { var lastClockTickJsonData = await lastClockHasTicked.Messages[0].GetJsonData(cancellationToken); var lastClockTick = JsonConvert.DeserializeObject <ClockHasTicked>(lastClockTickJsonData); if (LocalDate.FromDateTime(lastClockTick.DateTime.Date) != _clockProvider.Today) { await AppendClockHasTicked(cancellationToken, clockStreamId, eventMapping); } } }
public async Task <Foo> Load(string id) { var page = await _streamStore.ReadStreamBackwards(id, StreamVersion.End, 1); if (page.Status == PageReadStatus.StreamNotFound) { return(null); } var streamMessage = page.Messages.First(); var jsonData = await streamMessage.GetJsonData(); var state = JsonConvert.DeserializeObject <FooMemento>(jsonData, _serializerSettings); return(new Foo(id, state, page.LastStreamVersion)); }
public async Task <IActionResult> GetDeliveriesPage(Guid id, int?start = null, CancellationToken cancellationToken = default(CancellationToken)) { var fromVersionInclusive = start ?? StreamVersion.End; var webHooks = await _webHooksRepository.Load(cancellationToken); if (!webHooks.TryGet(id, out var w)) { return(NotFound()); } var streamId = w.StreamIds.DeliveriesStreamId; var page = await _streamStore.ReadStreamBackwards(streamId, fromVersionInclusive, PageSize, true, cancellationToken); if (page.Status == PageReadStatus.StreamNotFound) { return(new ObjectResult(new DeliveryEventsPage { Next = StreamVersion.End })); } var items = page.Messages.Select(m => { var deliveryMetadata = JsonConvert.DeserializeObject <DeliveryMetadata>(m.JsonMetadata, WebHookPublisher.SerializerSettings); return(new DeliveryEventItem { MessageId = m.MessageId, EventMessageId = deliveryMetadata.EventId, EventSequence = deliveryMetadata.Sequence, Success = deliveryMetadata.DeliverySuccess, CreatedUtc = m.CreatedUtc, EventName = m.Type, Sequence = m.StreamVersion, ErrorMessage = deliveryMetadata.ErrorMessage }); }).ToArray(); return(new ObjectResult(new DeliveryEventsPage { Items = items, Next = items.Last().Sequence })); }
public async Task <Unit> Invoke(IStreamStore streamStore, CancellationToken ct) { var messageId = (await streamStore.ReadStreamBackwards( StreamId, StreamVersion, 1, true, ct)) .Messages.FirstOrDefault( message => StreamVersion == SqlStreamStore.Streams.StreamVersion.End || message.StreamVersion == StreamVersion) .MessageId; await streamStore.DeleteMessage(StreamId, messageId, ct); return(Unit.Instance); }
public async Task <WebHooks> Load(CancellationToken cancellationToken) { var page = await _streamStore.ReadStreamBackwards(_name, StreamVersion.End, 1, cancellationToken); if (page.Status == PageReadStatus.StreamNotFound) { await _streamStore.SetStreamMetadata(_name, maxCount : 1, cancellationToken : cancellationToken); return(new WebHooks(_getUtcNow, _maxWebHookCount)); } var json = await page.Messages[0].GetJsonData(cancellationToken); var memento = JsonConvert.DeserializeObject <WebHooksMemento>(json); return(new WebHooks(memento, _getUtcNow, _maxWebHookCount)); }
public static async Task <int> LastPosition(this IStreamStore streamStore, string key) { var page = await streamStore.ReadStreamBackwards(key, StreamVersion.End, 1); if (page.Status == PageReadStatus.StreamNotFound) { return(ExpectedVersion.NoStream); } if (page.Messages.Any()) { return(page.Messages.Single().StreamVersion); } return(ExpectedVersion.EmptyStream); }
public async ValueTask <Optional <TBusinessTransaction> > GetOptional(string id, CancellationToken cancellationToken = default) { var page = await _streamStore.ReadStreamBackwards(id, StreamVersion.End, 1, cancellationToken : cancellationToken); if (page.Messages.Length == 0) { return(Optional <TBusinessTransaction> .Empty); } var document = page.Messages[0]; var data = await document.GetJsonData(cancellationToken); return(JsonSerializer.Deserialize <TBusinessTransaction>(data).WithVersion(document.StreamVersion)); }
/// <inheritdoc /> public async Task <IConfigurationSettings> GetLatest(CancellationToken ct) { var lastPage = await _streamStore.ReadStreamBackwards( streamId : new StreamId(_streamId), fromVersionInclusive : StreamVersion.End, maxCount : 1, cancellationToken : ct); if (lastPage.Status == PageReadStatus.StreamNotFound) { return(ConfigurationSettings.Empty()); } var lastMessage = lastPage.Messages.First(); return(await BuildConfigurationSettingsFromMessage(lastMessage, _messageHooks, ct)); }
public Task <ReadStreamPage> Invoke(IStreamStore streamStore, CancellationToken ct) => ReadDirection == Constants.ReadDirection.Forwards ? streamStore.ReadStreamForwards(StreamId, _fromVersionInclusive, _maxCount, EmbedPayload, ct) : streamStore.ReadStreamBackwards(StreamId, _fromVersionInclusive, _maxCount, EmbedPayload, ct);
public async Task <StreamMessage> Invoke(IStreamStore streamStore, CancellationToken ct) => (await streamStore.ReadStreamBackwards(StreamId, StreamVersion, 1, true, ct)) .Messages.FirstOrDefault(message => StreamVersion == SqlStreamStore.Streams.StreamVersion.End || message.StreamVersion == StreamVersion);
public async Task <int> GetLastEventNumber(string streamId) { var result = await _streamStore.ReadStreamBackwards(new StreamId(streamId), StreamVersion.End, 1); return(result.LastStreamVersion); }
private async Task <bool> Validate( IStreamStore from, IStreamStore to, string branchId, bool failOnNoStream = false) { await _messageQueue.UncompletedMessagesOnBranch(branchId).FirstAsync(s => s == 0) .Timeout(Configuration.Timeout); var page = await from.ListStreams(); while (page.StreamIds.Length > 0) { foreach (var s in page.StreamIds.Where(x => !x.StartsWith("$"))) { var source = await from.GetStream(s, _serializer); if (source.Timeline != branchId) { continue; } var target = await to.GetStream(s, _serializer); if (target == null) // stream exists but some of the ancestors do not { return(false); } if (failOnNoStream && target.Version == ExpectedVersion.NoStream) { _log.Warn($"Stream {s} does not exist on target, probably due to missing ancestors", this); return(false); } if (source.Version <= target.Version && source.Version > ExpectedVersion.EmptyStream) { var fromMessage = (await from.ReadStreamBackwards(s, StreamVersion.End, 1)).Messages.SingleOrDefault(); var toMessage = (await to.ReadStreamForwards(s, source.ReadPosition(source.Version), 1)).Messages.SingleOrDefault(); if (fromMessage.MessageId == toMessage.MessageId) { return(true); } _log.Warn( $"Message doesn't match with remote for stream {s}@{source.Version} : " + $"{fromMessage.MessageId} != {toMessage.MessageId}", this); return(false); } var parent = source.Parent; while (parent != null && parent.Version > ExpectedVersion.EmptyStream) { if (!await Validate(from, to, parent.Timeline, true)) { return(false); } parent = parent.Parent; } } page = await page.Next(); } return(true); }
public async Task <int> ReadLastStreamVersion(string streamId, CancellationToken cancellationToken = default(CancellationToken)) { var end = await _store.ReadStreamBackwards(streamId, -1, 1, cancellationToken); return(end.LastStreamVersion); }
public Subscriber(IStreamStore store, StreamId targetStream) { if (store == null) { throw new ArgumentNullException(nameof(store)); } MessagePumpCancellation = new CancellationTokenSource(); Mailbox = new BufferBlock <object>( new DataflowBlockOptions { BoundedCapacity = int.MaxValue, MaxMessagesPerTask = 1, CancellationToken = MessagePumpCancellation.Token } ); Disposed = Mailbox .Completion .ContinueWith( task => { MessagePumpCancellation?.Dispose(); }, TaskContinuationOptions.ExecuteSynchronously); MessagePump = new Lazy <Task>( () => Task.Run(async() => { long?position = null; var targetStreamVersion = ExpectedVersion.NoStream; var page = await store.ReadStreamBackwards(targetStream, StreamVersion.End, 1, MessagePumpCancellation.Token); if (page.Status == PageReadStatus.Success) { targetStreamVersion = page.LastStreamVersion; if (page.Messages.Length == 1) { position = JsonConvert .DeserializeObject <MetaDataView>(page.Messages[0].JsonMetadata) .CausedByPosition; } } var subscription = store.SubscribeToAll( position, async(_, received, token) => { if (received.StreamId != targetStream) // skip your own messages { var msg = new Messages.AllStreamSubscriptionReceivedMessage { Position = received.Position, StreamId = received.StreamId, StreamVersion = received.StreamVersion, MessageId = received.MessageId, Type = received.Type, JsonData = await received.GetJsonData(token), JsonMetaData = received.JsonMetadata, CreatedUtc = received.CreatedUtc }; await Mailbox.SendAsync(msg, token); } }, (_, reason, exception) => Mailbox.Post(new Messages.AllStreamSubscriptionDropped { Reason = reason, Exception = exception })); while (!MessagePumpCancellation.IsCancellationRequested) { var message = await Mailbox.ReceiveAsync(MessagePumpCancellation.Token); switch (message) { case Messages.AllStreamSubscriptionReceivedMessage received: var appendResult = await store.AppendToStream( targetStream, targetStreamVersion, new [] { new NewStreamMessage( received.MessageId, received.Type, received.JsonData, received.JsonMetaData) }, MessagePumpCancellation.Token); targetStreamVersion = appendResult.CurrentVersion; break; case Messages.AllStreamSubscriptionDropped dropped: break; } } }, MessagePumpCancellation.Token), LazyThreadSafetyMode.ExecutionAndPublication); }
public Task <ReadStreamPage> ReadStreamBackwards(StreamId streamId, int fromVersionInclusive, int maxCount, bool prefetchJsonData = true, CancellationToken cancellationToken = new CancellationToken()) { return(_store.ReadStreamBackwards(streamId, fromVersionInclusive, maxCount, prefetchJsonData, cancellationToken)); }