Beispiel #1
0
        public async Task Publish_MessageStreamProviderOfEnvelopes_StreamedEnvelopesReceived()
        {
            var receivedStreams       = 0;
            var receivedEnvelopes     = 0;
            var receivedTestEnvelopes = 0;

            var serviceProvider = ServiceProviderHelper.GetServiceProvider(
                services => services
                .AddFakeLogger()
                .AddSilverback()
                .AsObservable()
                .AddDelegateSubscriber(
                    (IMessageStreamObservable <IEnvelope> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => Interlocked.Increment(ref receivedEnvelopes));
            })
                .AddDelegateSubscriber(
                    (IMessageStreamObservable <TestEnvelope> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => Interlocked.Increment(ref receivedTestEnvelopes));
            }));
            var streamPublisher = serviceProvider.GetRequiredService <IStreamPublisher>();

            var streamProvider = new MessageStreamProvider <IEnvelope>();

            await streamPublisher.PublishAsync(streamProvider);

            await streamProvider.PushAsync(new TestEnvelope(new TestEventOne()));

            await streamProvider.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedEnvelopes >= 2 && receivedTestEnvelopes >= 2);

            receivedStreams.Should().Be(2);
            receivedEnvelopes.Should().Be(2);
            receivedTestEnvelopes.Should().Be(2);
        }
Beispiel #2
0
        public async Task Publish_MessageStreamProviderOfEnvelopes_StreamedUnwrappedMessagesReceived()
        {
            var receivedStreams       = 0;
            var receivedTestEventOnes = 0;
            var receivedTestEnvelopes = 0;

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamObservable <TestEventOne> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => Interlocked.Increment(ref receivedTestEventOnes));
            })
                    .AddDelegateSubscriber(
                        (IMessageStreamObservable <TestEnvelope> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => Interlocked.Increment(ref receivedTestEnvelopes));
            })));

            var stream = new MessageStreamProvider <IEnvelope>();
            await streamPublisher.PublishAsync(stream);

            await stream.PushAsync(new TestEnvelope(new TestEventOne()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await stream.PushAsync(new TestEnvelope(new TestEventOne()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedTestEventOnes >= 2 && receivedTestEnvelopes >= 4);

            receivedStreams.Should().Be(2);
            receivedTestEventOnes.Should().Be(2);
            receivedTestEnvelopes.Should().Be(4);
        }
        public async Task CompleteAsync_WhileAsyncEnumeratingStreams_EnumerationCompleted()
        {
            int?count    = null;
            var provider = new MessageStreamProvider <int>();
            var stream   = provider.CreateStream <int>();

            var enumerationTask = Task.Run(async() => { count = await stream.CountAsync(); });

            await provider.PushAsync(1);

            await provider.PushAsync(2);

            await provider.PushAsync(3);

            count.Should().BeNull();

            await provider.CompleteAsync();

            await enumerationTask;

            count.Should().Be(3);
        }
        public async Task Publish_MessageStreamProviderOfEnvelopes_OnlyMatchingUnwrappedMessagesReceived()
        {
            var receivedStreamsOfOnes = 0;
            var receivedTestEventOnes = 0;
            var receivedStreamsOfTwos = 0;
            var receivedTestEventTwos = 0;

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <TestEventOne> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreamsOfOnes);
                foreach (var dummy in enumerable)
                {
                    Interlocked.Increment(ref receivedTestEventOnes);
                }
            })
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <TestEventTwo> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreamsOfTwos);
                foreach (var dummy in enumerable)
                {
                    Interlocked.Increment(ref receivedTestEventTwos);
                }
            })));

            var stream = new MessageStreamProvider <IEnvelope>();
            await streamPublisher.PublishAsync(stream);

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedTestEventTwos >= 2);

            receivedStreamsOfOnes.Should().Be(0);
            receivedTestEventOnes.Should().Be(0);
            receivedStreamsOfTwos.Should().Be(1);
            receivedTestEventTwos.Should().Be(2);

            await stream.PushAsync(new TestEnvelope(new TestEventOne()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await stream.PushAsync(new TestEnvelope(new TestEventOne()));

            await stream.PushAsync(new TestEnvelope(new TestEventTwo()));

            await AsyncTestingUtil.WaitAsync(() => receivedTestEventTwos >= 4);

            receivedStreamsOfOnes.Should().Be(1);
            receivedTestEventOnes.Should().Be(2);
            receivedStreamsOfTwos.Should().Be(1);
            receivedTestEventTwos.Should().Be(4);
        }
        public async Task PublishAsync_MessageStreamProvider_ProcessExceptionRethrown()
        {
            var received = 0;

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <IEvent> enumerable) =>
            {
                foreach (var dummy in enumerable)
                {
                    if (Interlocked.Increment(ref received) >= 3)
                    {
                        throw new TestException();
                    }
                }
            })
                    .AddDelegateSubscriber(
                        async(IMessageStreamEnumerable <TestEventOne> enumerable) =>
            {
                await foreach (var dummy in enumerable)
                {
                }
            })));

            var streamProvider = new MessageStreamProvider <IEvent>();

            var tasks = await streamPublisher.PublishAsync(streamProvider);

            streamProvider.PushAsync(new TestEventOne()).RunWithoutBlocking();
            streamProvider.PushAsync(new TestEventOne()).RunWithoutBlocking();
            streamProvider.PushAsync(new TestEventOne()).RunWithoutBlocking();

            Func <Task> act = async() => await await Task.WhenAny(tasks);

            act.Should().Throw <TargetInvocationException>();
        }
Beispiel #6
0
        public async Task Abort_WhileAsyncEnumeratingStreams_EnumerationAborted()
        {
            int?count    = null;
            var provider = new MessageStreamProvider <int>();
            var stream   = provider.CreateStream <int>();

            var enumerationTask = Task.Run(async() => { count = await stream.CountAsync(); });

            await provider.PushAsync(1);

            await provider.PushAsync(2);

            await provider.PushAsync(3);

            count.Should().BeNull();

            provider.Abort();

            await AsyncTestingUtil.WaitAsync(() => enumerationTask.IsCompleted);

            count.Should().BeNull();
            enumerationTask.Status.Should().Be(TaskStatus.Canceled);
        }
Beispiel #7
0
        public async Task CreateLazyStream_PushingMessages_StreamCreatedWhenMatchingMessagePushed()
        {
            var provider   = new MessageStreamProvider <IEvent>();
            var lazyStream = provider.CreateLazyStream <TestEventTwo>();
            List <TestEventTwo> receivedTwos = new();

            Task.Run(
                async() =>
            {
                await lazyStream.WaitUntilCreatedAsync();
                foreach (var message in lazyStream.Stream !)
                {
                    receivedTwos.Add(message);
                }
            }).FireAndForget();

            var createStreamTask = lazyStream.WaitUntilCreatedAsync();

            await provider.PushAsync(new TestEventOne(), false);

            await provider.PushAsync(new TestEventOne(), false);

            createStreamTask.Status.Should().NotBe(TaskStatus.RanToCompletion);
            lazyStream.Stream.Should().BeNull();

            await provider.PushAsync(new TestEventTwo());

            createStreamTask.Status.Should().Be(TaskStatus.RanToCompletion);
            lazyStream.Stream.Should().BeOfType <MessageStreamEnumerable <TestEventTwo> >();

            await provider.PushAsync(new TestEventTwo());

            receivedTwos.Should().HaveCount(2);

            await provider.CompleteAsync();
        }
Beispiel #8
0
        public async Task PushAsync_Messages_ReturnedAfterMessagesProcessed()
        {
            var provider = new MessageStreamProvider <IMessage>();
            var stream   = provider.CreateStream <IEvent>();

            var processed = false;

            Task.Run(
                async() =>
            {
                await Task.Delay(50);
                stream.GetEnumerator().MoveNext();
                await Task.Delay(50);
                processed = true;
                stream.GetEnumerator().MoveNext();
            }).FireAndForget();

            await provider.PushAsync(new TestEventOne());

            processed.Should().BeTrue();
        }
Beispiel #9
0
        /// <summary>
        ///     Adds the message to the sequence.
        /// </summary>
        /// <param name="envelope">
        ///     The envelope to be added to the sequence.
        /// </param>
        /// <param name="sequence">
        ///     The sequence to be added to the sequence.
        /// </param>
        /// <param name="throwIfUnhandled">
        ///     A boolean value indicating whether an exception must be thrown if no subscriber is handling the
        ///     message.
        /// </param>
        /// <returns>
        ///     A <see cref="Task{TResult}" /> representing the asynchronous operation. The task result contains the
        ///     number of streams that have been pushed.
        /// </returns>
        protected virtual async Task <int> AddCoreAsync(TEnvelope envelope, ISequence?sequence, bool throwIfUnhandled)
        {
            if (!IsPending || IsCompleting)
            {
                if (IsAborted)
                {
                    return(0);
                }

                throw new InvalidOperationException("Cannot add new messages to the complete or aborted sequence.");
            }

            ResetTimeout();

            if (sequence != null && sequence != this)
            {
                _sequences ??= new List <ISequence>();
                _sequences.Add(sequence);
                (sequence as ISequenceImplementation)?.SetParentSequence(this);
            }
            else
            {
                _offsets.Add(envelope.Offset);
            }

            await _addingSemaphoreSlim.WaitAsync().ConfigureAwait(false);

            try
            {
                _abortCancellationTokenSource.Token.ThrowIfCancellationRequested();

                Length++;

                if (TotalLength != null && Length == TotalLength || IsLastMessage(envelope))
                {
                    TotalLength  = Length;
                    IsCompleting = true;

                    _logger.LogTrace(
                        IntegrationEventIds.LowLevelTracing,
                        "{sequenceType} '{sequenceId}' is completing (total length {sequenceLength})...",
                        GetType().Name,
                        SequenceId,
                        TotalLength);
                }

                int pushedStreamsCount = await _streamProvider.PushAsync(
                    envelope,
                    throwIfUnhandled,
                    _abortCancellationTokenSource.Token)
                                         .ConfigureAwait(false);

                if (IsCompleting)
                {
                    await CompleteAsync().ConfigureAwait(false);
                }

                return(pushedStreamsCount);
            }
            catch (OperationCanceledException)
            {
                // Ignore
                return(0);
            }
            catch (Exception ex)
            {
                _logger.LogTrace(
                    IntegrationEventIds.LowLevelTracing,
                    ex,
                    "Error occurred adding message to {sequenceType} '{sequenceId}'.",
                    GetType().Name,
                    SequenceId);

                throw;
            }
            finally
            {
                _addingSemaphoreSlim.Release();
            }
        }