public async Task Should_not_subscribe_on_notify_when_stream_matches()
        {
            var sut = new PollingSubscription(eventStore, eventNotifier, eventSubscriber, "^my-stream", position);

            eventNotifier.NotifyEventsStored("other-stream-123");

            await WaitAndStopAsync(sut);

            A.CallTo(() => eventStore.GetEventsAsync(A <Func <StoredEvent, Task> > .Ignored, A <CancellationToken> .Ignored, "^my-stream", position))
            .MustHaveHappened(Repeated.Exactly.Once);
        }
Esempio n. 2
0
        private async Task AppendEventsInternalAsync(Guid commitId, string streamName, long expectedVersion, ICollection <EventData> events)
        {
            Guard.NotNullOrEmpty(streamName, nameof(streamName));
            Guard.NotNull(events, nameof(events));

            if (events.Count == 0)
            {
                return;
            }

            var currentVersion = await GetEventStreamOffset(streamName);

            if (expectedVersion != AnyVersion && expectedVersion != currentVersion)
            {
                throw new WrongEventVersionException(currentVersion, expectedVersion);
            }

            var commit = BuildCommit(commitId, streamName, expectedVersion >= -1 ? expectedVersion : currentVersion, events);

            for (var attempt = 0; attempt < MaxAttempts; attempt++)
            {
                try
                {
                    await Collection.InsertOneAsync(commit);

                    notifier.NotifyEventsStored();

                    return;
                }
                catch (MongoWriteException ex)
                {
                    if (ex.WriteError?.Category == ServerErrorCategory.DuplicateKey)
                    {
                        currentVersion = await GetEventStreamOffset(streamName);

                        if (expectedVersion != AnyVersion)
                        {
                            throw new WrongEventVersionException(currentVersion, expectedVersion);
                        }
                        else if (attempt < MaxAttempts)
                        {
                            expectedVersion = currentVersion;
                        }
                        else
                        {
                            throw new TimeoutException("Could not acquire a free slot for the commit within the provided time.");
                        }
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
Esempio n. 3
0
        public async Task AppendEventsAsync(Guid commitId, string streamName, int expectedVersion, ICollection <EventData> events)
        {
            Guard.NotNullOrEmpty(streamName, nameof(streamName));
            Guard.NotNull(events, nameof(events));

            var eventsCount = events.Count;

            if (eventsCount > 0)
            {
                var commitEvents = new MongoEvent[events.Count];

                var i = 0;

                foreach (var e in events)
                {
                    var mongoEvent = new MongoEvent {
                        EventId = e.EventId, Metadata = e.Metadata, Payload = e.Payload, Type = e.Type
                    };

                    commitEvents[i++] = mongoEvent;
                }

                var commit = new MongoEventCommit
                {
                    Id                = commitId,
                    Events            = commitEvents,
                    EventsCount       = eventsCount,
                    EventStream       = streamName,
                    EventStreamOffset = expectedVersion,
                    Timestamp         = EmptyTimestamp
                };

                try
                {
                    await Collection.InsertOneAsync(commit);

                    notifier.NotifyEventsStored();
                }
                catch (MongoWriteException ex)
                {
                    if (ex.WriteError?.Category == ServerErrorCategory.DuplicateKey)
                    {
                        var currentVersion = await GetEventStreamOffset(streamName);

                        throw new WrongEventVersionException(currentVersion, expectedVersion);
                    }

                    throw;
                }
            }
        }
Esempio n. 4
0
        public async Task AppendEventsAsync(Guid commitId, string streamName, int expectedVersion, IEnumerable <EventData> events)
        {
            Guard.NotNullOrEmpty(streamName, nameof(streamName));
            Guard.NotNull(events, nameof(events));

            var currentVersion = await GetEventStreamOffset(streamName);

            if (currentVersion != expectedVersion)
            {
                throw new WrongEventVersionException(currentVersion, expectedVersion);
            }

            var now = clock.GetCurrentInstant();

            var commitEvents = events.Select(x => SimpleMapper.Map(x, new MongoEvent())).ToList();

            if (commitEvents.Any())
            {
                var offset = await GetEventOffsetAsync();

                var commit = new MongoEventCommit
                {
                    Id                = commitId,
                    Events            = commitEvents,
                    EventsOffset      = offset,
                    EventsCount       = commitEvents.Count,
                    EventStream       = streamName,
                    EventStreamOffset = expectedVersion,
                    Timestamp         = now
                };

                for (var retry = 0; retry < Retries; retry++)
                {
                    try
                    {
                        await Collection.InsertOneAsync(commit);

                        notifier.NotifyEventsStored();

                        return;
                    }
                    catch (MongoWriteException ex)
                    {
                        if (ex.Message.IndexOf(eventsOffsetIndex, StringComparison.OrdinalIgnoreCase) >= 0)
                        {
                            commit.EventsOffset = await GetEventOffsetAsync();
                        }
                        else if (ex.WriteError?.Category == ServerErrorCategory.DuplicateKey)
                        {
                            currentVersion = await GetEventStreamOffset(streamName);

                            throw new WrongEventVersionException(currentVersion, expectedVersion);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }
        }