private async Task <StreamMetadataResult> GetStreamMetadataAsync(string streamName,
                                                                         EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials = null,
                                                                         CancellationToken cancellationToken = default)
        {
            ResolvedEvent metadata;

            _log.LogDebug("Read stream metadata for {streamName}.");

            try {
                metadata = await ReadStreamAsync(Direction.Backwards, SystemStreams.MetastreamOf(streamName),
                                                 StreamPosition.End, 1, operationOptions, false, userCredentials, cancellationToken)
                           .FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
            } catch (StreamNotFoundException) {
                _log.LogWarning("Stream metadata for {streamName} not found.");
                return(StreamMetadataResult.None(streamName));
            }

            return(metadata.Event == null
                                ? StreamMetadataResult.None(streamName)
                                : StreamMetadataResult.Create(streamName, metadata.OriginalEventNumber,
                                                              JsonSerializer.Deserialize <StreamMetadata>(metadata.Event.Data.Span,
                                                                                                          StreamMetadataJsonSerializerOptions)));
        }
        private async Task <StreamMetadataResult> GetStreamMetadataAsync(string streamName,
                                                                         EventStoreClientOperationOptions operationOptions, UserCredentials userCredentials = default,
                                                                         CancellationToken cancellationToken = default)
        {
            ResolvedEvent metadata = default;

            try {
                metadata = await ReadStreamAsync(Direction.Backwards, SystemStreams.MetastreamOf(streamName), StreamRevision.End, 1,
                                                 operationOptions,
                                                 resolveLinkTos : false,
                                                 userCredentials : userCredentials,
                                                 cancellationToken : cancellationToken).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
            } catch (StreamNotFoundException) {
                return(StreamMetadataResult.None(streamName));
            }

            return(metadata.Event == null
                                ? StreamMetadataResult.None(streamName)
                                : StreamMetadataResult.Create(
                       streamName,
                       metadata.OriginalEventNumber,
                       JsonSerializer.Deserialize <StreamMetadata>(metadata.Event.Data, StreamMetadataJsonSerializerOptions)));
        }
Exemplo n.º 3
0
        public async Task subscribe_to_empty_database()
        {
            var appeared = new TaskCompletionSource <bool>();
            var dropped  = new TaskCompletionSource <(SubscriptionDroppedReason, Exception)>();

            using var subscription = await _fixture.Client
                                     .SubscribeToAllAsync(Position.End, EventAppeared, false, SubscriptionDropped)
                                     .WithTimeout();

            Assert.False(appeared.Task.IsCompleted);

            if (dropped.Task.IsCompleted)
            {
                Assert.False(dropped.Task.IsCompleted, dropped.Task.Result.ToString());
            }

            subscription.Dispose();

            var(reason, ex) = await dropped.Task.WithTimeout();

            Assert.Equal(SubscriptionDroppedReason.Disposed, reason);
            Assert.Null(ex);

            Task EventAppeared(StreamSubscription s, ResolvedEvent e, CancellationToken ct)
            {
                if (!SystemStreams.IsSystemStream(e.OriginalStreamId))
                {
                    appeared.TrySetResult(true);
                }

                return(Task.CompletedTask);
            }

            void SubscriptionDropped(StreamSubscription s, SubscriptionDroppedReason reason, Exception ex) =>
            dropped.SetResult((reason, ex));
        }
        public async Task reads_all_existing_events_after_position_and_keep_listening_to_new_ones()
        {
            var events = _fixture.CreateTestEvents(20).ToArray();

            var appeared = new TaskCompletionSource <bool>();
            var dropped  = new TaskCompletionSource <(SubscriptionDroppedReason, Exception)>();

            var beforeEvents = events.Take(10);
            var afterEvents  = events.Skip(10);

            using var enumerator = events.AsEnumerable().GetEnumerator();

            enumerator.MoveNext();

            var position = await _fixture.Client.ReadAllAsync(Direction.Forwards, Position.Start, 1)
                           .Select(x => x.OriginalEvent.Position)
                           .FirstAsync();

            foreach (var @event in beforeEvents)
            {
                await _fixture.Client.AppendToStreamAsync($"stream-{@event.EventId:n}", StreamState.NoStream,
                                                          new[] { @event });
            }

            using var subscription =
                      await _fixture.Client.SubscribeToAllAsync(position, EventAppeared, false, SubscriptionDropped);

            foreach (var @event in afterEvents)
            {
                await _fixture.Client.AppendToStreamAsync($"stream-{@event.EventId:n}", StreamState.NoStream,
                                                          new[] { @event });
            }

            await appeared.Task.WithTimeout();

            Assert.False(dropped.Task.IsCompleted);

            subscription.Dispose();

            var(reason, ex) = await dropped.Task.WithTimeout();

            Assert.Equal(SubscriptionDroppedReason.Disposed, reason);
            Assert.Null(ex);

            Task EventAppeared(StreamSubscription s, ResolvedEvent e, CancellationToken ct)
            {
                if (position >= e.OriginalEvent.Position)
                {
                    appeared.TrySetException(new Exception());
                }

                if (!SystemStreams.IsSystemStream(e.OriginalStreamId))
                {
                    try {
                        Assert.Equal(enumerator.Current.EventId, e.OriginalEvent.EventId);
                        if (!enumerator.MoveNext())
                        {
                            appeared.TrySetResult(true);
                        }
                    } catch (Exception ex) {
                        appeared.TrySetException(ex);
                        throw;
                    }
                }

                return(Task.CompletedTask);
            }

            void SubscriptionDropped(StreamSubscription s, SubscriptionDroppedReason reason, Exception ex) =>
            dropped.SetResult((reason, ex));
        }