Remove immediate parameter from Frame.ProduceStart

- Simply call SocketOutput.WriteAsync(_emptyData) to force headers to be flushed
This commit is contained in:
Stephen Halter 2016-01-25 11:02:24 -08:00
parent 7570da9daa
commit a4b8b01c99
2 changed files with 24 additions and 28 deletions

View File

@ -312,7 +312,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
} }
} }
await ProduceStartAndFireOnStarting(immediate: true); await ProduceStartAndFireOnStarting();
// Force flush
await SocketOutput.WriteAsync(_emptyData);
return DuplexStream; return DuplexStream;
} }

View File

@ -392,19 +392,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
public void Flush() public void Flush()
{ {
ProduceStartAndFireOnStarting(immediate: false).GetAwaiter().GetResult(); ProduceStartAndFireOnStarting().GetAwaiter().GetResult();
SocketOutput.Write(_emptyData); SocketOutput.Write(_emptyData);
} }
public async Task FlushAsync(CancellationToken cancellationToken) public async Task FlushAsync(CancellationToken cancellationToken)
{ {
await ProduceStartAndFireOnStarting(immediate: false); await ProduceStartAndFireOnStarting();
await SocketOutput.WriteAsync(_emptyData, cancellationToken: cancellationToken); await SocketOutput.WriteAsync(_emptyData, cancellationToken: cancellationToken);
} }
public void Write(ArraySegment<byte> data) public void Write(ArraySegment<byte> data)
{ {
ProduceStartAndFireOnStarting(immediate: false).GetAwaiter().GetResult(); ProduceStartAndFireOnStarting().GetAwaiter().GetResult();
if (_autoChunk) if (_autoChunk)
{ {
@ -443,7 +443,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
public async Task WriteAsyncAwaited(ArraySegment<byte> data, CancellationToken cancellationToken) public async Task WriteAsyncAwaited(ArraySegment<byte> data, CancellationToken cancellationToken)
{ {
await ProduceStartAndFireOnStarting(immediate: false); await ProduceStartAndFireOnStarting();
if (_autoChunk) if (_autoChunk)
{ {
@ -493,13 +493,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
} }
} }
public Task ProduceStartAndFireOnStarting(bool immediate) public Task ProduceStartAndFireOnStarting()
{ {
if (_responseStarted) return TaskUtilities.CompletedTask; if (_responseStarted) return TaskUtilities.CompletedTask;
if (_onStarting != null) if (_onStarting != null)
{ {
return FireOnStartingProduceStart(immediate); return ProduceStartAndFireOnStartingAwaited();
} }
if (_applicationException != null) if (_applicationException != null)
@ -509,10 +509,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
_applicationException); _applicationException);
} }
return ProduceStart(immediate, appCompleted: false); ProduceStart(appCompleted: false);
return TaskUtilities.CompletedTask;
} }
private async Task FireOnStartingProduceStart(bool immediate) private async Task ProduceStartAndFireOnStartingAwaited()
{ {
await FireOnStarting(); await FireOnStarting();
@ -523,17 +525,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
_applicationException); _applicationException);
} }
await ProduceStart(immediate, appCompleted: false); ProduceStart(appCompleted: false);
} }
private Task ProduceStart(bool immediate, bool appCompleted) private void ProduceStart(bool appCompleted)
{ {
if (_responseStarted) return TaskUtilities.CompletedTask; if (_responseStarted) return;
_responseStarted = true; _responseStarted = true;
var statusBytes = ReasonPhrases.ToStatusBytes(StatusCode, ReasonPhrase); var statusBytes = ReasonPhrases.ToStatusBytes(StatusCode, ReasonPhrase);
return CreateResponseHeader(statusBytes, appCompleted, immediate); CreateResponseHeader(statusBytes, appCompleted);
} }
protected Task ProduceEnd() protected Task ProduceEnd()
@ -556,7 +558,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
} }
} }
if (!_responseStarted) if (!_responseStarted)
{ {
return ProduceEndAwaited(); return ProduceEndAwaited();
@ -567,7 +568,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
private async Task ProduceEndAwaited() private async Task ProduceEndAwaited()
{ {
await ProduceStart(immediate: true, appCompleted: true); ProduceStart(appCompleted: true);
// Force flush
await SocketOutput.WriteAsync(_emptyData);
await WriteSuffix(); await WriteSuffix();
} }
@ -599,10 +603,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
} }
} }
private Task CreateResponseHeader( private void CreateResponseHeader(
byte[] statusBytes, byte[] statusBytes,
bool appCompleted, bool appCompleted)
bool immediate)
{ {
var end = SocketOutput.ProducingStart(); var end = SocketOutput.ProducingStart();
if (_keepAlive) if (_keepAlive)
@ -658,16 +661,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
end.CopyFrom(_bytesEndHeaders, 0, _bytesEndHeaders.Length); end.CopyFrom(_bytesEndHeaders, 0, _bytesEndHeaders.Length);
SocketOutput.ProducingComplete(end); SocketOutput.ProducingComplete(end);
if (immediate)
{
// Force a call to uv_write
return SocketOutput.WriteAsync(default(ArraySegment<byte>));
}
else
{
return TaskUtilities.CompletedTask;
}
} }
protected bool TakeStartLine(SocketInput input) protected bool TakeStartLine(SocketInput input)