public void WritesDontCompleteImmediatelyWhenTooManyBytesAreAlreadyPreCompleted()
        {
            // This should match _maxBytesPreCompleted in SocketOutput
            var maxBytesPreCompleted = 65536;
            var completeQueue        = new Queue <Action <int> >();

            // Arrange
            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    completeQueue.Enqueue(triggerCompleted);
                    return(0);
                }
            };

            using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
            {
                kestrelEngine.Start(count: 1);

                var kestrelThread = kestrelEngine.Threads[0];
                var socket        = new MockSocket(kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                var trace         = new KestrelTrace(new TestKestrelTrace());
                var socketOutput  = new SocketOutput(kestrelThread, socket, 0, trace);

                var bufferSize  = maxBytesPreCompleted;
                var buffer      = new ArraySegment <byte>(new byte[bufferSize], 0, bufferSize);
                var completedWh = new ManualResetEventSlim();
                Action <Exception, object, bool> onCompleted = (ex, state, calledInline) =>
                {
                    Assert.Null(ex);
                    Assert.Null(state);
                    completedWh.Set();
                };

                // Act
                socketOutput.Write(buffer, onCompleted, null);
                // Assert
                // The first write should pre-complete since it is <= _maxBytesPreCompleted.
                Assert.True(completedWh.Wait(1000));
                // Arrange
                completedWh.Reset();
                // Act
                socketOutput.Write(buffer, onCompleted, null);
                // Assert
                // Too many bytes are already pre-completed for the second write to pre-complete.
                Assert.False(completedWh.Wait(1000));
                // Act
                completeQueue.Dequeue()(0);
                // Assert
                // Finishing the first write should allow the second write to pre-complete.
                Assert.True(completedWh.Wait(1000));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Writes some data to the connection.
        /// </summary>
        public void Write(ArraySegment <byte> data)
        {
            // Update the expires timer
            this.Expires = Timer.Now + Timeout;

            // Increment the counters
            NetStat.BytesOutgoing.Add(data.Count);

            // Write through the socket
            SocketOutput.Write(data);
        }
        public void CanWrite1MB()
        {
            // This test was added because when initially implementing write-behind buffering in
            // SocketOutput, the write callback would never be invoked for writes larger than
            // _maxBytesPreCompleted even after the write actually completed.

            // Arrange
            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    triggerCompleted(0);
                    return(0);
                }
            };

            using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
            {
                kestrelEngine.Start(count: 1);

                var kestrelThread = kestrelEngine.Threads[0];
                var socket        = new MockSocket(kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                var trace         = new KestrelTrace(new TestKestrelTrace());
                var socketOutput  = new SocketOutput(kestrelThread, socket, 0, trace);

                // I doubt _maxBytesPreCompleted will ever be over a MB. If it is, we should change this test.
                var bufferSize  = 1048576;
                var buffer      = new ArraySegment <byte>(new byte[bufferSize], 0, bufferSize);
                var completedWh = new ManualResetEventSlim();
                Action <Exception, object, bool> onCompleted = (ex, state, calledInline) =>
                {
                    Assert.Null(ex);
                    Assert.Null(state);
                    completedWh.Set();
                };

                // Act
                socketOutput.Write(buffer, onCompleted, null);

                // Assert
                Assert.True(completedWh.Wait(1000));
            }
        }
Esempio n. 4
0
 /// <summary>
 /// Flushes the connection.
 /// </summary>
 public void Flush()
 {
     SocketOutput.Write(EmptyBuffer);
 }