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