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);
                }
            }
        }
Exemple #2
0
        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));
        }
Exemple #6
0
        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));
        }
Exemple #8
0
        /// <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);
Exemple #10
0
 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);
Exemple #11
0
        public async Task <int> GetLastEventNumber(string streamId)
        {
            var result = await _streamStore.ReadStreamBackwards(new StreamId(streamId), StreamVersion.End, 1);

            return(result.LastStreamVersion);
        }
Exemple #12
0
        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);
        }
Exemple #13
0
        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);
        }
Exemple #15
0
 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));
 }