private void UnrootedConnectionsGetRemovedFromHeartbeatInnerScope(
            string connectionId,
            ConnectionManager httpConnectionManager,
            Mock <IKestrelTrace> trace)
        {
            var serviceContext = new TestServiceContext();
            var mock           = new Mock <DefaultConnectionContext>()
            {
                CallBase = true
            };

            mock.Setup(m => m.ConnectionId).Returns(connectionId);
            var transportConnectionManager = new TransportConnectionManager(httpConnectionManager);
            var httpConnection             = new KestrelConnection <ConnectionContext>(0, serviceContext, transportConnectionManager, _ => Task.CompletedTask, mock.Object, Mock.Of <IKestrelTrace>());

            transportConnectionManager.AddConnection(0, httpConnection);

            var connectionCount = 0;

            httpConnectionManager.Walk(_ => connectionCount++);

            Assert.Equal(1, connectionCount);
            trace.Verify(t => t.ApplicationNeverCompleted(connectionId), Times.Never());

            // Ensure httpConnection doesn't get GC'd before this point.
            GC.KeepAlive(httpConnection);
        }
    public async Task OnConnectionFiresOnCompleted()
    {
        var serviceContext = new TestServiceContext();

        var connection = new Mock <DefaultConnectionContext> {
            CallBase = true
        }.Object;

        connection.ConnectionClosed = new CancellationToken(canceled: true);
        var transportConnectionManager = new TransportConnectionManager(serviceContext.ConnectionManager);
        var kestrelConnection          = new KestrelConnection <ConnectionContext>(0, serviceContext, transportConnectionManager, _ => Task.CompletedTask, connection, serviceContext.Log);

        transportConnectionManager.AddConnection(0, kestrelConnection);
        var completeFeature = kestrelConnection.TransportConnection.Features.Get <IConnectionCompleteFeature>();

        Assert.NotNull(completeFeature);
        object stateObject   = new object();
        object callbackState = null;

        completeFeature.OnCompleted(state => { callbackState = state; return(Task.CompletedTask); }, stateObject);

        await kestrelConnection.ExecuteAsync();

        Assert.Equal(stateObject, callbackState);
    }
    public async Task OnConnectionOnCompletedExceptionCaught()
    {
        var serviceContext = new TestServiceContext(LoggerFactory);
        var connection = new Mock <DefaultConnectionContext> {
            CallBase = true
        }.Object;

        connection.ConnectionClosed = new CancellationToken(canceled: true);
        var transportConnectionManager = new TransportConnectionManager(serviceContext.ConnectionManager);
        var kestrelConnection          = new KestrelConnection <ConnectionContext>(0, serviceContext, transportConnectionManager, _ => Task.CompletedTask, connection, serviceContext.Log);

        transportConnectionManager.AddConnection(0, kestrelConnection);
        var completeFeature = kestrelConnection.TransportConnection.Features.Get <IConnectionCompleteFeature>();

        Assert.NotNull(completeFeature);
        object stateObject   = new object();
        object callbackState = null;

        completeFeature.OnCompleted(state => { callbackState = state; throw new InvalidTimeZoneException(); }, stateObject);

        await kestrelConnection.ExecuteAsync();

        Assert.Equal(stateObject, callbackState);
        var errors = TestSink.Writes.Where(e => e.LogLevel >= LogLevel.Error).ToArray();

        Assert.Single(errors);
        Assert.Equal("An error occurred running an IConnectionCompleteFeature.OnCompleted callback.", errors[0].Message);
    }
 public ActiveTransport(IConnectionListenerBase transport, Task acceptLoopTask, TransportConnectionManager transportConnectionManager, EndpointConfig?endpointConfig = null)
 {
     ConnectionListener         = transport;
     AcceptLoopTask             = acceptLoopTask;
     TransportConnectionManager = transportConnectionManager;
     EndpointConfig             = endpointConfig;
 }
Example #5
0
    private void StartAcceptLoop <T>(IConnectionListener <T> connectionListener, Func <T, Task> connectionDelegate, EndpointConfig?endpointConfig) where T : BaseConnectionContext
    {
        var transportConnectionManager = new TransportConnectionManager(_serviceContext.ConnectionManager);
        var connectionDispatcher       = new ConnectionDispatcher <T>(_serviceContext, connectionDelegate, transportConnectionManager);
        var acceptLoopTask             = connectionDispatcher.StartAcceptingConnections(connectionListener);

        _transports.Add(new ActiveTransport(connectionListener, acceptLoopTask, transportConnectionManager, endpointConfig));
    }
Example #6
0
    public ConnectionReference(long id, KestrelConnection connection, TransportConnectionManager transportConnectionManager)
    {
        _id = id;

        _weakReference = new WeakReference <KestrelConnection>(connection);
        ConnectionId   = connection.TransportConnection.ConnectionId;

        _transportConnectionManager = transportConnectionManager;
    }
Example #7
0
 public KestrelConnection(long id,
                          ServiceContext serviceContext,
                          TransportConnectionManager transportConnectionManager,
                          Func <T, Task> connectionDelegate,
                          T connectionContext,
                          KestrelTrace logger)
     : base(id, serviceContext, transportConnectionManager, logger)
 {
     _connectionDelegate  = connectionDelegate;
     _transportConnection = connectionContext;
     connectionContext.Features.Set <IConnectionHeartbeatFeature>(this);
     connectionContext.Features.Set <IConnectionCompleteFeature>(this);
     connectionContext.Features.Set <IConnectionLifetimeNotificationFeature>(this);
 }
Example #8
0
        public async Task OneToTenThreads(int threadCount)
        {
            var listenOptions   = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
            var serviceContext  = new TestServiceContext();
            var testApplication = new DummyApplication(context =>
            {
                return(context.Response.WriteAsync("Hello World"));
            });

            listenOptions.UseHttpServer(serviceContext, testApplication, Core.HttpProtocols.Http1, addAltSvcHeader: false);

            var transportContext = new TestLibuvTransportContext
            {
#pragma warning disable CS0618
                Options = new LibuvTransportOptions {
                    ThreadCount = threadCount
                }
#pragma warning restore CS0618
            };

            await using var transport = new LibuvConnectionListener(transportContext, listenOptions.EndPoint);
            await transport.BindAsync();

            listenOptions.EndPoint = transport.EndPoint;

            var transportConnectionManager = new TransportConnectionManager(serviceContext.ConnectionManager);
            var dispatcher = new ConnectionDispatcher <ConnectionContext>(serviceContext, c => listenOptions.Build()(c), transportConnectionManager);
            var acceptTask = dispatcher.StartAcceptingConnections(new GenericConnectionListener(transport));

            using (var client = new HttpClient())
            {
                // Send 20 requests just to make sure we don't get any failures
                var requestTasks = new List <Task <string> >();
                for (int i = 0; i < 20; i++)
                {
                    var requestTask = client.GetStringAsync($"http://127.0.0.1:{listenOptions.IPEndPoint.Port}/");
                    requestTasks.Add(requestTask);
                }

                foreach (var result in await Task.WhenAll(requestTasks))
                {
                    Assert.Equal("Hello World", result);
                }
            }

            await transport.UnbindAsync();

            await acceptTask;

            if (!await transportConnectionManager.CloseAllConnectionsAsync(default))
        public async Task OnConnectionCreatesLogScopeWithConnectionId()
        {
            var serviceContext = new TestServiceContext();
            // This needs to run inline
            var tcs = new TaskCompletionSource();

            var connection = new Mock <DefaultConnectionContext> {
                CallBase = true
            }.Object;

            connection.ConnectionClosed = new CancellationToken(canceled: true);
            var transportConnectionManager = new TransportConnectionManager(serviceContext.ConnectionManager);
            var kestrelConnection          = new KestrelConnection <ConnectionContext>(0, serviceContext, transportConnectionManager, _ => tcs.Task, connection, serviceContext.Log);

            transportConnectionManager.AddConnection(0, kestrelConnection);

            var task = kestrelConnection.ExecuteAsync();

            // The scope should be created
            var scopeObjects = ((TestKestrelTrace)serviceContext.Log)
                               .Logger
                               .Scopes
                               .OfType <IReadOnlyList <KeyValuePair <string, object> > >()
                               .ToList();

            Assert.Single(scopeObjects);
            var pairs = scopeObjects[0].ToDictionary(p => p.Key, p => p.Value);

            Assert.True(pairs.ContainsKey("ConnectionId"));
            Assert.Equal(connection.ConnectionId, pairs["ConnectionId"]);

            tcs.TrySetResult();

            await task;

            // Verify the scope was disposed after request processing completed
            Assert.True(((TestKestrelTrace)serviceContext.Log).Logger.Scopes.IsEmpty);
        }
Example #10
0
 public ConnectionDispatcher(ServiceContext serviceContext, Func <T, Task> connectionDelegate, TransportConnectionManager transportConnectionManager)
 {
     _serviceContext             = serviceContext;
     _connectionDelegate         = connectionDelegate;
     _transportConnectionManager = transportConnectionManager;
 }