Ejemplo n.º 1
0
        public async Task It_returns_same_value_to_concurrent_requests()
        {
            var seed     = 0;
            var barrier  = new Barrier(3);
            var producer = new PipelineStep <int>(() => Task.FromResult(++seed));

            var firstConsumer = Task.Run(() =>
            {
                barrier.SignalAndWait();
                return(producer.GetLatestAsync());
            });

            var secondConsumer = Task.Run(() =>
            {
                barrier.SignalAndWait();
                return(producer.GetLatestAsync());
            });

            var thirdConsumer = Task.Run(() =>
            {
                barrier.SignalAndWait();
                return(producer.GetLatestAsync());
            });

            var values = await Task.WhenAll(firstConsumer, secondConsumer, thirdConsumer);

            values.Should().HaveCount(3).And.OnlyContain(i => i == 1);
        }
Ejemplo n.º 2
0
        public async Task When_invalidated_while_producing_a_value_the_consumer_waiting_will_wait_for_latest_production_to_be_finished()
        {
            var seed    = 0;
            var barrier = new Barrier(2);

            PipelineStep <int> producer = null;

            producer = new PipelineStep <int>(() =>
            {
                // will require all consumer to reach this point to move on
                barrier.SignalAndWait(3.Seconds());
                barrier.RemoveParticipant();

                producer.Invalidate();

                return(Task.FromResult(Interlocked.Increment(ref seed)));
            });



            var values = await Task.WhenAll(
                producer.GetLatestAsync(),
                producer.GetLatestAsync());



            values.Should().BeEquivalentTo(2, 2);

            // var values = await Task.WhenAll(firstConsumer, secondConsumer);
            // values.Should().HaveCount(2).And.OnlyContain(i => i == 2);
        }
Ejemplo n.º 3
0
        public async Task It_produces_a_new_value_when_invalidated()
        {
            var seed     = 0;
            var producer = new PipelineStep <int>(() => Task.FromResult(Interlocked.Increment(ref seed)));
            var value    = await producer.GetLatestAsync();

            value.Should().Be(1);

            producer.Invalidate();
            var newValue = await producer.GetLatestAsync();

            newValue.Should().Be(2);
        }
Ejemplo n.º 4
0
        public async Task It_retains_the_latest_value()
        {
            var seed     = 0;
            var producer = new PipelineStep <int>(() => Task.FromResult(Interlocked.Increment(ref seed)));
            var value1   = await producer.GetLatestAsync();

            var value2 = await producer.GetLatestAsync();

            var value3 = await producer.GetLatestAsync();

            value1.Should().Be(1);
            value2.Should().Be(1);
            value3.Should().Be(1);
        }
Ejemplo n.º 5
0
        public async Task It_produces_a_new_value_when_there_is_none()
        {
            var producer = new PipelineStep <string>(() => Task.FromResult("something"));
            var value    = await producer.GetLatestAsync();

            value.Should().Be("something");
        }
Ejemplo n.º 6
0
        public async Task When_invalidated_while_producing_a_value_the_consumer_waiting_will_wait_for_latest_production_to_be_finished()
        {
            var seed            = 0;
            var consumerBarrier = new Barrier(2);
            var producerBarrier = new Barrier(2);

            var producer = new PipelineStep <int>(() =>
            {
                // will require all consumer to reach this point to move on
                producerBarrier.SignalAndWait(2.Seconds());
                return(Task.FromResult(Interlocked.Increment(ref seed)));
            });

            var firstConsumer = Task.Run(() =>
            {
                var task = producer.GetLatestAsync();
                // block waiting for the other consumer
                consumerBarrier.SignalAndWait(2.Seconds());
                return(task);
            }
                                         );

            var secondConsumer = Task.Run(() =>
            {
                // now both consumer reached the barrier
                consumerBarrier.SignalAndWait(2.Seconds());
                producer.Invalidate();
                // let the firs request fire
                producerBarrier.RemoveParticipant();
                // second request after invalidation
                var task = producer.GetLatestAsync();
                return(task);
            }
                                          );

            var values = await Task.WhenAll(firstConsumer, secondConsumer);

            values.Should().HaveCount(2).And.OnlyContain(i => i == 2);
        }
Ejemplo n.º 7
0
        public async Task It_returns_same_value_to_concurrent_requests()
        {
            var seed     = 0;
            var barrier  = new Barrier(3);
            var producer = new PipelineStep <int>(() =>
            {
                barrier.SignalAndWait(2.Seconds());
                return(Task.FromResult(++seed));
            });

            var values = await Task.WhenAll(Enumerable.Range(0, 3)
                                            .AsParallel()
                                            .Select((_) => producer.GetLatestAsync()));

            values.Should().HaveCount(3).And.OnlyContain(i => i == 1);
        }
Ejemplo n.º 8
0
        public async Task It_remains_invalid_if_exceptions_are_thrown()
        {
            var seed     = 0;
            var producer = new PipelineStep <int>(() =>
            {
                var next = Interlocked.Increment(ref seed);
                if (next == 1)
                {
                    throw new InvalidOperationException();
                }
                return(Task.FromResult(next));
            });

            producer.Awaiting(p => p.GetLatestAsync())
            .Should()
            .Throw <InvalidOperationException>();

            var value = await producer.GetLatestAsync();

            value.Should().Be(2);
        }