Skip to content

Commit

Permalink
Use PooledContextFactory
Browse files Browse the repository at this point in the history
Also needs aspnet/HttpAbstractions#501 to be
real
  • Loading branch information
benaadams committed Dec 7, 2015
1 parent e742afb commit 8c7e97f
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
1 change: 0 additions & 1 deletion src/Benchmarks/DebugInfoPageMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public async Task Invoke(HttpContext httpContext)
await httpContext.Response.WriteAsync($"<li>Configuration: {_configurationName}</li>");
await httpContext.Response.WriteAsync($"<li>Server: {_hostingEnv.Configuration["server"]}</li>");
await httpContext.Response.WriteAsync($"<li>Server URLs: {_hostingEnv.Configuration["server.urls"]}</li>");
await httpContext.Response.WriteAsync($"<li>Supports Send File: {httpContext.Response.SupportsSendFile()}</li>");

await httpContext.Response.WriteAsync($"<li>Server features:<ul>");

Expand Down
74 changes: 74 additions & 0 deletions src/Benchmarks/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
// 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.Data.Common;
using System.Data.SqlClient;
using Benchmarks.Data;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Http.Internal;
using Microsoft.Data.Entity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -44,6 +47,7 @@ public void ConfigureServices(IServiceCollection services)
// No scenarios covered by the benchmarks require the HttpContextAccessor so we're replacing it with a
// no-op version to avoid the cost.
services.AddSingleton(typeof(IHttpContextAccessor), typeof(InertHttpContextAccessor));
services.AddSingleton(typeof(IHttpContextFactory), typeof(PooledContextFactory));

if (StartupOptions.EnableDbTests)
{
Expand Down Expand Up @@ -121,5 +125,75 @@ public class Options

public string ConnectionString { get; set; }
}

public class PooledContextFactory : IHttpContextFactory
{
private IHttpContextAccessor _httpContextAccessor;

[ThreadStatic]
Queue<DefaultHttpContext> _contextPool;

public PooledContextFactory() : this(httpContextAccessor: null)
{
}

public PooledContextFactory(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}

private Queue<DefaultHttpContext> ContextPool
{
get
{
if (_contextPool == null)
{
_contextPool = new Queue<DefaultHttpContext>(16);
}
return _contextPool;
}
}

public HttpContext Create(IFeatureCollection featureCollection)
{
var contextPool = ContextPool;
// locking as ThreadStatic didn't appear to be behaving thread safe via property on coreclr x64
lock (contextPool)
{
if (contextPool.Count > 0)
{
var context = contextPool.Dequeue();
// Needs https://github.com/aspnet/HttpAbstractions/pull/501
context.ReplaceFeatures(featureCollection);
return context;
}
}

return new DefaultHttpContext(featureCollection);
}

public void Dispose(HttpContext httpContext)
{
if (_httpContextAccessor != null)
{
_httpContextAccessor.HttpContext = null;
}

var context = httpContext as DefaultHttpContext;

if (context != null)
{
var contextPool = ContextPool;
// locking as ThreadStatic didn't appear to be behaving thread safe via property on coreclr x64
lock (contextPool)
{
if (contextPool.Count < 16)
{
contextPool.Enqueue(context);
}
}
}
}
}
}
}

0 comments on commit 8c7e97f

Please sign in to comment.