Don't use a GUID for request ID because it's slow:
- FastHttpRequestIdentifierFeature uses an incrementing long with an int seed - Everything is lazy so no computer incurred if ID is not asked for - Optimized routine to stringify the ID - #306
This commit is contained in:
parent
1ef8474be2
commit
7441855c34
|
|
@ -0,0 +1,60 @@
|
|||
// 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.Threading;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
|
||||
namespace Microsoft.AspNet.Hosting.Internal
|
||||
{
|
||||
public class FastHttpRequestIdentifierFeature : IHttpRequestIdentifierFeature
|
||||
{
|
||||
private static readonly string _hexChars = "0123456789ABCDEF";
|
||||
// Seed the _requestId for this application instance with a random int
|
||||
private static long _requestId = new Random().Next();
|
||||
|
||||
private string _id = null;
|
||||
|
||||
public string TraceIdentifier
|
||||
{
|
||||
get
|
||||
{
|
||||
// Don't incur the cost of generating the request ID until it's asked for
|
||||
if (_id == null)
|
||||
{
|
||||
_id = GenerateRequestId(Interlocked.Increment(ref _requestId));
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
_id = value;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GenerateRequestId(long id)
|
||||
{
|
||||
// The following routine is ~33% faster than calling long.ToString() when testing in tight loops of
|
||||
// 1 million iterations.
|
||||
var charBuffer = new char[sizeof(long) * 2];
|
||||
charBuffer[0] = _hexChars[(int)(id >> 60) & 0x0f];
|
||||
charBuffer[1] = _hexChars[(int)(id >> 56) & 0x0f];
|
||||
charBuffer[2] = _hexChars[(int)(id >> 52) & 0x0f];
|
||||
charBuffer[3] = _hexChars[(int)(id >> 48) & 0x0f];
|
||||
charBuffer[4] = _hexChars[(int)(id >> 44) & 0x0f];
|
||||
charBuffer[5] = _hexChars[(int)(id >> 40) & 0x0f];
|
||||
charBuffer[6] = _hexChars[(int)(id >> 36) & 0x0f];
|
||||
charBuffer[7] = _hexChars[(int)(id >> 32) & 0x0f];
|
||||
charBuffer[8] = _hexChars[(int)(id >> 28) & 0x0f];
|
||||
charBuffer[9] = _hexChars[(int)(id >> 24) & 0x0f];
|
||||
charBuffer[10] = _hexChars[(int)(id >> 20) & 0x0f];
|
||||
charBuffer[11] = _hexChars[(int)(id >> 16) & 0x0f];
|
||||
charBuffer[12] = _hexChars[(int)(id >> 12) & 0x0f];
|
||||
charBuffer[13] = _hexChars[(int)(id >> 8) & 0x0f];
|
||||
charBuffer[14] = _hexChars[(int)(id >> 4) & 0x0f];
|
||||
charBuffer[15] = _hexChars[(int)(id >> 0) & 0x0f];
|
||||
|
||||
return new string(charBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,6 @@ using Microsoft.AspNet.Hosting.Server;
|
|||
using Microsoft.AspNet.Hosting.Startup;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Http.Features.Internal;
|
||||
using Microsoft.AspNet.Server.Features;
|
||||
using Microsoft.Dnx.Runtime;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
|
@ -278,10 +277,7 @@ namespace Microsoft.AspNet.Hosting.Internal
|
|||
var requestIdentifierFeature = httpContext.Features.Get<IHttpRequestIdentifierFeature>();
|
||||
if (requestIdentifierFeature == null)
|
||||
{
|
||||
requestIdentifierFeature = new HttpRequestIdentifierFeature()
|
||||
{
|
||||
TraceIdentifier = Guid.NewGuid().ToString()
|
||||
};
|
||||
requestIdentifierFeature = new FastHttpRequestIdentifierFeature();
|
||||
httpContext.Features.Set(requestIdentifierFeature);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ namespace Microsoft.AspNet.Hosting
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(httpContext);
|
||||
Assert.IsType<HttpRequestIdentifierFeature>(httpContext.Features.Get<IHttpRequestIdentifierFeature>());
|
||||
Assert.IsType<FastHttpRequestIdentifierFeature>(httpContext.Features.Get<IHttpRequestIdentifierFeature>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -328,7 +328,7 @@ namespace Microsoft.AspNet.Hosting
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(httpContext);
|
||||
Assert.IsType<HttpRequestIdentifierFeature>(httpContext.Features.Get<IHttpRequestIdentifierFeature>());
|
||||
Assert.IsType<FastHttpRequestIdentifierFeature>(httpContext.Features.Get<IHttpRequestIdentifierFeature>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
// 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.AspNet.Hosting.Internal;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Hosting.Tests.Internal
|
||||
{
|
||||
public class FastHttpRequestIdentifierFeatureTests
|
||||
{
|
||||
[Fact]
|
||||
public void TraceIdentifier_ReturnsId()
|
||||
{
|
||||
var feature = new FastHttpRequestIdentifierFeature();
|
||||
|
||||
var id = feature.TraceIdentifier;
|
||||
|
||||
Assert.NotNull(id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TraceIdentifier_ReturnsStableId()
|
||||
{
|
||||
var feature = new FastHttpRequestIdentifierFeature();
|
||||
|
||||
var id1 = feature.TraceIdentifier;
|
||||
var id2 = feature.TraceIdentifier;
|
||||
|
||||
Assert.Equal(id1, id2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TraceIdentifier_ReturnsUniqueIdForDifferentInstances()
|
||||
{
|
||||
var feature1 = new FastHttpRequestIdentifierFeature();
|
||||
var feature2 = new FastHttpRequestIdentifierFeature();
|
||||
|
||||
var id1 = feature1.TraceIdentifier;
|
||||
var id2 = feature2.TraceIdentifier;
|
||||
|
||||
Assert.NotEqual(id1, id2);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue