Remove the RequestId from DefaultConnectionContext (#516)

* Remove the RequestId from DefaultConnectionContext
- Added a GetHttpContext() extension method on ConnectionContext
- Also fixed an issue not setting LastSeenUtc
This commit is contained in:
David Fowler 2017-06-03 22:05:44 -10:00 committed by GitHub
parent 7de91da37d
commit 831fa72893
7 changed files with 44 additions and 35 deletions

View File

@ -1,4 +1,7 @@
using Microsoft.AspNetCore.Sockets; // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Sockets;
namespace Microsoft.AspNetCore.SignalR namespace Microsoft.AspNetCore.SignalR
{ {

View File

@ -20,15 +20,13 @@ namespace Microsoft.AspNetCore.Sockets
Transport = transport; Transport = transport;
Application = application; Application = application;
ConnectionId = id; ConnectionId = id;
LastSeenUtc = DateTime.UtcNow;
} }
public CancellationTokenSource Cancellation { get; set; } public CancellationTokenSource Cancellation { get; set; }
public SemaphoreSlim Lock { get; } = new SemaphoreSlim(1, 1); public SemaphoreSlim Lock { get; } = new SemaphoreSlim(1, 1);
// REVIEW: This should only be on the Http implementation
public string RequestId { get; set; }
public Task TransportTask { get; set; } public Task TransportTask { get; set; }
public Task ApplicationTask { get; set; } public Task ApplicationTask { get; set; }
@ -65,8 +63,6 @@ namespace Microsoft.AspNetCore.Sockets
{ {
Status = ConnectionStatus.Disposed; Status = ConnectionStatus.Disposed;
RequestId = null;
// If the application task is faulted, propagate the error to the transport // If the application task is faulted, propagate the error to the transport
if (ApplicationTask?.IsFaulted == true) if (ApplicationTask?.IsFaulted == true)
{ {

View File

@ -0,0 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Sockets
{
public static class HttpConnectionContextExtensions
{
public static HttpContext GetHttpContext(this ConnectionContext connection)
{
return connection.Metadata.Get<HttpContext>(ConnectionMetadataNames.HttpContext);
}
}
}

View File

@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Sockets
if (connection.Status == DefaultConnectionContext.ConnectionStatus.Active) if (connection.Status == DefaultConnectionContext.ConnectionStatus.Active)
{ {
_logger.LogDebug("Connection {connectionId} is already active via {requestId}. Cancelling previous request.", connection.ConnectionId, connection.RequestId); _logger.LogDebug("Connection {connectionId} is already active via {requestId}. Cancelling previous request.", connection.ConnectionId, connection.GetHttpContext().TraceIdentifier);
using (connection.Cancellation) using (connection.Cancellation)
{ {
@ -158,20 +158,17 @@ namespace Microsoft.AspNetCore.Sockets
// Should be a cancelled task // Should be a cancelled task
} }
_logger.LogDebug("Previous poll cancelled for {connectionId} on {requestId}.", connection.ConnectionId, connection.RequestId); _logger.LogDebug("Previous poll cancelled for {connectionId} on {requestId}.", connection.ConnectionId, connection.GetHttpContext().TraceIdentifier);
} }
} }
// Mark the request identifier
connection.RequestId = context.TraceIdentifier;
// Mark the connection as active // Mark the connection as active
connection.Status = DefaultConnectionContext.ConnectionStatus.Active; connection.Status = DefaultConnectionContext.ConnectionStatus.Active;
// Raise OnConnected for new connections only since polls happen all the time // Raise OnConnected for new connections only since polls happen all the time
if (connection.ApplicationTask == null) if (connection.ApplicationTask == null)
{ {
_logger.LogDebug("Establishing new connection: {connectionId} on {requestId}", connection.ConnectionId, connection.RequestId); _logger.LogDebug("Establishing new connection: {connectionId} on {requestId}", connection.ConnectionId, connection.GetHttpContext().TraceIdentifier);
connection.Metadata[ConnectionMetadataNames.Transport] = TransportType.LongPolling; connection.Metadata[ConnectionMetadataNames.Transport] = TransportType.LongPolling;
@ -179,7 +176,7 @@ namespace Microsoft.AspNetCore.Sockets
} }
else else
{ {
_logger.LogDebug("Resuming existing connection: {connectionId} on {requestId}", connection.ConnectionId, connection.RequestId); _logger.LogDebug("Resuming existing connection: {connectionId} on {requestId}", connection.ConnectionId, connection.GetHttpContext().TraceIdentifier);
} }
var longPolling = new LongPollingTransport(connection.Application.Input, _loggerFactory); var longPolling = new LongPollingTransport(connection.Application.Input, _loggerFactory);
@ -241,7 +238,7 @@ namespace Microsoft.AspNetCore.Sockets
connection.Status = DefaultConnectionContext.ConnectionStatus.Inactive; connection.Status = DefaultConnectionContext.ConnectionStatus.Inactive;
connection.RequestId = null; connection.Metadata[ConnectionMetadataNames.HttpContext] = null;
// Dispose the cancellation token // Dispose the cancellation token
connection.Cancellation.Dispose(); connection.Cancellation.Dispose();
@ -257,16 +254,6 @@ namespace Microsoft.AspNetCore.Sockets
} }
} }
private DefaultConnectionContext CreateConnection(HttpContext context)
{
var connection = _manager.CreateConnection();
var format = (string)context.Request.Query[ConnectionMetadataNames.Format];
connection.User = context.User;
connection.Metadata[ConnectionMetadataNames.HttpContext] = context;
connection.Metadata[ConnectionMetadataNames.Format] = string.IsNullOrEmpty(format) ? "json" : format;
return connection;
}
private async Task DoPersistentConnection(SocketDelegate socketDelegate, private async Task DoPersistentConnection(SocketDelegate socketDelegate,
IHttpTransport transport, IHttpTransport transport,
HttpContext context, HttpContext context,
@ -288,7 +275,7 @@ namespace Microsoft.AspNetCore.Sockets
// There's already an active request // There's already an active request
if (connection.Status == DefaultConnectionContext.ConnectionStatus.Active) if (connection.Status == DefaultConnectionContext.ConnectionStatus.Active)
{ {
_logger.LogDebug("Connection {connectionId} is already active via {requestId}.", connection.ConnectionId, connection.RequestId); _logger.LogDebug("Connection {connectionId} is already active via {requestId}.", connection.ConnectionId, connection.GetHttpContext().TraceIdentifier);
// Reject the request with a 409 conflict // Reject the request with a 409 conflict
context.Response.StatusCode = StatusCodes.Status409Conflict; context.Response.StatusCode = StatusCodes.Status409Conflict;
@ -298,9 +285,6 @@ namespace Microsoft.AspNetCore.Sockets
// Mark the connection as active // Mark the connection as active
connection.Status = DefaultConnectionContext.ConnectionStatus.Active; connection.Status = DefaultConnectionContext.ConnectionStatus.Active;
// Store the request identifier
connection.RequestId = context.TraceIdentifier;
// Call into the end point passing the connection // Call into the end point passing the connection
connection.ApplicationTask = ExecuteApplication(socketDelegate, connection); connection.ApplicationTask = ExecuteApplication(socketDelegate, connection);
@ -336,7 +320,7 @@ namespace Microsoft.AspNetCore.Sockets
context.Response.ContentType = "text/plain"; context.Response.ContentType = "text/plain";
// Establish the connection // Establish the connection
var connection = CreateConnection(context); var connection = _manager.CreateConnection();
// Get the bytes for the connection id // Get the bytes for the connection id
var connectionIdBuffer = Encoding.UTF8.GetBytes(connection.ConnectionId); var connectionIdBuffer = Encoding.UTF8.GetBytes(connection.ConnectionId);
@ -407,8 +391,6 @@ namespace Microsoft.AspNetCore.Sockets
return false; return false;
} }
connection.User = context.User;
var transport = connection.Metadata.Get<TransportType?>(ConnectionMetadataNames.Transport); var transport = connection.Metadata.Get<TransportType?>(ConnectionMetadataNames.Transport);
if (transport == null) if (transport == null)
@ -421,6 +403,13 @@ namespace Microsoft.AspNetCore.Sockets
await context.Response.WriteAsync("Cannot change transports mid-connection"); await context.Response.WriteAsync("Cannot change transports mid-connection");
return false; return false;
} }
// Setup the connection state from the http context
var format = (string)context.Request.Query[ConnectionMetadataNames.Format];
connection.User = context.User;
connection.Metadata[ConnectionMetadataNames.HttpContext] = context;
connection.Metadata[ConnectionMetadataNames.Format] = string.IsNullOrEmpty(format) ? "json" : format;
return true; return true;
} }
@ -455,7 +444,7 @@ namespace Microsoft.AspNetCore.Sockets
// There's no connection id so this is a brand new connection // There's no connection id so this is a brand new connection
if (StringValues.IsNullOrEmpty(connectionId)) if (StringValues.IsNullOrEmpty(connectionId))
{ {
connection = CreateConnection(context); connection = _manager.CreateConnection();
} }
else if (!_manager.TryGetConnection(connectionId, out connection)) else if (!_manager.TryGetConnection(connectionId, out connection))
{ {

View File

@ -1,4 +1,7 @@
using System; // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
namespace Microsoft.AspNetCore.Sockets namespace Microsoft.AspNetCore.Sockets

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
Assert.Null(connection.ApplicationTask); Assert.Null(connection.ApplicationTask);
Assert.Null(connection.TransportTask); Assert.Null(connection.TransportTask);
Assert.Null(connection.Cancellation); Assert.Null(connection.Cancellation);
Assert.Null(connection.RequestId); Assert.NotEqual(default(DateTime), connection.LastSeenUtc);
Assert.NotNull(connection.Transport); Assert.NotNull(connection.Transport);
} }

View File

@ -458,7 +458,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
await task; await task;
Assert.Equal(DefaultConnectionContext.ConnectionStatus.Inactive, connection.Status); Assert.Equal(DefaultConnectionContext.ConnectionStatus.Inactive, connection.Status);
Assert.Null(connection.RequestId); Assert.Null(connection.GetHttpContext());
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode); Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
} }