public void ThrowsOnAdvanceWithNoMemory() { using (var memoryPool = new MemoryPool()) { var pipe = new ResetablePipe(new PipeOptions(memoryPool)); var buffer = pipe.Writer; var exception = Assert.Throws <InvalidOperationException>(() => buffer.Advance(1)); Assert.Equal("No writing operation. Make sure GetMemory() was called.", exception.Message); } }
public async Task CanWriteNothingToBuffer() { using (var memoryPool = new MemoryPool()) { var pipe = new ResetablePipe(new PipeOptions(memoryPool)); var buffer = pipe.Writer; buffer.GetMemory(0); buffer.Advance(0); // doing nothing, the hard way await buffer.FlushAsync(); } }
public static PipeWriter CreateWriter(PipeOptions options, Stream stream) { if (!stream.CanWrite) { throw new NotSupportedException(); } var pipe = new ResetablePipe(options); var ignore = pipe.Reader.CopyToEndAsync(stream); return(pipe.Writer); }
public void OnWriterCompletedExceptionSurfacesToReaderScheduler() { var exception = new Exception(); var scheduler = new TestScheduler(); var pipe = new ResetablePipe(new PipeOptions(_pool, readerScheduler: scheduler)); pipe.Reader.OnWriterCompleted((e, state) => throw exception, null); pipe.Writer.Complete(); Assert.Equal(1, scheduler.CallCount); var aggregateException = Assert.IsType <AggregateException>(scheduler.LastException); Assert.Equal(aggregateException.InnerExceptions[0], exception); }
public void OnWriterCompletedPassesState() { var callbackRan = false; var callbackState = new object(); var pipe = new ResetablePipe(new PipeOptions(_pool)); pipe.Reader.OnWriterCompleted((exception, state) => { Assert.Equal(callbackState, state); callbackRan = true; }, callbackState); pipe.Writer.Complete(); Assert.True(callbackRan); }
public async Task WriteHex(int value, string hex) { using (var memoryPool = new MemoryPool()) { var pipe = new ResetablePipe(new PipeOptions(memoryPool)); var buffer = pipe.Writer; buffer.Append(value, SymbolTable.InvariantUtf8, 'x'); await buffer.FlushAsync(); var result = await pipe.Reader.ReadAsync(); Assert.Equal(hex, result.Buffer.GetAsciiString()); pipe.Reader.Advance(result.Buffer.End); } }
public void OnWriterCompletedUsingReaderScheduler() { var callbackRan = false; var scheduler = new TestScheduler(); var pipe = new ResetablePipe(new PipeOptions(_pool, readerScheduler: scheduler)); pipe.Reader.OnWriterCompleted((exception, state) => { callbackRan = true; }, null); pipe.Writer.Complete(); Assert.True(callbackRan); Assert.Equal(1, scheduler.CallCount); }
public async Task MultipleCompleteReaderWriterCauseDisposeOnlyOnce() { var pool = new DisposeTrackingBufferPool(); var readerWriter = new ResetablePipe(new PipeOptions(pool)); await readerWriter.Writer.WriteAsync(new byte[] { 1 }); readerWriter.Writer.Complete(); readerWriter.Reader.Complete(); Assert.Equal(1, pool.ReturnedBlocks); readerWriter.Writer.Complete(); readerWriter.Reader.Complete(); Assert.Equal(1, pool.ReturnedBlocks); }
public void OnReaderCompletedPassesException() { var callbackRan = false; var pipe = new ResetablePipe(new PipeOptions(_pool)); var readerException = new Exception(); pipe.Writer.OnReaderCompleted((exception, state) => { callbackRan = true; Assert.Same(readerException, exception); }, null); pipe.Reader.Complete(readerException); Assert.True(callbackRan); }
public async Task CanWriteUInt64ToBuffer(ulong value, string valueAsString) { using (var memoryPool = new MemoryPool()) { var pipe = new ResetablePipe(new PipeOptions(memoryPool)); var buffer = pipe.Writer; buffer.Append(value, SymbolTable.InvariantUtf8); await buffer.FlushAsync(); var result = await pipe.Reader.ReadAsync(); var inputBuffer = result.Buffer; Assert.Equal(valueAsString, inputBuffer.GetUtf8Span()); } }
public async Task WriteDuringReadIsNotReturned() { var pool = new DisposeTrackingBufferPool(); var writeSize = 512; var pipe = new ResetablePipe(new PipeOptions(pool)); await pipe.Writer.WriteAsync(new byte[writeSize]); pipe.Writer.GetMemory(writeSize); var readResult = await pipe.Reader.ReadAsync(); pipe.Reader.Advance(readResult.Buffer.End); pipe.Writer.Write(new byte[writeSize]); pipe.Writer.Commit(); Assert.Equal(1, pool.CurrentlyRentedBlocks); }
public void CompletingWriterFromReaderCallbackWorks() { var callbackRan = false; var pipe = new ResetablePipe(new PipeOptions(_pool, maximumSizeHigh: 5)); pipe.Reader.OnWriterCompleted((exception, state) => { pipe.Reader.Complete(); }, null); pipe.Writer.OnReaderCompleted((exception, state) => { callbackRan = true; }, null); pipe.Writer.Complete(); Assert.True(callbackRan); }
internal SocketConnection(Socket socket, MemoryPool <byte> pool) { socket.NoDelay = true; _socket = socket; if (pool == null) { _ownsPool = true; pool = new MemoryPool(); } _pool = pool; // TODO: Make this configurable // Dispatch to avoid deadlocks _input = new ResetablePipe(new PipeOptions(pool, Scheduler.ThreadPool, Scheduler.ThreadPool)); _output = new ResetablePipe(new PipeOptions(pool, Scheduler.ThreadPool, Scheduler.ThreadPool)); _receiveTask = ReceiveFromSocketAndPushToWriterAsync(); _sendTask = ReadFromReaderAndWriteToSocketAsync(); }
public async Task AdvanceToEndReturnsAllBlocks() { var pool = new DisposeTrackingBufferPool(); var writeSize = 512; var pipe = new ResetablePipe(new PipeOptions(pool)); while (pool.CurrentlyRentedBlocks != 3) { var writableBuffer = pipe.Writer.WriteEmpty(writeSize); await writableBuffer.FlushAsync(); } var readResult = await pipe.Reader.ReadAsync(); pipe.Reader.Advance(readResult.Buffer.End); Assert.Equal(0, pool.CurrentlyRentedBlocks); }
public async Task FlushCallbackRunsOnWriterScheduler() { using (var pool = new MemoryPool()) { using (var scheduler = new ThreadScheduler()) { var pipe = new ResetablePipe(new PipeOptions(pool, maximumSizeLow: 32, maximumSizeHigh: 64, writerScheduler: scheduler)); var writableBuffer = pipe.Writer.WriteEmpty(64); var flushAsync = writableBuffer.FlushAsync(); Assert.False(flushAsync.IsCompleted); Func <Task> doWrite = async() => { var oid = Thread.CurrentThread.ManagedThreadId; await flushAsync; Assert.NotEqual(oid, Thread.CurrentThread.ManagedThreadId); pipe.Writer.Complete(); Assert.Equal(Thread.CurrentThread.ManagedThreadId, scheduler.Thread.ManagedThreadId); }; var writing = doWrite(); var result = await pipe.Reader.ReadAsync(); pipe.Reader.Advance(result.Buffer.End, result.Buffer.End); pipe.Reader.Complete(); await writing; } } }
public async Task RentsMinimumSegmentSize() { var pool = new DisposeTrackingBufferPool(); var writeSize = 512; var pipe = new ResetablePipe(new PipeOptions(pool, minimumSegmentSize: 2020)); var buffer = pipe.Writer.GetMemory(writeSize); var allocatedSize = buffer.Length; pipe.Writer.Advance(buffer.Length); buffer = pipe.Writer.GetMemory(1); var ensuredSize = buffer.Length; await pipe.Writer.FlushAsync(); pipe.Reader.Complete(); pipe.Writer.Complete(); Assert.Equal(2020, ensuredSize); Assert.Equal(2020, allocatedSize); }
public async Task CopyToAsync() { using (var pool = new MemoryPool()) { var readerWriter = new ResetablePipe(new PipeOptions(pool)); var output = readerWriter.Writer; output.Append("Hello World", SymbolTable.InvariantUtf8); await output.FlushAsync(); var ms = new MemoryStream(); var result = await readerWriter.Reader.ReadAsync(); var rb = result.Buffer; await rb.CopyToAsync(ms); ms.Position = 0; Assert.Equal(11, rb.Length); Assert.Equal(11, ms.Length); Assert.Equal(rb.ToArray(), ms.ToArray()); Assert.Equal("Hello World", Encoding.ASCII.GetString(ms.ToArray())); } }
public async Task DefaultWriterSchedulerRunsInline() { using (var pool = new MemoryPool()) { var pipe = new ResetablePipe(new PipeOptions(pool, maximumSizeLow: 32, maximumSizeHigh: 64 )); var writableBuffer = pipe.Writer.WriteEmpty(64); var flushAsync = writableBuffer.FlushAsync(); Assert.False(flushAsync.IsCompleted); int id = 0; Func <Task> doWrite = async() => { await flushAsync; pipe.Writer.Complete(); Assert.Equal(Thread.CurrentThread.ManagedThreadId, id); }; var writing = doWrite(); var result = await pipe.Reader.ReadAsync(); id = Thread.CurrentThread.ManagedThreadId; pipe.Reader.Advance(result.Buffer.End, result.Buffer.End); pipe.Reader.Complete(); await writing; } }
public void OnWriterCompletedRanBeforeReadContinuation() { var callbackRan = false; var continuationRan = false; var pipe = new ResetablePipe(new PipeOptions(_pool)); pipe.Reader.OnWriterCompleted((exception, state) => { callbackRan = true; Assert.False(continuationRan); }, null); var awaiter = pipe.Reader.ReadAsync(); Assert.False(awaiter.IsCompleted); awaiter.OnCompleted(() => { continuationRan = true; }); pipe.Writer.Complete(); Assert.True(callbackRan); }
public async Task WriteLargeDataTextAscii(int length) { string data = new string('#', length); FillRandomStringData(data, length); using (var memoryPool = new MemoryPool()) { var pipe = new ResetablePipe(new PipeOptions(memoryPool)); var output = pipe.Writer; output.Append(data, SymbolTable.InvariantUtf8); var foo = output.GetMemory().IsEmpty; // trying to see if .Memory breaks await output.FlushAsync(); pipe.Writer.Complete(); long offset = 0; while (true) { var result = await pipe.Reader.ReadAsync(); var input = result.Buffer; if (input.Length == 0) { break; } string s = ReadableBufferExtensions.GetAsciiString(input); // We are able to cast because test arguments are in range of int Assert.Equal(data.Substring((int)offset, (int)input.Length), s); offset += input.Length; pipe.Reader.Advance(input.End); } Assert.Equal(data.Length, offset); } }
public WritableBufferWriterFacts() { _pool = new MemoryPool(); _pipe = new ResetablePipe(new PipeOptions(_pool)); }
public void OnWriterCompletedThrowsWithNullCallback() { var pipe = new ResetablePipe(new PipeOptions(_pool)); Assert.Throws <ArgumentNullException>(() => pipe.Reader.OnWriterCompleted(null, null)); }
public PipeConnection(PipeOptions pipeOptions) { Input = new ResetablePipe(pipeOptions); Output = new ResetablePipe(pipeOptions); }
public PipeResetTests() { _pool = new MemoryPool(); _pipe = new ResetablePipe(new PipeOptions(_pool)); }
public BackpressureTests() { _pool = new MemoryPool(); _pipe = new ResetablePipe(new PipeOptions(_pool, maximumSizeLow: 32, maximumSizeHigh: 64)); }