Skip to content

Commit 8c7e97f

Browse files
committed
Use PooledContextFactory
Also needs aspnet/HttpAbstractions#501 to be real
1 parent e742afb commit 8c7e97f

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

src/Benchmarks/DebugInfoPageMiddleware.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ public async Task Invoke(HttpContext httpContext)
4848
await httpContext.Response.WriteAsync($"<li>Configuration: {_configurationName}</li>");
4949
await httpContext.Response.WriteAsync($"<li>Server: {_hostingEnv.Configuration["server"]}</li>");
5050
await httpContext.Response.WriteAsync($"<li>Server URLs: {_hostingEnv.Configuration["server.urls"]}</li>");
51-
await httpContext.Response.WriteAsync($"<li>Supports Send File: {httpContext.Response.SupportsSendFile()}</li>");
5251

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

src/Benchmarks/Startup.cs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.Data.Common;
67
using System.Data.SqlClient;
78
using Benchmarks.Data;
89
using Microsoft.AspNet.Builder;
910
using Microsoft.AspNet.Hosting;
1011
using Microsoft.AspNet.Http;
12+
using Microsoft.AspNet.Http.Features;
13+
using Microsoft.AspNet.Http.Internal;
1114
using Microsoft.Data.Entity;
1215
using Microsoft.Extensions.Configuration;
1316
using Microsoft.Extensions.DependencyInjection;
@@ -44,6 +47,7 @@ public void ConfigureServices(IServiceCollection services)
4447
// No scenarios covered by the benchmarks require the HttpContextAccessor so we're replacing it with a
4548
// no-op version to avoid the cost.
4649
services.AddSingleton(typeof(IHttpContextAccessor), typeof(InertHttpContextAccessor));
50+
services.AddSingleton(typeof(IHttpContextFactory), typeof(PooledContextFactory));
4751

4852
if (StartupOptions.EnableDbTests)
4953
{
@@ -121,5 +125,75 @@ public class Options
121125

122126
public string ConnectionString { get; set; }
123127
}
128+
129+
public class PooledContextFactory : IHttpContextFactory
130+
{
131+
private IHttpContextAccessor _httpContextAccessor;
132+
133+
[ThreadStatic]
134+
Queue<DefaultHttpContext> _contextPool;
135+
136+
public PooledContextFactory() : this(httpContextAccessor: null)
137+
{
138+
}
139+
140+
public PooledContextFactory(IHttpContextAccessor httpContextAccessor)
141+
{
142+
_httpContextAccessor = httpContextAccessor;
143+
}
144+
145+
private Queue<DefaultHttpContext> ContextPool
146+
{
147+
get
148+
{
149+
if (_contextPool == null)
150+
{
151+
_contextPool = new Queue<DefaultHttpContext>(16);
152+
}
153+
return _contextPool;
154+
}
155+
}
156+
157+
public HttpContext Create(IFeatureCollection featureCollection)
158+
{
159+
var contextPool = ContextPool;
160+
// locking as ThreadStatic didn't appear to be behaving thread safe via property on coreclr x64
161+
lock (contextPool)
162+
{
163+
if (contextPool.Count > 0)
164+
{
165+
var context = contextPool.Dequeue();
166+
// Needs https://github.com/aspnet/HttpAbstractions/pull/501
167+
context.ReplaceFeatures(featureCollection);
168+
return context;
169+
}
170+
}
171+
172+
return new DefaultHttpContext(featureCollection);
173+
}
174+
175+
public void Dispose(HttpContext httpContext)
176+
{
177+
if (_httpContextAccessor != null)
178+
{
179+
_httpContextAccessor.HttpContext = null;
180+
}
181+
182+
var context = httpContext as DefaultHttpContext;
183+
184+
if (context != null)
185+
{
186+
var contextPool = ContextPool;
187+
// locking as ThreadStatic didn't appear to be behaving thread safe via property on coreclr x64
188+
lock (contextPool)
189+
{
190+
if (contextPool.Count < 16)
191+
{
192+
contextPool.Enqueue(context);
193+
}
194+
}
195+
}
196+
}
197+
}
124198
}
125199
}

0 commit comments

Comments
 (0)