コード例 #1
0
    private void OnOutputDragDroppedTo(SocketInput target)
    {
        //  if sockets connected already
        //  do nothing
        if (_currentDraggingSocket.HasConnection() && target.HasConnection())
        {
            if (_currentDraggingSocket.connection == target.connection)
            {
                _currentDraggingSocket = null;
                drawer.CancelDrag();

                return;
            }
        }

        if (target != null)
        {
            //  check if input allows multiple connection
            if (target.HasConnection())
            {
                //  disconnect old connection
                if (target.connectionType != ConnectionType.Multiple)
                {
                    Disconnect(target.connection);
                }
            }

            Connect(target, _currentDraggingSocket);
        }

        _currentDraggingSocket = null;
        drawer.CancelDrag();
    }
コード例 #2
0
        public void ProducingStartAndProducingCompleteCanBeCalledAfterConnectionClose()
        {
            var mockLibuv = new MockLibuv();

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

                    var kestrelThread = kestrelEngine.Threads[0];
                    var socket        = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                    var trace         = new KestrelTrace(new TestKestrelTrace());
                    var ltp           = new LoggingThreadPool(trace);
                    var connection    = new MockConnection();
                    var socketOutput  = new SocketOutput(kestrelThread, socket, memory, connection, "0", trace, ltp, new Queue <UvWriteReq>());

                    // Close SocketOutput
                    var cleanupTask = socketOutput.WriteAsync(
                        default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);

                    Assert.True(connection.SocketClosed.Wait(1000));

                    var start = socketOutput.ProducingStart();

                    Assert.True(start.IsDefault);
                    // ProducingComplete should not throw given a default iterator
                    socketOutput.ProducingComplete(start);
                }
        }
コード例 #3
0
 private void OnOutputSocketClicked(SocketOutput output, PointerEventData eventData)
 {
     if (eventData.button == PointerEventData.InputButton.Right)
     {
         connections.Where(conn => conn.output == output)
         .ToList()
         .ForEach(conn => Disconnect(conn));
     }
 }
コード例 #4
0
        public void OnlyAllowsUpToThreeConcurrentWrites()
        {
            var writeWh       = new ManualResetEventSlim();
            var completeQueue = new Queue <Action <int> >();

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

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

                    var kestrelThread = kestrelEngine.Threads[0];
                    var socket        = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                    var trace         = new KestrelTrace(new TestKestrelTrace());
                    var ltp           = new LoggingThreadPool(trace);
                    var socketOutput  = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue <UvWriteReq>());

                    var buffer = new ArraySegment <byte>(new byte[1]);

                    // First three writes trigger uv_write
                    socketOutput.WriteAsync(buffer, CancellationToken.None);
                    Assert.True(writeWh.Wait(1000));
                    writeWh.Reset();
                    socketOutput.WriteAsync(buffer, CancellationToken.None);
                    Assert.True(writeWh.Wait(1000));
                    writeWh.Reset();
                    socketOutput.WriteAsync(buffer, CancellationToken.None);
                    Assert.True(writeWh.Wait(1000));
                    writeWh.Reset();

                    // The fourth write won't trigger uv_write since the first three haven't completed
                    socketOutput.WriteAsync(buffer, CancellationToken.None);
                    Assert.False(writeWh.Wait(1000));

                    // Complete 1st write allowing uv_write to be triggered again
                    completeQueue.Dequeue()(0);
                    Assert.True(writeWh.Wait(1000));

                    // Cleanup
                    var cleanupTask = socketOutput.WriteAsync(
                        default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);

                    foreach (var triggerCompleted in completeQueue)
                    {
                        triggerCompleted(0);
                    }
                }
        }
コード例 #5
0
        public void WritesAreAggregated()
        {
            var writeWh    = new ManualResetEventSlim();
            var writeCount = 0;

            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    writeCount++;
                    triggerCompleted(0);
                    writeWh.Set();
                    return(0);
                }
            };

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

                    var kestrelThread = kestrelEngine.Threads[0];
                    var socket        = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                    var trace         = new KestrelTrace(new TestKestrelTrace());
                    var ltp           = new LoggingThreadPool(trace);
                    var socketOutput  = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue <UvWriteReq>());

                    var blockThreadWh = new ManualResetEventSlim();
                    kestrelThread.Post(_ =>
                    {
                        blockThreadWh.Wait();
                    }, state: null);

                    var buffer = new ArraySegment <byte>(new byte[1]);

                    // Two calls to WriteAsync trigger uv_write once if both calls
                    // are made before write is scheduled
                    socketOutput.WriteAsync(buffer, CancellationToken.None);
                    socketOutput.WriteAsync(buffer, CancellationToken.None);

                    blockThreadWh.Set();

                    Assert.True(writeWh.Wait(1000));
                    writeWh.Reset();

                    // Write isn't called twice after the thread is unblocked
                    Assert.False(writeWh.Wait(1000));
                    Assert.Equal(1, writeCount);
                    // One call to ScheduleWrite + One call to Post to block the thread
                    Assert.Equal(2, mockLibuv.PostCount);

                    // Cleanup
                    var cleanupTask = socketOutput.WriteAsync(
                        default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);
                }
        }
コード例 #6
0
        private static void Main(string[] args)
        {
            var server = new SocketOutput();

            server.SetupServer();
            server.SetupAdminServer();
            Console.ReadLine();
            server.CloseConnection();
            Console.ReadKey();
        }
コード例 #7
0
        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()))
                using (var memory = new MemoryPool2())
                {
                    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 ltp           = new LoggingThreadPool(trace);
                    var socketOutput  = new SocketOutput(kestrelThread, socket, memory, null, 0, trace, ltp, new Queue <UvWriteReq>());

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

                    // Act
                    socketOutput.WriteAsync(buffer).ContinueWith(onCompleted);
                    // Assert
                    // The first write should pre-complete since it is <= _maxBytesPreCompleted.
                    Assert.True(completedWh.Wait(1000));
                    // Arrange
                    completedWh.Reset();
                    // Act
                    socketOutput.WriteAsync(buffer).ContinueWith(onCompleted);
                    // 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));
                }
        }
コード例 #8
0
ファイル: Connection.cs プロジェクト: sentientpc/emitter
        /// <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);
        }
コード例 #9
0
ファイル: Connection.cs プロジェクト: sentientpc/emitter
        /// <summary>
        /// Writes some data to the connection.
        /// </summary>
        public Task WriteAsync(ArraySegment <byte> data, CancellationToken cancellationToken)
        {
            // Update the expires timer
            this.Expires = Timer.Now + Timeout;

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

            // Write through the socket
            return(SocketOutput.WriteAsync(data, cancellationToken: cancellationToken));
        }
コード例 #10
0
ファイル: Connection.cs プロジェクト: sentientpc/emitter
        /// <summary>
        /// Creates a new connection from the listener context.
        /// </summary>
        /// <param name="context">The listener context to use.</param>
        /// <param name="socket">The socket handle.</param>
        internal Connection(ListenerContext context, UvStreamHandle socket) : base(context)
        {
            _socket           = socket;
            socket.Connection = this;

            ConnectionId = ConnectionId.NewConnectionId();

            _rawSocketInput  = new SocketInput(Memory, ThreadPool);
            _rawSocketOutput = new SocketOutput(Thread, _socket, Memory, this, ConnectionId, ThreadPool, WriteReqPool);

            this.Expires = Timer.Now + TimeSpan.FromMinutes(1);
            this.ConnectionManager.Register(this);
        }
コード例 #11
0
 public void Post(Action <SocketOutput> callback, SocketOutput state)
 {
     lock (_workSync)
     {
         _workAdding.Enqueue(new Work
         {
             CallbackAdapter = _socketCallbackAdapter,
             Callback        = callback,
             State           = state
         });
     }
     _post.Send();
 }
コード例 #12
0
        public void ProducingStartAndProducingCompleteCanBeUsedDirectly()
        {
            int nBuffers  = 0;
            var nBufferWh = new ManualResetEventSlim();

            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    nBuffers = buffers;
                    nBufferWh.Set();
                    triggerCompleted(0);
                    return(0);
                }
            };

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

                    var kestrelThread = kestrelEngine.Threads[0];
                    var socket        = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                    var trace         = new KestrelTrace(new TestKestrelTrace());
                    var ltp           = new LoggingThreadPool(trace);
                    var socketOutput  = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue <UvWriteReq>());

                    // block 1
                    var start = socketOutput.ProducingStart();
                    start.Block.End = start.Block.Data.Offset + start.Block.Data.Count;

                    // block 2
                    var block2 = memory.Lease();
                    block2.End       = block2.Data.Offset + block2.Data.Count;
                    start.Block.Next = block2;

                    var end = new MemoryPoolIterator(block2, block2.End);

                    socketOutput.ProducingComplete(end);

                    // A call to Write is required to ensure a write is scheduled
                    socketOutput.WriteAsync(default(ArraySegment <byte>), default(CancellationToken));

                    Assert.True(nBufferWh.Wait(1000));
                    Assert.Equal(2, nBuffers);

                    // Cleanup
                    var cleanupTask = socketOutput.WriteAsync(
                        default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);
                }
        }
コード例 #13
0
        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 memory = new MemoryPool())
                using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
                {
                    kestrelEngine.Start(count: 1);

                    var kestrelThread = kestrelEngine.Threads[0];
                    var socket        = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                    var trace         = new KestrelTrace(new TestKestrelTrace());
                    var ltp           = new LoggingThreadPool(trace);
                    var socketOutput  = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue <UvWriteReq>());

                    // 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();

                    // Act
                    socketOutput.WriteAsync(buffer, default(CancellationToken)).ContinueWith(
                        (t) =>
                    {
                        Assert.Null(t.Exception);
                        completedWh.Set();
                    }
                        );

                    // Assert
                    Assert.True(completedWh.Wait(1000));

                    // Cleanup
                    var cleanupTask = socketOutput.WriteAsync(
                        default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);
                }
        }
コード例 #14
0
    private void OnOutputDragStarted(SocketOutput socketOnDrag)
    {
        _currentDraggingSocket = socketOnDrag;
        drawer.StartDrag(_currentDraggingSocket);

        //  check socket connection type
        if (_currentDraggingSocket.HasConnection())
        {
            //  if single, disconnect
            if (_currentDraggingSocket.connectionType == ConnectionType.Single)
            {
                Disconnect(_currentDraggingSocket.connection);
            }
        }
    }
コード例 #15
0
ファイル: Program.cs プロジェクト: Deeadline/ZTP
        //public static readonly Logger.Logger Logger = new Logger.Logger(Output.Output.Socket);

        private static void Main(string[] args)
        {
            //Logger.Log(LogLevel.Info, "TEST 1");
            //Logger.Log(LogLevel.Error, "TEST 1");
            //Logger.Log(LogLevel.Alert, "TEST 1");
            //Logger.Log(LogLevel.Debug, "");


            var server = new SocketOutput();

            server.SetupServer();
            server.SetupAdminServer();
            Console.ReadLine();
            server.CloseConnection();
            Console.ReadKey();
        }
コード例 #16
0
    public void Connect(SocketInput input, SocketOutput output)
    {
        var connection = new Connection()
        {
            id     = CreateId,
            input  = input,
            output = output
        };

        input.Connect(connection);
        output.Connect(connection);

        connections.Add(connection);
        input.parentNode.OnConnection(input, output);

        drawer.Add(connection.id, output.handle, input.handle);
    }
コード例 #17
0
        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));
            }
        }
コード例 #18
0
        public async Task FailedWriteCompletesOrCancelsAllPendingTasks()
        {
            // 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 memory = new MemoryPool())
                using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
                {
                    kestrelEngine.Start(count: 1);

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

                    using (var mockConnection = new MockConnection())
                    {
                        var           abortedSource = mockConnection.RequestAbortedSource;
                        ISocketOutput socketOutput  = new SocketOutput(kestrelThread, socket, memory, mockConnection, "0", trace, ltp, new Queue <UvWriteReq>());

                        var bufferSize = maxBytesPreCompleted;

                        var data       = new byte[bufferSize];
                        var fullBuffer = new ArraySegment <byte>(data, 0, bufferSize);

                        // Act
                        var task1Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: abortedSource.Token);
                        // task1 should complete successfully as < _maxBytesPreCompleted

                        // First task is completed and successful
                        Assert.True(task1Success.IsCompleted);
                        Assert.False(task1Success.IsCanceled);
                        Assert.False(task1Success.IsFaulted);

                        // following tasks should wait.
                        var task2Success  = socketOutput.WriteAsync(fullBuffer, cancellationToken: default(CancellationToken));
                        var task3Canceled = socketOutput.WriteAsync(fullBuffer, cancellationToken: abortedSource.Token);

                        // Give time for tasks to percolate
                        await Task.Delay(1000);

                        // Second task is not completed
                        Assert.False(task2Success.IsCompleted);
                        Assert.False(task2Success.IsCanceled);
                        Assert.False(task2Success.IsFaulted);

                        // Third task is not completed
                        Assert.False(task3Canceled.IsCompleted);
                        Assert.False(task3Canceled.IsCanceled);
                        Assert.False(task3Canceled.IsFaulted);

                        // Cause the first write to fail.
                        completeQueue.Dequeue()(-1);

                        // Second task is now completed
                        await task2Success;

                        // Third task is now canceled
                        await Assert.ThrowsAsync <TaskCanceledException>(() => task3Canceled);

                        Assert.True(task3Canceled.IsCanceled);

                        // Cleanup
                        var cleanupTask = ((SocketOutput)socketOutput).WriteAsync(
                            default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);

                        foreach (var triggerCompleted in completeQueue)
                        {
                            triggerCompleted(0);
                        }
                    }
                }
        }
コード例 #19
0
 public static void InvokeOutputSocketClick(SocketOutput output, PointerEventData eventData)
 {
     OutputSocketClickEvent?.Invoke(output, eventData);
 }
コード例 #20
0
ファイル: Connection.cs プロジェクト: sentientpc/emitter
 /// <summary>
 /// Flushes the connection.
 /// </summary>
 public async Task FlushAsync(CancellationToken cancellationToken)
 {
     await SocketOutput.WriteAsync(EmptyBuffer, cancellationToken : cancellationToken);
 }
コード例 #21
0
ファイル: Connection.cs プロジェクト: sentientpc/emitter
 /// <summary>
 /// Flushes the connection.
 /// </summary>
 public void Flush()
 {
     SocketOutput.Write(EmptyBuffer);
 }
コード例 #22
0
        public async Task OnlyWritesRequestingCancellationAreErroredOnCancellation()
        {
            // 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 memory = new MemoryPool())
                using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
                {
                    kestrelEngine.Start(count: 1);

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

                    using (var mockConnection = new MockConnection())
                    {
                        ISocketOutput socketOutput = new SocketOutput(kestrelThread, socket, memory, mockConnection, "0", trace, ltp, new Queue <UvWriteReq>());

                        var bufferSize = maxBytesPreCompleted;

                        var data       = new byte[bufferSize];
                        var fullBuffer = new ArraySegment <byte>(data, 0, bufferSize);

                        var cts = new CancellationTokenSource();

                        // Act
                        var task1Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token);
                        // task1 should complete successfully as < _maxBytesPreCompleted

                        // First task is completed and successful
                        Assert.True(task1Success.IsCompleted);
                        Assert.False(task1Success.IsCanceled);
                        Assert.False(task1Success.IsFaulted);

                        // following tasks should wait.
                        var task2Throw   = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token);
                        var task3Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: default(CancellationToken));

                        // Give time for tasks to percolate
                        await Task.Delay(1000);

                        // Second task is not completed
                        Assert.False(task2Throw.IsCompleted);
                        Assert.False(task2Throw.IsCanceled);
                        Assert.False(task2Throw.IsFaulted);

                        // Third task is not completed
                        Assert.False(task3Success.IsCompleted);
                        Assert.False(task3Success.IsCanceled);
                        Assert.False(task3Success.IsFaulted);

                        cts.Cancel();

                        // Second task is now canceled
                        await Assert.ThrowsAsync <TaskCanceledException>(() => task2Throw);

                        Assert.True(task2Throw.IsCanceled);

                        // Third task is now completed
                        await task3Success;

                        // Fourth task immediately cancels as the token is canceled
                        var task4Throw = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token);

                        Assert.True(task4Throw.IsCompleted);
                        Assert.True(task4Throw.IsCanceled);
                        Assert.False(task4Throw.IsFaulted);

                        var task5Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: default(CancellationToken));
                        // task5 should complete immediately

                        Assert.True(task5Success.IsCompleted);
                        Assert.False(task5Success.IsCanceled);
                        Assert.False(task5Success.IsFaulted);

                        cts = new CancellationTokenSource();

                        var task6Success = socketOutput.WriteAsync(fullBuffer, cancellationToken: cts.Token);
                        // task6 should complete immediately but not cancel as its cancellation token isn't set

                        Assert.True(task6Success.IsCompleted);
                        Assert.False(task6Success.IsCanceled);
                        Assert.False(task6Success.IsFaulted);

                        Assert.True(true);

                        // Cleanup
                        var cleanupTask = ((SocketOutput)socketOutput).WriteAsync(
                            default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);

                        foreach (var triggerCompleted in completeQueue)
                        {
                            triggerCompleted(0);
                        }
                    }
                }
        }
コード例 #23
0
        public void WritesDontCompleteImmediatelyWhenTooManyBytesIncludingNonImmediateAreAlreadyPreCompleted()
        {
            // This should match _maxBytesPreCompleted in SocketOutput
            var maxBytesPreCompleted = 65536;
            var completeQueue        = new Queue <Action <int> >();
            var writeRequestedWh     = new ManualResetEventSlim();

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

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

                    var kestrelThread = kestrelEngine.Threads[0];
                    var socket        = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                    var trace         = new KestrelTrace(new TestKestrelTrace());
                    var ltp           = new LoggingThreadPool(trace);
                    var socketOutput  = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue <UvWriteReq>());

                    var bufferSize            = maxBytesPreCompleted / 2;
                    var data                  = new byte[bufferSize];
                    var halfWriteBehindBuffer = new ArraySegment <byte>(data, 0, bufferSize);

                    // Act
                    var writeTask1 = socketOutput.WriteAsync(halfWriteBehindBuffer, default(CancellationToken));
                    // Assert
                    // The first write should pre-complete since it is <= _maxBytesPreCompleted.
                    Assert.Equal(TaskStatus.RanToCompletion, writeTask1.Status);
                    Assert.True(writeRequestedWh.Wait(1000));
                    writeRequestedWh.Reset();

                    // Add more bytes to the write-behind buffer to prevent the next write from
                    var iter = socketOutput.ProducingStart();
                    iter.CopyFrom(halfWriteBehindBuffer);
                    socketOutput.ProducingComplete(iter);

                    // Act
                    var writeTask2 = socketOutput.WriteAsync(halfWriteBehindBuffer, default(CancellationToken));
                    // Assert
                    // Too many bytes are already pre-completed for the fourth write to pre-complete.
                    Assert.True(writeRequestedWh.Wait(1000));
                    Assert.False(writeTask2.IsCompleted);

                    // 2 calls have been made to uv_write
                    Assert.Equal(2, completeQueue.Count);

                    // Act
                    completeQueue.Dequeue()(0);

                    // Assert
                    // Finishing the first write should allow the second write to pre-complete.
                    Assert.True(writeTask2.Wait(1000));

                    // Cleanup
                    var cleanupTask = socketOutput.WriteAsync(
                        default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);

                    foreach (var triggerCompleted in completeQueue)
                    {
                        triggerCompleted(0);
                    }
                }
        }
コード例 #24
0
 public static void InvokeSocketDragFrom(SocketOutput output)
 {
     OutputSocketDragStartEvent?.Invoke(output);
 }
コード例 #25
0
        public void WritesDontGetCompletedTooQuickly()
        {
            // This should match _maxBytesPreCompleted in SocketOutput
            var maxBytesPreCompleted = 65536;
            var completeQueue        = new Queue <Action <int> >();
            var onWriteWh            = new ManualResetEventSlim();

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

                    return(0);
                }
            };

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

                    var kestrelThread = kestrelEngine.Threads[0];
                    var socket        = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                    var trace         = new KestrelTrace(new TestKestrelTrace());
                    var ltp           = new LoggingThreadPool(trace);
                    var socketOutput  = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue <UvWriteReq>());

                    var bufferSize = maxBytesPreCompleted;
                    var buffer     = new ArraySegment <byte>(new byte[bufferSize], 0, bufferSize);

                    var           completedWh = new ManualResetEventSlim();
                    Action <Task> onCompleted = (Task t) =>
                    {
                        Assert.Null(t.Exception);
                        completedWh.Set();
                    };

                    var           completedWh2 = new ManualResetEventSlim();
                    Action <Task> onCompleted2 = (Task t) =>
                    {
                        Assert.Null(t.Exception);
                        completedWh2.Set();
                    };

                    // Act (Pre-complete the maximum number of bytes in preparation for the rest of the test)
                    socketOutput.WriteAsync(buffer, default(CancellationToken)).ContinueWith(onCompleted);
                    // Assert
                    // The first write should pre-complete since it is <= _maxBytesPreCompleted.
                    Assert.True(completedWh.Wait(1000));
                    Assert.True(onWriteWh.Wait(1000));
                    // Arrange
                    completedWh.Reset();
                    onWriteWh.Reset();

                    // Act
                    socketOutput.WriteAsync(buffer, default(CancellationToken)).ContinueWith(onCompleted);
                    socketOutput.WriteAsync(buffer, default(CancellationToken)).ContinueWith(onCompleted2);

                    Assert.True(onWriteWh.Wait(1000));
                    completeQueue.Dequeue()(0);

                    // Assert
                    // Too many bytes are already pre-completed for the third but not the second write to pre-complete.
                    // https://github.com/aspnet/KestrelHttpServer/issues/356
                    Assert.True(completedWh.Wait(1000));
                    Assert.False(completedWh2.Wait(1000));

                    // Act
                    completeQueue.Dequeue()(0);

                    // Assert
                    // Finishing the first write should allow the second write to pre-complete.
                    Assert.True(completedWh2.Wait(1000));

                    // Cleanup
                    var cleanupTask = ((SocketOutput)socketOutput).WriteAsync(
                        default(ArraySegment <byte>), default(CancellationToken), socketDisconnect: true);

                    foreach (var triggerCompleted in completeQueue)
                    {
                        triggerCompleted(0);
                    }
                }
        }