public static async Task CopyToAsync(this IReadableChannel input, IWritableChannel output) { while (true) { var result = await input.ReadAsync(); var inputBuffer = result.Buffer; var fin = result.IsCompleted; try { if (inputBuffer.IsEmpty && fin) { return; } var buffer = output.Alloc(); buffer.Append(inputBuffer); await buffer.FlushAsync(); } finally { input.Advance(inputBuffer.End); } } }
private async void Consume(IReadableChannel channel) { while (true) { var result = await channel.ReadAsync(); var buffer = result.Buffer; try { if (buffer.IsEmpty && result.IsCompleted) { break; } await WriteAsync(buffer); } finally { channel.Advance(buffer.End); } } channel.Complete(); }
/// <summary> /// Constructs a new <see cref="WebSocketConnection"/> from an <see cref="IReadableChannel"/> and an <see cref="IWritableChannel"/> that represents an established WebSocket connection (i.e. after handshaking) /// </summary> /// <param name="inbound">A <see cref="IReadableChannel"/> from which frames will be read when receiving.</param> /// <param name="outbound">A <see cref="IWritableChannel"/> to which frame will be written when sending.</param> /// <param name="subProtocol">The sub-protocol provided during handshaking</param> /// <param name="options">A <see cref="WebSocketOptions"/> which provides the configuration options for the socket.</param> public WebSocketConnection(IReadableChannel inbound, IWritableChannel outbound, string subProtocol, WebSocketOptions options) { _inbound = inbound; _outbound = outbound; _options = options; SubProtocol = subProtocol; if (_options.FixedMaskingKey != null) { // Use the fixed key directly as the buffer. _maskingKeyBuffer = _options.FixedMaskingKey; // Clear the MaskingKeyGenerator just to ensure that nobody set it. _options.MaskingKeyGenerator = null; } else if (_options.MaskingKeyGenerator != null) { // Establish a buffer for the random generator to use _maskingKeyBuffer = new byte[4]; } if (_options.PingInterval > TimeSpan.Zero) { var pingIntervalMillis = (int)_options.PingInterval.TotalMilliseconds; // Set up the pinger _pinger = new Timer(Pinger, this, pingIntervalMillis, pingIntervalMillis); } }
private static async Task CopyCompletedAsync(IReadableChannel input, IWritableChannel channel) { var inputBuffer = await input.ReadAsync(); while (true) { try { if (inputBuffer.IsEmpty && input.Completion.IsCompleted) { return; } var buffer = channel.Alloc(); buffer.Append(ref inputBuffer); await buffer.FlushAsync(); } finally { inputBuffer.Consumed(); } var awaiter = input.ReadAsync(); if (!awaiter.IsCompleted) { // No more data break; } inputBuffer = await awaiter; } }
private static async Task <int> ReadAsyncAwaited(this IReadableChannel input, Span <byte> destination) { while (true) { var result = await input.ReadAsync(); var inputBuffer = result.Buffer; var fin = result.IsCompleted; var sliced = inputBuffer.Slice(0, destination.Length); sliced.CopyTo(destination); int actual = sliced.Length; input.Advance(sliced.End); if (actual != 0) { return(actual); } else if (fin) { return(0); } } }
public async Task DuplexStreaming(IReadableChannel <GreetingRequest> requestStream, IWritableChannel <GreetingResponse> responseStream, MethodCallContext context) { Console.WriteLine("Received duplex streaming request from {{{0}}}", context); var greeting = "Hello!"; await responseStream.WriteAsync(new GreetingResponse { Greeting = greeting }).ConfigureAwait(false); Console.WriteLine("Sent: {0}", greeting); while (await requestStream.WaitReadAvailableAsync().ConfigureAwait(false)) { while (requestStream.TryRead(out var request)) { Console.WriteLine("Received: {0}", request.Name); greeting = $"Hello, {request.Name}!"; await responseStream .WriteAsync(new GreetingResponse { Greeting = greeting }) .ConfigureAwait(false); Console.WriteLine("Sent: {0}", greeting); } } Console.WriteLine("Request stream completed"); greeting = "Good Bye!"; await responseStream .WriteAsync(new GreetingResponse { Greeting = greeting }) .ConfigureAwait(false); Console.WriteLine("Sent: {0}", greeting); greeting = "See you again!"; await responseStream .WriteAsync(new GreetingResponse { Greeting = greeting }) .ConfigureAwait(false); Console.WriteLine("Sent: {0}", greeting); Console.WriteLine("Completed"); }
public HttpConnection(IHttpApplication <TContext> application, IReadableChannel input, IWritableChannel output) { _application = application; _input = input; _output = output; _initialBody = new HttpBodyStream <TContext>(this); }
private static async Task Pipes_ReadWriteValues <T>(bool firstWaitToRead, int numItems, Func <int, T> getValue) { using (AnonymousPipeServerStream serverPipe = new AnonymousPipeServerStream(PipeDirection.Out)) using (AnonymousPipeClientStream clientPipe = new AnonymousPipeClientStream(PipeDirection.In, serverPipe.ClientSafePipeHandle)) { IWritableChannel <T> writer = Channel.WriteToStream <T>(serverPipe); IReadableChannel <T> reader = Channel.ReadFromStream <T>(clientPipe); for (int i = 0; i < numItems; i++) { T itemToWrite = getValue(i); Task <T> readItem = firstWaitToRead ? reader.WaitToReadAsync().ContinueWith(_ => reader.ReadAsync().AsTask()).Unwrap() : reader.ReadAsync().AsTask(); Task writeItem = writer.WriteAsync(itemToWrite); await Task.WhenAll(readItem, writeItem); Assert.Equal(itemToWrite, readItem.Result); } writer.Complete(); Assert.False(await reader.WaitToReadAsync()); await reader.Completion; } }
public static async Task CopyToAsync(this IReadableChannel input, Stream stream, int bufferSize, CancellationToken cancellationToken) { // TODO: Use bufferSize argument while (!cancellationToken.IsCancellationRequested) { var inputBuffer = await input.ReadAsync(); try { if (inputBuffer.IsEmpty && input.Reading.IsCompleted) { return; } foreach (var memory in inputBuffer) { ArraySegment <byte> buffer; if (!memory.TryGetArray(out buffer)) { // Fall back to copies if this was native memory and we were unable to get // something we could write buffer = new ArraySegment <byte>(memory.Span.CreateArray()); } await stream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count); } } finally { input.Advance(inputBuffer.End); } } }
public static async Task CopyToAsync(this IReadableChannel input, Stream stream) { while (true) { await input; var fin = input.Completion.IsCompleted; var span = input.BeginRead(); if (span.Begin.IsEnd && fin) { return; } try { await span.Begin.CopyToAsync(stream, span.End.Block); } finally { input.EndRead(span.End); } } }
private static async Task CopyCompletedAsync(IReadableChannel input, IWritableChannel channel) { await input; do { var fin = input.Completion.IsCompleted; var inputBuffer = input.BeginRead(); try { if (inputBuffer.IsEmpty && fin) { return; } var buffer = channel.Alloc(); buffer.Append(inputBuffer); await channel.WriteAsync(buffer); } finally { input.EndRead(inputBuffer); } }while (input.IsCompleted); }
public static async Task CopyToAsync(this IReadableChannel input, IWritableChannel output) { while (true) { var inputBuffer = await input.ReadAsync(); var fin = input.Completion.IsCompleted; try { if (inputBuffer.IsEmpty && fin) { return; } var buffer = output.Alloc(); buffer.Append(ref inputBuffer); await buffer.FlushAsync(); } finally { inputBuffer.Consumed(); } } }
public static ValueTask <int> ReadAsync(this IReadableChannel input, Span <byte> destination) { while (true) { var awaiter = input.ReadAsync(); if (!awaiter.IsCompleted) { break; } var fin = input.Completion.IsCompleted; var inputBuffer = awaiter.GetResult(); var sliced = inputBuffer.Slice(0, destination.Length); sliced.CopyTo(destination); int actual = sliced.Length; inputBuffer.Consumed(sliced.End); if (actual != 0) { return(new ValueTask <int>(actual)); } else if (fin) { return(new ValueTask <int>(0)); } } return(new ValueTask <int>(input.ReadAsyncAwaited(destination))); }
private static async Task CopyCompletedAsync(IReadableChannel input, IWritableChannel channel) { var inputBuffer = await input; do { var fin = input.Completion.IsCompleted; try { if (inputBuffer.IsEmpty && fin) { return; } var buffer = channel.Alloc(); buffer.Append(inputBuffer); await buffer.FlushAsync(); } finally { inputBuffer.Consumed(); } }while (input.IsCompleted); }
public static async Task ConsumeAsync <T>( this IReadableChannel <T> channel, Func <T, Task> handleAsync, CancellationToken cancellationToken = default, Func <Task> onCompletedAsync = null, Func <Exception, Task> onTerminatedAsync = null) { try { do { while (channel.TryRead(out var item)) { await handleAsync(item).ConfigureAwait(false); } } while (await channel.WaitReadAvailableAsync(cancellationToken).ConfigureAwait(false)); if (onCompletedAsync != null) { await onCompletedAsync().ConfigureAwait(false); } } catch (Exception ex) { if (onTerminatedAsync != null) { await onTerminatedAsync(ex).ConfigureAwait(false); } else { throw; } } }
public IReadableChannel MakeReadableChannel(IReadableChannel channel, Func <IReadableChannel, IWritableChannel, Task> produce) { var newChannel = new Channel(_pool); Execute(channel, newChannel, produce); return(newChannel); }
public static async Task CopyToAsync(this IReadableChannel input, Stream stream) { while (true) { var inputBuffer = await input.ReadAsync(); var fin = input.Completion.IsCompleted; try { if (inputBuffer.IsEmpty && fin) { return; } foreach (var span in inputBuffer) { await stream.WriteAsync(span.Array, span.Offset, span.Length); } } finally { inputBuffer.Consumed(); } } }
private static void Pipes_WaitForReadThenTryReadValues() { using (AnonymousPipeServerStream serverPipe = new AnonymousPipeServerStream(PipeDirection.Out)) using (AnonymousPipeClientStream clientPipe = new AnonymousPipeClientStream(PipeDirection.In, serverPipe.ClientSafePipeHandle)) { IWritableChannel <int> writer = Channel.WriteToStream <int>(serverPipe); IReadableChannel <int> reader = Channel.ReadFromStream <int>(clientPipe); Task.WaitAll( Task.Run(async() => { for (int i = 0; i < 100; i++) { await writer.WriteAsync(i); } writer.Complete(); Assert.False(writer.TryWrite(100)); }), Task.Run(async() => { int result; int i = 0; while (await reader.WaitToReadAsync()) { if (reader.TryRead(out result)) { Assert.Equal(i++, result); } } Assert.False(reader.TryRead(out result)); })); } }
public static async Task CopyToAsync(this IReadableChannel input, Stream stream) { while (true) { await input; var fin = input.Completion.IsCompleted; var inputBuffer = input.BeginRead(); try { if (inputBuffer.IsEmpty && fin) { return; } foreach (var span in inputBuffer) { await stream.WriteAsync(span.Array, span.Offset, span.Length); } } catch (Exception) { // REVIEW: Should we do anything here? } finally { input.EndRead(inputBuffer); } } }
private static void Pipes_EnumerateValues() { using (AnonymousPipeServerStream serverPipe = new AnonymousPipeServerStream(PipeDirection.Out)) using (AnonymousPipeClientStream clientPipe = new AnonymousPipeClientStream(PipeDirection.In, serverPipe.ClientSafePipeHandle)) { IWritableChannel <int> writer = Channel.WriteToStream <int>(serverPipe); IReadableChannel <int> reader = Channel.ReadFromStream <int>(clientPipe); Task.WaitAll( Task.Run(async() => { for (int i = 0; i < 100; i++) { await writer.WriteAsync(i); } writer.Complete(); Assert.False(writer.TryWrite(100)); }), Task.Run(async() => { int i = 0; IAsyncEnumerator <int> e = reader.GetAsyncEnumerator(); while (await e.MoveNextAsync()) { Assert.Equal(i++, e.Current); } })); } }
public static async Task CopyToAsync(this IReadableChannel input, IWritableChannel channel) { while (true) { await input; var fin = input.Completion.IsCompleted; var inputBuffer = input.BeginRead(); try { if (inputBuffer.IsEmpty && fin) { return; } var buffer = channel.Alloc(); buffer.Append(inputBuffer); await channel.WriteAsync(buffer); } finally { input.EndRead(inputBuffer); } } }
Pipeline(IReadableChannel <T> inputChannel, IEnumerable <IRoutine> routines) { Guard.NotNull(inputChannel, nameof(inputChannel)); Guard.NotNull(routines, nameof(routines)); this.inputChannel = inputChannel; this.routines = routines; }
public static void ConsumeBufferedItems <T>( this IReadableChannel <T> channel, Action <T> handle) { while (channel.TryRead(out var item)) { handle(item); } }
public HttpConnection(IHttpApplication <TContext> application, IReadableChannel input, IWritableChannel output) { _application = application; _input = input; _output = output; _requestBody = new HttpRequestStream <TContext>(this); _responseBody = new HttpResponseStream <TContext>(this); }
/// <summary>Gets an awaiter that enables directly awaiting a channel to read data from it.</summary> /// <typeparam name="T">Specifies the type of data in the channel.</typeparam> /// <param name="channel">The channel to await and from which to read.</param> /// <returns>An awaiter for reading data from the channel.</returns> /// <remarks> /// Getting the awaiter will initiate a read operation on the channel. /// </remarks> public static ValueTask <T> .ValueTaskAwaiter GetAwaiter <T>(this IReadableChannel <T> channel) { if (channel == null) { throw new ArgumentNullException("channel"); } return(new ValueTask <T> .ValueTaskAwaiter(channel.ReadAsync(), continueOnCapturedContext : true)); }
public void Completion_Idempotent() { var t = new TaskCompletionSource <int>().Task; IReadableChannel <int> c = Channel.CreateFromTask(t); Assert.NotNull(c.Completion); Assert.NotSame(t, c.Completion); Assert.Same(c.Completion, c.Completion); }
public HttpConnection(IHttpApplication<TContext> application, IReadableChannel input, IWritableChannel output) { _application = application; _input = input; _output = output; _requestBody = new HttpRequestStream<TContext>(this); _responseBody = new HttpResponseStream<TContext>(this); _outputFormatter = _output.GetFormatter(EncodingData.InvariantUtf8); }
/// <summary>Gets an awaiter that enables directly awaiting a channel to read data from it.</summary> /// <typeparam name="T">Specifies the type of data in the channel.</typeparam> /// <param name="channel">The channel to await and from which to read.</param> /// <returns>An awaiter for reading data from the channel.</returns> /// <remarks> /// Getting the awaiter will initiate a read operation on the channel. /// </remarks> public static ValueTaskAwaiter <T> GetAwaiter <T>(this IReadableChannel <T> channel) { if (channel == null) { throw new ArgumentNullException("channel"); } return(channel.ReadAsync().GetAwaiter()); }
public void ReadFromStream_Precancellation() { IReadableChannel <int> r = Channel.ReadFromStream <int>(new MemoryStream()); var cts = new CancellationTokenSource(); cts.Cancel(); AssertSynchronouslyCanceled(r.WaitToReadAsync(cts.Token), cts.Token); AssertSynchronouslyCanceled(r.ReadAsync(cts.Token).AsTask(), cts.Token); }
public async Task Range_AllDataReadable_Success(int mode) { const int Start = 42, Count = 99; IReadableChannel <int> c = Channel.CreateFromEnumerable <int>(Enumerable.Range(Start, Count)); Assert.False(c.Completion.IsCompleted); int result; for (int i = Start; i < Start + Count; i++) { switch (mode) { case 0: // TryRead Assert.True(c.TryRead(out result)); Assert.Equal(i, result); break; case 1: // WaitToReadAsync then TryRead Assert.True(await c.WaitToReadAsync()); Assert.True(c.TryRead(out result)); Assert.Equal(i, result); break; case 2: // ReadAsync Assert.Equal(i, await c.ReadAsync()); break; case 3: // WaitToReadAsync then ReadAsync Assert.True(await c.WaitToReadAsync()); Assert.Equal(i, await c.ReadAsync()); break; case 4: // Multiple WaitToReadAsync then ReadAsync Assert.True(await c.WaitToReadAsync()); Assert.True(await c.WaitToReadAsync()); Assert.True(await c.WaitToReadAsync()); Assert.True(await c.WaitToReadAsync()); Assert.Equal(i, await c.ReadAsync()); break; } } Assert.False(await c.WaitToReadAsync()); Assert.False(await c.WaitToReadAsync()); Assert.False(c.TryRead(out result)); Assert.False(c.TryRead(out result)); await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.ReadAsync().AsTask()); await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.ReadAsync().AsTask()); await c.Completion; }