Beispiel #1
0
        public async Task <StreamReadResults> ReadFrom(string streamId, Func <IAmAStoredEvent, bool> predicate = null, Direction direction = Direction.Backwards, CancellationToken cancellationToken = default)
        {
            var readResult = client.ReadStreamAsync(direction,
                                                    streamId,
                                                    direction == Direction.Backwards ? StreamPosition.End : StreamPosition.Start,
                                                    resolveLinkTos: true,
                                                    configureOperationOptions: options => options.TimeoutAfter = TimeSpan.FromSeconds(30),
                                                    cancellationToken: cancellationToken);

            bool streamExists = false;

            try
            {
                var readState = await readResult.ReadState;
                streamExists = readState == ReadState.Ok;
            }
#pragma warning disable 168
            catch (StreamDeletedException ex)
            // This happens when the stream is hard-deleted. We don't want to throw in that case
#pragma warning restore 168
            {
                streamExists = false;
            }

            if (!streamExists)
            {
                return(new StreamReadResults(emptyReadResult, false, StreamPosition.FromInt64(-1)));
            }

            predicate ??= _ => true;

            var lastIndex = (await client.ReadStreamAsync(Direction.Backwards, streamId,
                                                          revision: StreamPosition.End,
                                                          maxCount: 1,
                                                          resolveLinkTos: false).FirstAsync(cancellationToken)).OriginalEventNumber;

            IAsyncEnumerable <StoredEvent> storedEvents;
            if (direction == Direction.Backwards)
            {
                storedEvents = readResult
                               // Trust me, resharper is wrong in this one. Event can be null
                               // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                               .Where(e => e.Event != null)
                               .Select((e, _) => e.Event.ToStoredEvent(stateFactory))
                               .TakeWhile(e => e.DeserializedEvent is not EntitySoftDeleted)
                               .Where(e => predicate(e));
            }
            else
            {
                storedEvents = readResult
                               // Trust me, resharper is wrong in this one. Event can be null
                               // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                               .Where(e => e.Event != null)
                               .Select((e, c) => e.Event.ToStoredEvent(stateFactory))
                               .Where(e => predicate(e));
            }


            return(new StreamReadResults(storedEvents, true, lastIndex));
        }
Beispiel #2
0
        private static async Task SubscribeToStream(EventStoreClient client)
        {
            #region subscribe-to-stream
            await client.SubscribeToStreamAsync("some-stream",
                                                async (subscription, evnt, cancellationToken) => {
                Console.WriteLine($"Received event {evnt.OriginalEventNumber}@{evnt.OriginalStreamId}");
                await HandleEvent(evnt);
            });

            #endregion subscribe-to-stream

            #region subscribe-to-stream-from-position
            await client.SubscribeToStreamAsync(
                "some-stream",
                StreamPosition.FromInt64(20),
                EventAppeared);

            #endregion subscribe-to-stream-from-position

            #region subscribe-to-stream-live
            await client.SubscribeToStreamAsync(
                "some-stream",
                StreamPosition.End,
                EventAppeared);

            #endregion subscribe-to-stream-live

            #region subscribe-to-stream-resolving-linktos
            await client.SubscribeToStreamAsync(
                "$et-myEventType",
                StreamPosition.Start,
                EventAppeared,
                resolveLinkTos : true);

            #endregion subscribe-to-stream-resolving-linktos

            #region subscribe-to-stream-subscription-dropped
            var checkpoint = StreamPosition.Start;
            await client.SubscribeToStreamAsync(
                "some-stream",
                checkpoint,
                eventAppeared : async(subscription, evnt, cancellationToken) => {
                await HandleEvent(evnt);
                checkpoint = evnt.OriginalEventNumber;
            },
                subscriptionDropped : ((subscription, reason, exception) => {
                Console.WriteLine($"Subscription was dropped due to {reason}. {exception}");
                if (reason != SubscriptionDroppedReason.Disposed)
                {
                    // Resubscribe if the client didn't stop the subscription
                    Resubscribe(checkpoint);
                }
            }));

            #endregion subscribe-to-stream-subscription-dropped
        }
Beispiel #3
0
        /// <summary>
        /// Reads the events.
        /// </summary>
        /// <param name="streamName">Name of the stream.</param>
        /// <param name="fromVersion">From version.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public async Task <List <ResolvedEvent> > ReadEvents(String streamName,
                                                             Int64 fromVersion,
                                                             CancellationToken cancellationToken)
        {
            this.LogInformation($"About to read events from Stream {streamName} fromVersion is {fromVersion}");

            List <ResolvedEvent> resolvedEvents = new List <ResolvedEvent>();

            EventStoreClient.ReadStreamResult response;
            List <ResolvedEvent> events;

            do
            {
                response = this.EventStoreClient.ReadStreamAsync(Direction.Forwards,
                                                                 streamName,
                                                                 StreamPosition.FromInt64(fromVersion),
                                                                 2,
                                                                 resolveLinkTos: true,
                                                                 cancellationToken: cancellationToken);

                // Check the read state
                ReadState readState = await response.ReadState;

                if (readState == ReadState.StreamNotFound)
                {
                    this.LogInformation($"Read State from Stream {streamName} is {readState}");
                    return(null);
                }

                events = await response.ToListAsync(cancellationToken);

                resolvedEvents.AddRange(events);

                fromVersion += events.Count;
            } while (events.Any());

            this.LogInformation($"About to return {resolvedEvents.Count} events from Stream {streamName}");
            return(resolvedEvents);
        }
        /// <summary>
        /// Event Store Initialize (read events and subscribe at the end)
        /// </summary>
        private async Task <bool> Initialize(string stream)
        {
            var _init = _position;

            try
            {
                var ec_stream = _client.ReadStreamAsync(
                    Direction.Forwards, stream,
                    StreamPosition.FromInt64(_position),
                    maxCount: 100
                    );

                if (await ec_stream.ReadState == ReadState.StreamNotFound)
                {
                    await _client.SubscribeToStreamAsync(stream, SubscribeReturn);

                    return(false);
                }

                foreach (var vnt in ec_stream.ToEnumerable().AsParallel())
                {
                    await SubscribeReturn(null, vnt, CancellationToken.None);
                }
                await ec_stream.DisposeAsync();
            }
            catch { }

            if (_init == _position)
            {
                await _client.SubscribeToStreamAsync(stream, StreamPosition.FromInt64(_position), SubscribeReturn);

                return(false);
            }

            return(true);
        }
Beispiel #5
0
        protected override async Task <EventSubscription> Subscribe(
            Checkpoint checkpoint,
            CancellationToken cancellationToken
            )
        {
            var subTask = checkpoint.Position == null
                ? EventStoreClient.SubscribeToStreamAsync(
                _options.StreamName,
                HandleEvent,
                _options.ResolveLinkTos,
                HandleDrop,
                _options.ConfigureOperation,
                _options.Credentials,
                cancellationToken
                )
                : EventStoreClient.SubscribeToStreamAsync(
                _options.StreamName,
                StreamPosition.FromInt64((long)checkpoint.Position),
                HandleEvent,
                _options.ResolveLinkTos,
                HandleDrop,
                _options.ConfigureOperation,
                _options.Credentials,
                cancellationToken
                );

            var sub = await subTask.Ignore();

            return(new EventSubscription(SubscriptionId, new Stoppable(() => sub.Dispose())));

            async Task HandleEvent(EventStore.Client.StreamSubscription _, ResolvedEvent re, CancellationToken ct)
            {
                await Handler(AsReceivedEvent(re), ct).Ignore();
            }

            void HandleDrop(EventStore.Client.StreamSubscription _, SubscriptionDroppedReason reason, Exception?ex)
            => Dropped(EsdbMappings.AsDropReason(reason), ex);

            ReceivedEvent AsReceivedEvent(ResolvedEvent re)
            {
                var evt = DeserializeData(
                    re.Event.ContentType,
                    re.Event.EventType,
                    re.Event.Data,
                    re.Event.EventStreamId,
                    re.Event.EventNumber
                    );

                return(new ReceivedEvent(
                           re.Event.EventId.ToString(),
                           re.Event.EventType,
                           re.Event.ContentType,
                           re.Event.Position.CommitPosition,
                           re.Event.EventNumber,
                           re.Event.EventStreamId,
                           re.Event.EventNumber,
                           re.Event.Created,
                           evt
                           // re.Event.Metadata
                           ));
            }
        }
 public static StreamPosition AsStreamPosition(this StreamReadPosition position)
 => StreamPosition.FromInt64(position.Value);
 public static StreamPosition AsStreamPosition(this StreamTruncatePosition position)
 => StreamPosition.FromInt64(position.Value);
        public override async IAsyncEnumerable <IDomainEventDescriptor> GetAggregateEvents <TKey>(string aggregateType, TKey id, long afterVersion, [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            var streamName = GenerateStreamId(aggregateType, id);

            ReadStreamResult eventStoreDbEvents;

            if (afterVersion == -1)
            {
                eventStoreDbEvents = EventStoreClient.ReadStreamAsync(
                    Direction.Forwards,
                    streamName,
                    StreamPosition.Start,
                    cancellationToken: cancellationToken);
            }
            else
            {
                eventStoreDbEvents = EventStoreClient.ReadStreamAsync(
                    Direction.Forwards,
                    streamName,
                    StreamPosition.FromInt64(afterVersion + 1),
                    cancellationToken: cancellationToken);
            }

            if (await eventStoreDbEvents.ReadState == ReadState.StreamNotFound)
            {
                yield break;
            }

            var eventDescriptors = eventStoreDbEvents.Select(@event =>
            {
                var version      = @event.Event.EventNumber.ToInt64();
                var bsonData     = @event.Event.Data;
                var bsonMetadata = @event.Event.Metadata;
                var eventType    = @event.Event.EventType;

                DomainEventDescriptor descriptor;

                using (var stream = bsonData.AsStream())
                    using (var reader = new BsonDataReader(stream))
                    {
                        JsonSerializer serializer   = new JsonSerializer();
                        serializer.TypeNameHandling = TypeNameHandling.All;
                        var domainEvent             = serializer.Deserialize <IDomainEvent>(reader);
                        descriptor = DomainEventDescriptor.FromStore(aggregateType, id.ToString(), domainEvent, version, eventType);
                    }

                using (var stream = bsonMetadata.AsStream())
                    using (var reader = new BsonDataReader(stream))
                    {
                        JsonSerializer serializer   = new JsonSerializer();
                        serializer.TypeNameHandling = TypeNameHandling.All;
                        var metadata = serializer.Deserialize <IDictionary <string, string> >(reader);

                        foreach (var keyValue in metadata)
                        {
                            descriptor.Metadata.Add(keyValue.Key, keyValue.Value);
                        }
                    }

                return(descriptor);
            });

            await foreach (var eventDescriptor in eventDescriptors)
            {
                yield return(eventDescriptor);
            }
        }
Beispiel #9
0
        public async Task <IEnumerable <DomainEvent> > GetEvents <T>(Guid id, Int32 eventsPerRequest = 100) where T : AggregateRootWithEvents
        {
            String streamName = GetStreamId <T>(id);
            var    encoding   = new UTF8Encoding();

            var firstEvent = _client.ReadStreamAsync(Direction.Forwards, streamName, StreamPosition.Start, 1);
            var state      = await firstEvent.ReadState;

            if (state == ReadState.StreamNotFound)
            {
                return(Array.Empty <DomainEvent>());
            }

            List <DomainEvent> domainEvents = new();
            Int32 streamPosition            = 0;

            while (true)
            {
                var partialEvents = _client.ReadStreamAsync(Direction.Forwards, streamName, StreamPosition.FromInt64(streamPosition), eventsPerRequest);
                var items         = await partialEvents.ToListAsync();

                if (items.Count == 0)
                {
                    break;
                }

                foreach (var item in items)
                {
                    EventMeta meta = System.Text.Json.JsonSerializer.Deserialize <EventMeta>(new ReadOnlySpan <Byte>(item.Event.Metadata.ToArray()));

                    String content = encoding.GetString(item.Event.Data.ToArray());

                    var domainEvent = (DomainEvent)JsonConvert.DeserializeObject(content, Type.GetType(meta.BodyType), _jsonSerializerSettings);
                    domainEvents.Add(domainEvent);
                }

                streamPosition += eventsPerRequest;
            }

            return(domainEvents);
        }