public async Task TestMultiThreadedStagedMockStream() { var readStream = new MemoryStream(); var messageStream = new ConcurrentMessageStream <IStagedBodyMessage>( new StagedBodyMessageDeserializer( new MessageProvider <int, IStagedBodyMessage>(), new TestMessageDeserializer() ), new StagedBodyMessageSerializer( new TestMessageSerializer() ), new StreamDuplexMessageStream(readStream).MakeWriteOnly(), // we use writeonly because we dont want to hit EOF (exception) => new ValueTask() ); await messageStream.OpenAsync().ConfigureAwait(false); int messageCount = 5; int actualMessageCount = 0; for (int i = 0; i < messageCount; i++) { await messageStream.EnqueueMessageOnReaderAsync(new TestMessage { Header = new StagedBodyMessageHeader(), Value = (short)i }, i == messageCount - 1); } await Task.WhenAll(Enumerable.Range(0, 5).Select(async _ => { var result = await messageStream.ReadAsync().ConfigureAwait(false); if (result.ReadResult) { var count = Interlocked.Increment(ref actualMessageCount); } })).ConfigureAwait(false); Assert.Equal(messageCount, actualMessageCount); // Close await messageStream.CloseAsync().ConfigureAwait(false); }
public async Task TestMultiThreadedStagedStream() { var readStream = new MemoryStream(); var writeStream = new MemoryStream(); var messageStream = new ConcurrentMessageStream <IStagedBodyMessage>( new MessageStreamReader(readStream), new StagedBodyMessageDeserializer( new MessageProvider <int, IStagedBodyMessage>(), new TestMessageDeserializer() ), new MessageStreamWriter(writeStream), new StagedBodyMessageSerializer( new TestMessageSerializer() ), readerFlushTimeout: TimeSpan.FromSeconds(1) ); await messageStream.OpenAsync().ConfigureAwait(false); const int messageCount = 100000; const int parallellism = 10; const int blockSize = messageCount / parallellism; var random = new Random(); await Task.WhenAll(Enumerable.Range(0, parallellism).Select(async _ => { for (int i = 0; i < blockSize; i++) { await messageStream.WriteAsync(new TestMessage { Value = (short)random.Next(10000) }).ConfigureAwait(false); } })).ConfigureAwait(false); await messageStream.CloseAsync().ConfigureAwait(false); // Reset the streams position so we can read in the messages writeStream.Position = 0; writeStream.CopyTo(readStream); readStream.Position = 0; await messageStream.OpenAsync().ConfigureAwait(false); int actualMessageCount = 0; await Task.WhenAll(Enumerable.Range(0, parallellism).Select(async _ => { while (true) { var result = await messageStream.ReadAsync().ConfigureAwait(false); if (result.Result != null) { Interlocked.Increment(ref actualMessageCount); } if (result.IsCompleted) { break; } } })).ConfigureAwait(false); Assert.Equal(messageCount, actualMessageCount); // Close await messageStream.CloseAsync().ConfigureAwait(false); }
public static async Task Main0(string[] args) { const int messageCount = 1_000_000; const int iterations = 10; const int parallellism = 1; int messageCounter = 0; var stopwatch = new Stopwatch(); var messageProvider = new MessageProvider <int, IStagedBodyMessage>(); var readStream = await GetReadStreamAsync(messageCount).ConfigureAwait(false); var writeStream = new MemoryStream((int)readStream.Length); var messageStream = new ConcurrentMessageStream <IStagedBodyMessage>( new StagedBodyMessageDeserializer( messageProvider, new TestMessageDeserializer(), new TestMessage2Deserializer() ), new StagedBodyMessageSerializer( new TestMessageSerializer(), new TestMessage2Serializer() ), new StreamDuplexMessageStream(readStream, writeStream), exception => new ValueTask() ); Console.WriteLine(); for (int i = 0; i < iterations; i++) { readStream.Position = 0; writeStream.Position = 0; messageCounter = 0; await messageStream.OpenAsync().ConfigureAwait(false); stopwatch.Restart(); await Task.WhenAll(Enumerable.Range(0, parallellism).Select(async _ => { while (true) { var result = await messageStream.ReadAsync().ConfigureAwait(false); if (result.ReadResult) { Interlocked.Increment(ref messageCounter); } if (result.IsCompleted) { break; } } })).ConfigureAwait(false); stopwatch.Stop(); Console.WriteLine($"Done iteration: {messageCounter / stopwatch.Elapsed.TotalSeconds} messages/s. {messageCounter} total messages read."); if (messageStream.Open) { await messageStream.CloseAsync().ConfigureAwait(false); } } readStream.Dispose(); writeStream.Dispose(); Console.ReadLine(); }
public async Task TestMultiThreadedStagedStream() { var readStream = new MemoryStream(); var writeStream = new MemoryStream(); var messageStream = new ConcurrentMessageStream <IStagedBodyMessage>( new StagedBodyMessageDeserializer( new MessageProvider <int, IStagedBodyMessage>(), new TestMessageDeserializer() ), new StagedBodyMessageSerializer( new TestMessageSerializer() ), new StreamDuplexMessageStream(writeStream).MakeWriteOnly(), (exception) => new ValueTask() ); await messageStream.OpenAsync().ConfigureAwait(false); const int messageCount = 100000; const int parallellism = 10; const int blockSize = messageCount / parallellism; var random = new Random(); await Task.WhenAll(Enumerable.Range(0, parallellism).Select(async _ => { for (int i = 0; i < blockSize; i++) { await messageStream.WriteAndWaitAsync(new TestMessage { Value = (short)random.Next(10000) }).ConfigureAwait(false); } })).ConfigureAwait(false); await messageStream.CloseAsync().ConfigureAwait(false); // Reset the streams position so we can read in the messages readStream = new MemoryStream(writeStream.ToArray()); readStream.Position = 0; writeStream = new MemoryStream(); messageStream = new ConcurrentMessageStream <IStagedBodyMessage>( new StagedBodyMessageDeserializer( new MessageProvider <int, IStagedBodyMessage>(), new TestMessageDeserializer() ), new StagedBodyMessageSerializer( new TestMessageSerializer() ), new StreamDuplexMessageStream(readStream).MakeReadOnly(), (exception) => new ValueTask() ); await messageStream.OpenAsync().ConfigureAwait(false); int actualMessageCount = 0; await Task.WhenAll(Enumerable.Range(0, parallellism).Select(async _ => { while (true) { var result = await messageStream.ReadAsync().ConfigureAwait(false); if (result.ReadResult) { Interlocked.Increment(ref actualMessageCount); } if (result.IsCompleted) { break; } } })).ConfigureAwait(false); Assert.Equal(messageCount, actualMessageCount); // Close try { await messageStream.CloseAsync().ConfigureAwait(false); } catch (Exception ex) { // the stream was closed because EOF } }
public async Task TestStagedStreamAsync() { var readStream = new MemoryStream(); var writeStream = new MemoryStream(); var messageStream = new MessageStream <IStagedBodyMessage>( new StagedBodyMessageDeserializer( new MessageProvider <int, IStagedBodyMessage>(), new TestMessageDeserializer() ), new StagedBodyMessageSerializer( new TestMessageSerializer() ), new StreamDuplexMessageStream(readStream, writeStream) ); await messageStream.OpenAsync().ConfigureAwait(false); // Write two messages await messageStream.WriteAsync(new TestMessage { Value = 2 }).ConfigureAwait(false); await messageStream.WriteAsync(new TestMessage { Value = 4 }).ConfigureAwait(false); await messageStream.CloseAsync().ConfigureAwait(false); // Reset the streams position so we can read in the messages readStream = new MemoryStream(writeStream.ToArray()); readStream.Position = 0; writeStream = new MemoryStream(); messageStream = new ConcurrentMessageStream <IStagedBodyMessage>( new StagedBodyMessageDeserializer( new MessageProvider <int, IStagedBodyMessage>(), new TestMessageDeserializer() ), new StagedBodyMessageSerializer( new TestMessageSerializer() ), new StreamDuplexMessageStream(readStream, writeStream), (exception) => new ValueTask() ); await messageStream.OpenAsync().ConfigureAwait(false); // Read the two messages var result = await messageStream.ReadAsync().ConfigureAwait(false); Assert.False(result.IsCompleted); Assert.IsType <TestMessage>(result.Result); Assert.Equal(2, (result.Result as TestMessage).Value); var result2 = await messageStream.ReadAsync().ConfigureAwait(false); Assert.False(result2.IsCompleted); Assert.IsType <TestMessage>(result.Result); Assert.Equal(4, (result2.Result as TestMessage).Value); // This read should signal it's completed. var result3 = await messageStream.ReadAsync().ConfigureAwait(false); Assert.True(result3.IsCompleted); // Close await messageStream.CloseAsync().ConfigureAwait(false); }