Пример #1
0
        private async Task <FastForwardResult> FastForward(IStreamStore from, IStreamStore to, string branchId)
        {
            var fastForwardResult = new FastForwardResult();
            var page = await from.ListStreams();

            while (page.StreamIds.Length > 0)
            {
                foreach (var s in page.StreamIds.Where(x => x.StartsWith(branchId)))
                {
                    var localPosition = await from.LastPosition(s);

                    var remotePosition = await to.LastPosition(s);

                    if (localPosition == remotePosition)
                    {
                        continue;
                    }

                    var eventPage = await from.ReadStreamForwards(s, Math.Max(remotePosition + 1, 0), Configuration.BatchSize);

                    var appendMessages = new List <NewStreamMessage>();

                    if (eventPage.Messages.Length == 0 && localPosition >= ExpectedVersion.EmptyStream)
                    {
                        await to.AppendToStream(s, remotePosition, appendMessages.ToArray());
                    }

                    var metadata = await from.GetStreamMetadata(s);

                    await to.SetStreamMetadata(s, ExpectedVersion.Any, metadata.MaxAge, metadata.MaxCount, metadata.MetadataJson);

                    while (eventPage.Messages.Length > 0)
                    {
                        appendMessages.Clear();
                        foreach (var m in eventPage.Messages)
                        {
                            var payload = await m.GetJsonData();

                            var message = new NewStreamMessage(m.MessageId, m.Type, payload, m.JsonMetadata);
                            appendMessages.Add(message);
                        }

                        var result = await to.AppendToStream(s, remotePosition, appendMessages.ToArray());

                        fastForwardResult.NumberOfMessages += result.CurrentVersion - Math.Max(remotePosition, ExpectedVersion.EmptyStream);
                        eventPage = await eventPage.ReadNext();
                    }

                    fastForwardResult.NumberOfStreams++;
                }

                page = await page.Next();
            }

            fastForwardResult.ResultStatus = Status.Success;

            return(fastForwardResult);
        }
        public async Task ShouldAddNewAggregate()
        {
            // Arrange
            var aggregate = new TestAggregate();

            // Act
            await _sut.Save(aggregate);

            // Assert
            var streamId = _sut.GetStreamId(aggregate);
            var streams  = await _streamStore.ListStreams(Pattern.StartsWith(streamId));

            streams.StreamIds.Length.ShouldBe(1);
            var events = (await _streamStore.ReadStreamForwards(streamId, StreamVersion.Start, 1)).Messages;

            (await Task.WhenAll(events.Select(@event => @event.ToEvent(CancellationToken.None))))
            .All(@event => @event.GetType() == typeof(TestEvent)).ShouldBeTrue();
        }
Пример #3
0
        /// <inheritdoc />
        public async Task DeleteBranch(string branchId)
        {
            var page = await _streamStore.ListStreams(Configuration.BatchSize);

            while (page.StreamIds.Length > 0)
            {
                foreach (var s in page.StreamIds)
                {
                    if (!s.StartsWith(branchId) || !s.Contains("Command"))
                    {
                        continue;
                    }

                    await _streamStore.DeleteStream(s);

                    _log.Debug($"Deleted {nameof(ICommand)} stream {s}");
                }

                page = await page.Next();
            }
        }
 public Task <ListStreamsPage> Invoke(IStreamStore streamStore, CancellationToken cancellationToken)
 => streamStore.ListStreams(Pattern, MaxCount, ContinuationToken, cancellationToken);
Пример #5
0
 /// <inheritdoc />
 protected override async Task ListStreamsObservable(IObserver <IStream> observer, Func <string, bool> predicate, CancellationToken token)
 {
     var page = await _streamStore.ListStreams(Pattern.Anything(), Configuration.BatchSize, default, token);
Пример #6
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);
        }
Пример #7
0
 public Task <ListStreamsPage> ListStreams(int maxCount = 100, string continuationToken = null,
                                           CancellationToken cancellationToken = new CancellationToken())
 {
     return(_store.ListStreams(maxCount, continuationToken, cancellationToken));
 }