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; }
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)); }
public ConnectionReference(long id, KestrelConnection connection, TransportConnectionManager transportConnectionManager) { _id = id; _weakReference = new WeakReference <KestrelConnection>(connection); ConnectionId = connection.TransportConnection.ConnectionId; _transportConnectionManager = transportConnectionManager; }
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); }
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); }
public ConnectionDispatcher(ServiceContext serviceContext, Func <T, Task> connectionDelegate, TransportConnectionManager transportConnectionManager) { _serviceContext = serviceContext; _connectionDelegate = connectionDelegate; _transportConnectionManager = transportConnectionManager; }