Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

Commit e177a28

Browse files
committed
Reduce revision amplication
1 parent e638979 commit e177a28

File tree

5 files changed

+46
-29
lines changed

5 files changed

+46
-29
lines changed

src/Microsoft.AspNetCore.Http.Features/FeatureReferences.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ public FeatureReferences(IFeatureCollection collection)
1515
Revision = collection.Revision;
1616
}
1717

18+
public FeatureReferences(IFeatureCollection collection, int featuresVersion)
19+
{
20+
Collection = collection;
21+
Cache = default(TCache);
22+
Revision = featuresVersion;
23+
}
24+
1825
public IFeatureCollection Collection { get; private set; }
1926
public int Revision { get; private set; }
2027

src/Microsoft.AspNetCore.Http/DefaultHttpContext.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,22 @@ public DefaultHttpContext()
4242

4343
public DefaultHttpContext(IFeatureCollection features)
4444
{
45-
_features = new FeatureReferences<FeatureInterfaces>(features);
46-
_request = new DefaultHttpRequest(this);
47-
_response = new DefaultHttpResponse(this);
45+
var featuresVersion = features.Revision;
46+
47+
// Speculatively populate always used features for current version
48+
_features = new FeatureReferences<FeatureInterfaces>(features, featuresVersion);
49+
_request = new DefaultHttpRequest(this, featuresVersion);
50+
_response = new DefaultHttpResponse(this, featuresVersion);
51+
}
52+
53+
public void Initialize(IFeatureCollection features)
54+
{
55+
var featuresVersion = features.Revision;
56+
57+
// Speculatively populate always used features for current version
58+
_features = new FeatureReferences<FeatureInterfaces>(features, featuresVersion);
59+
_request.Initialize(features, featuresVersion);
60+
_response.Initialize(features, featuresVersion);
4861
}
4962

5063
private IItemsFeature ItemsFeature =>
@@ -155,13 +168,6 @@ public override void Abort()
155168
[MethodImpl(MethodImplOptions.NoInlining)]
156169
private WebSocketManager InitializeWebSocketManager() => (_websockets = new DefaultWebSocketManager(Features));
157170

158-
public void Initialize(IFeatureCollection features)
159-
{
160-
_features = new FeatureReferences<FeatureInterfaces>(features);
161-
_request.Initialize(features);
162-
_response.Initialize(features);
163-
}
164-
165171
public void Uninitialize()
166172
{
167173
_features = default(FeatureReferences<FeatureInterfaces>);

src/Microsoft.AspNetCore.Http/Internal/DefaultHttpRequest.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@ public sealed class DefaultHttpRequest : HttpRequest
1818
private readonly static Func<HttpRequest, IFormFeature> _newFormFeature = r => new FormFeature(r);
1919
private readonly static Func<IFeatureCollection, IRequestCookiesFeature> _newRequestCookiesFeature = f => new RequestCookiesFeature(f);
2020

21-
private DefaultHttpContext _context;
21+
private readonly DefaultHttpContext _context;
2222
private FeatureReferences<FeatureInterfaces> _features;
2323

24-
public DefaultHttpRequest(DefaultHttpContext context)
24+
public DefaultHttpRequest(DefaultHttpContext context, int featuresVersion)
2525
{
2626
_context = context;
27-
_features = new FeatureReferences<FeatureInterfaces>(context.Features);
27+
Initialize(context.Features, featuresVersion);
28+
}
29+
30+
public void Initialize(IFeatureCollection features, int featuresVersion)
31+
{
32+
// Speculatively populate always used features for current version
33+
_features = new FeatureReferences<FeatureInterfaces>(features, featuresVersion);
2834
}
2935

3036
public override HttpContext HttpContext => _context;
@@ -140,11 +146,6 @@ public override Task<IFormCollection> ReadFormAsync(CancellationToken cancellati
140146
return FormFeature.ReadFormAsync(cancellationToken);
141147
}
142148

143-
public void Initialize(IFeatureCollection features)
144-
{
145-
_features = new FeatureReferences<FeatureInterfaces>(features);
146-
}
147-
148149
public void Uninitialize()
149150
{
150151
_features = default(FeatureReferences<FeatureInterfaces>);

src/Microsoft.AspNetCore.Http/Internal/DefaultHttpResponse.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,20 @@ public sealed class DefaultHttpResponse : HttpResponse
1515
private readonly static Func<IFeatureCollection, IHttpResponseFeature> _nullResponseFeature = f => null;
1616
private readonly static Func<IFeatureCollection, IResponseCookiesFeature> _newResponseCookiesFeature = f => new ResponseCookiesFeature(f);
1717

18-
private DefaultHttpContext _context;
18+
private readonly DefaultHttpContext _context;
1919
private FeatureReferences<FeatureInterfaces> _features;
2020

21-
public DefaultHttpResponse(DefaultHttpContext context)
21+
public DefaultHttpResponse(DefaultHttpContext context, int featuresVersion)
2222
{
2323
_context = context;
24-
_features = new FeatureReferences<FeatureInterfaces>(context.Features);
24+
Initialize(context.Features, featuresVersion);
25+
}
26+
27+
public void Initialize(IFeatureCollection features, int featuresVersion)
28+
{
29+
// Speculatively populate always used features for current version
30+
_features = new FeatureReferences<FeatureInterfaces>(features, featuresVersion);
31+
_features.Cache.Response = (IHttpResponseFeature)features[typeof(IHttpResponseFeature)];
2532
}
2633

2734
private IHttpResponseFeature HttpResponseFeature =>
@@ -119,11 +126,6 @@ public override void Redirect(string location, bool permanent)
119126
Headers[HeaderNames.Location] = location;
120127
}
121128

122-
public void Initialize(IFeatureCollection features)
123-
{
124-
_features = new FeatureReferences<FeatureInterfaces>(features);
125-
}
126-
127129
public void Uninitialize()
128130
{
129131
_features = default(FeatureReferences<FeatureInterfaces>);

test/Microsoft.AspNetCore.Http.Performance/DefaultContextBenchmark.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ public class DefaultContextBenchmark
1818

1919
private IHttpContextFactory _contextFactory;
2020
private IFeatureCollection _features;
21+
private int _featuresVersion;
2122
private HttpContext _context;
2223
private DefaultHttpResponse _responseDirect;
2324

2425
[Setup]
2526
public void Setup()
2627
{
2728
_features = CreateFeatureCollection();
28-
29+
_featuresVersion = _features.Revision;
2930
_contextFactory = new HttpContextFactory(new DefaultObjectPoolProvider(), Options.Create(new FormOptions()));
3031

3132
_context = _contextFactory.Create(_features);
@@ -74,7 +75,7 @@ public void GetResponseBodyUncached()
7475
for (var i = 0; i < InnerLoopCount; i++)
7576
{
7677
// Reset feature cache
77-
_responseDirect.Initialize(_features);
78+
_responseDirect.Initialize(_features, _featuresVersion);
7879
GetResponseBodyImpl();
7980
}
8081
}
@@ -94,7 +95,7 @@ public void GetContentLengthUncached()
9495
for (var i = 0; i < InnerLoopCount; i++)
9596
{
9697
// Reset feature cache
97-
_responseDirect.Initialize(_features);
98+
_responseDirect.Initialize(_features, _featuresVersion);
9899
GetContentLengthImpl();
99100
}
100101
}

0 commit comments

Comments
 (0)