-
Notifications
You must be signed in to change notification settings - Fork 523
Conversation
|
||
public void ResumeStreams() | ||
{ | ||
_frameStreams.ResponseBody.ResumeAcceptingWrites(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this is ordered differently than Pause and Stop :) (Response/Request here, vs Request/Response on the others.)
if (((_bits & 1099511627776L) != 0)) _UserAgent = default(StringValues); | ||
if (((_bits & 2199023255552L) != 0)) _Origin = default(StringValues); | ||
if (((_bits & 4398046511104L) != 0)) _AccessControlRequestMethod = default(StringValues); | ||
if (((_bits & 8796093022208L) != 0)) _AccessControlRequestHeaders = default(StringValues); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any evidence this is faster than simply resetting all the fields without checking which bits are set like we did before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could do it in one statement by putting them in a struct and doing _headers = default(Headers)
Hey @benaadams, while you're at it... #628 |
{ | ||
RequestHeaders = null; | ||
ResponseHeaders = null; | ||
var frameHeaders = _frameHeaders; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this pattern is really achieving anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is to detect double call; also to drop references that have been returned to pool
176d1ea
to
abfe29a
Compare
abfe29a
to
7bb5e07
Compare
@@ -35,7 +36,7 @@ public ValueTask<int> ReadAsync(ArraySegment<byte> buffer, CancellationToken can | |||
return result; | |||
} | |||
|
|||
public async Task Consume(CancellationToken cancellationToken = default(CancellationToken)) | |||
public Task Consume(CancellationToken cancellationToken = default(CancellationToken)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be in this set
7bb5e07
to
460dbb1
Compare
Need to look at clearing methods
|
Update description with measurements |
aa49c75
to
b473402
Compare
Added fast header clear. Note: Also you will need to switch on some pooling for high perf as headers now are created and dropped per request rather than per connection. |
So with the inner struct clearing out all the header strings in ClearFast isn't much il IL_0009: ldflda valuetype HeaderReferences FrameRequestHeaders::_headers
IL_000e: initobj HeaderReferences Full function .method family hidebysig virtual instance void
ClearFast() cil managed
{
// Code size 37 (0x25)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.0
IL_0002: conv.i8
IL_0003: stfld int64 Microsoft.AspNetCore.Server.Kestrel.Http.FrameRequestHeaders::_bits
IL_0008: ldarg.0
IL_0009: ldflda valuetype Microsoft.AspNetCore.Server.Kestrel.Http.FrameRequestHeaders/HeaderReferences Microsoft.AspNetCore.Server.Kestrel.Http.FrameRequestHeaders::_headers
IL_000e: initobj Microsoft.AspNetCore.Server.Kestrel.Http.FrameRequestHeaders/HeaderReferences
IL_0014: ldarg.0
IL_0015: ldfld class [System.Collections]System.Collections.Generic.Dictionary`2<string,valuetype [Microsoft.Extensions.Primitives]Microsoft.Extensions.Primitives.StringValues> Microsoft.AspNetCore.Server.Kestrel.Http.FrameHeaders::MaybeUnknown
IL_001a: dup
IL_001b: brtrue.s IL_001f
IL_001d: pop
IL_001e: ret
IL_001f: call instance void class [System.Collections]System.Collections.Generic.Dictionary`2<string,valuetype [Microsoft.Extensions.Primitives]Microsoft.Extensions.Primitives.StringValues>::Clear()
IL_0024: ret
} // end of method FrameRequestHeaders::ClearFast |
🚢 |
_frameHeaders = HttpComponentFactory.CreateHeaders(DateHeaderValueManager); | ||
RequestHeaders = _frameHeaders.RequestHeaders; | ||
ResponseHeaders = _frameHeaders.ResponseHeaders; | ||
return this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't return this
. I don't see you using this anywhere anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, don't worry about this. I changed it while addressing my own PR feedback readying a merge.
For common header values (non-dictionary backed ones)
IHttpComponentFactory
controls header and stream creation, disposalHttpComponentFactory
implementation pools the headers, and streamsif
kestrel.maxPooledStreams > 0
||kestrel.maxPooledHeaders > 0
Faster cycling of header objects should cause the Response header values to remain in Gen0 as they are likely to be reset to a new value on each request.
Request values are reset if they have been set
Streams are uninitialized and reinitialized with frame reference so as not to prolong its lifetime.
Also doesn't hold onto header collections or stream objects while the Frame is in a keep-alive wait.
Resolves #607
Resolves #628
Resolves #629 when set > 0
Before:

With this change, setting
After memory is down by 1.4GB, headers have moved out of the top spots


And instead appear quite far down