Beispiel #1
0
        public async Task subscribe_to_empty_database()
        {
            var appeared = new TaskCompletionSource <bool>();
            var dropped  = new TaskCompletionSource <(SubscriptionDroppedReason, Exception)>();

            var firstEvent = await _fixture.Client.ReadAllAsync(Direction.Forwards, Position.Start, 1)
                             .FirstOrDefaultAsync();

            using var subscription = await _fixture.Client
                                     .SubscribeToAllAsync(firstEvent.OriginalEvent.Position, 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 (e.OriginalEvent.Position == firstEvent.OriginalEvent.Position)
                {
                    appeared.TrySetException(new Exception());
                    return(Task.CompletedTask);
                }

                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));
        }