예제 #1
0
        public async Task<EventStreamPosition> AppendEventsAsync(
            string streamName,
            EventStreamPosition position,
            IReadOnlyCollection<JournaledEvent> events)
        {
            Require.NotEmpty(streamName, "streamName");
            Require.NotEmpty(events, "events");

            var batch = m_table.PrepareBatchOperation();

            var targetVersion = position.Version.Increment(events.Count);
            WriteHeadProperty(streamName, position, (int) targetVersion, batch);
            WriteEvents(streamName, position.Version, events, batch);

            try
            {
                var batchResult = await batch.ExecuteAsync();
                var headResult = batchResult[0];

                return new EventStreamPosition(headResult.ETag, targetVersion);
            }
            catch (BatchOperationException exception)
            {
                if (exception.OperationBatchNumber == 0 && IsConcurrencyException(exception))
                {
                    throw new EventStreamConcurrencyException(
                        "Event stream '{0}' was concurrently updated.".FormatString(streamName),
                        exception);
                }

                throw;
            }
        }
예제 #2
0
 private EventStreamSlice()
 {
     m_streamPosition = EventStreamPosition.Start;
     m_events = new SortedList<StreamVersion, JournaledEvent>(0);
     m_endOfStream = true;
     m_currentSlicePosition = EventStreamPosition.Start;
 }
예제 #3
0
        public EventStreamSlice(EventStreamPosition streamPosition, SortedList<StreamVersion, JournaledEvent> events)
        {
            Require.NotNull(events, "events");

            m_streamPosition = streamPosition;
            m_events = events;

            var lastFetchedVersion = events.Keys[events.Count - 1];
            m_endOfStream = lastFetchedVersion >= streamPosition.Version;
            m_currentSlicePosition = new EventStreamPosition(streamPosition.ETag, lastFetchedVersion);
        }
예제 #4
0
        public FetchingCursorState(
            EventStreamPosition position,
            EventStreamPosition currentSlicePosition,
            FetchEvents fetch)
        {
            Require.NotNull(fetch, "fetch");

            m_position = position;
            m_currentSlicePosition = currentSlicePosition;
            m_fetch = fetch;
        }
예제 #5
0
        public async Task AppendEventsAsync(IReadOnlyCollection<JournaledEvent> events)
        {
            Require.NotNull(events, "events");

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

            m_endOfStream = await m_journal.AppendEventsAsync(m_streamName, m_endOfStream, events);
        }
예제 #6
0
        public EventStreamWriter(
            string streamName,
            EventStreamPosition endOfStream,
            IEventJournal journal)
        {
            Require.NotEmpty(streamName, "streamName");
            Require.NotNull(journal, "journal");

            m_streamName = streamName;
            m_endOfStream = endOfStream;
            m_journal = journal;
        }
예제 #7
0
        public EventStreamCursor(EventStreamPosition position, StreamVersion fromVersion, FetchEvents fetch)
        {
            Require.NotNull(fetch, "fetch");

            if (EventStreamPosition.IsNewStream(position))
            {
                m_state = new EndOfStreamCursorState();
                m_slice = EventStreamSlice.Empty;
            }
            else
            {
                m_state = new InitialCursorState(position, fromVersion, fetch);
            }
        }
예제 #8
0
        public async Task StreamPosition_AfterWriteAsyncCall_UpdatedStreamVersionValue(
            [Frozen] Mock<IEventJournal> journalMock,
            EventStreamPosition position,
            EventStreamWriter writer,
            JournaledEvent[] events)
        {
            journalMock
                .Setup(self => self.AppendEventsAsync(
                    It.IsAny<string>(),
                    It.IsAny<EventStreamPosition>(),
                    It.IsAny<IReadOnlyCollection<JournaledEvent>>()))
                .Returns(position.YieldTask());

            await writer.AppendEventsAsync(events);

            Assert.Equal(position.Version, writer.StreamVersion);
        }
예제 #9
0
        private async Task<EventStreamPosition> AppendEventsAsync(
            EventStreamPosition position,
            int batchSize = EVENTS_COUNT,
            int batchNumber = BATCH_NUMBER)
        {
            var batches = PrepareBatch(batchSize, batchNumber);

            var currentPosition = position;
            while (batches.Any())
            {
                currentPosition = await Journal.AppendEventsAsync(StreamName, currentPosition, batches.Dequeue());
            }

            return currentPosition;
        }
예제 #10
0
 public async Task MoveToEndOfStreamAsync()
 {
     m_endOfStream = await m_journal.ReadEndOfStreamPositionAsync(m_streamName);
 }
예제 #11
0
        private static void WriteHeadProperty(string stream, EventStreamPosition position, int targetVersion, IBatchOperation batch)
        {
            var headProperties = new Dictionary<string, object>
            {
                {EventJournalTableRowPropertyNames.Version, targetVersion}
            };

            if (EventStreamPosition.IsNewStream(position))
            {
                batch.Insert(stream, "HEAD", headProperties);
            }
            else
            {
                batch.Merge(stream, "HEAD", position.ETag, headProperties);
            }
        }