예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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();
        }
예제 #3
0
        /// <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);
            }
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        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);
                }
            }
        }
예제 #6
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");
        }
예제 #7
0
 public HttpConnection(IHttpApplication <TContext> application, IReadableChannel input, IWritableChannel output)
 {
     _application = application;
     _input       = input;
     _output      = output;
     _initialBody = new HttpBodyStream <TContext>(this);
 }
예제 #8
0
        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;
                }
        }
예제 #9
0
        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);
                }
            }
        }
예제 #10
0
        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);
                }
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
        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();
                }
            }
        }
예제 #13
0
        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)));
        }
예제 #14
0
        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);
        }
예제 #15
0
        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;
                }
            }
        }
예제 #16
0
        public IReadableChannel MakeReadableChannel(IReadableChannel channel, Func <IReadableChannel, IWritableChannel, Task> produce)
        {
            var newChannel = new Channel(_pool);

            Execute(channel, newChannel, produce);
            return(newChannel);
        }
예제 #17
0
        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();
                }
            }
        }
예제 #18
0
        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));
                    }));
                }
        }
예제 #19
0
        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);
                }
            }
        }
예제 #20
0
        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);
                        }
                    }));
                }
        }
예제 #21
0
        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);
                }
            }
        }
예제 #22
0
        Pipeline(IReadableChannel <T> inputChannel, IEnumerable <IRoutine> routines)
        {
            Guard.NotNull(inputChannel, nameof(inputChannel));
            Guard.NotNull(routines, nameof(routines));

            this.inputChannel = inputChannel;
            this.routines     = routines;
        }
예제 #23
0
 public static void ConsumeBufferedItems <T>(
     this IReadableChannel <T> channel, Action <T> handle)
 {
     while (channel.TryRead(out var item))
     {
         handle(item);
     }
 }
예제 #24
0
 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);
 }
예제 #25
0
        /// <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));
        }
예제 #26
0
        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);
        }
예제 #27
0
 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);
 }
예제 #28
0
        /// <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());
        }
예제 #29
0
        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);
        }
예제 #30
0
        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;
        }