From a4b8b01c997bf9da8854743ae8d9b994fbc7f2c4 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Mon, 25 Jan 2016 11:02:24 -0800 Subject: [PATCH] Remove immediate parameter from Frame.ProduceStart - Simply call SocketOutput.WriteAsync(_emptyData) to force headers to be flushed --- .../Http/Frame.FeatureCollection.cs | 5 +- .../Http/Frame.cs | 47 ++++++++----------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.FeatureCollection.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.FeatureCollection.cs index 8a10a7c618..f93f88915d 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.FeatureCollection.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.FeatureCollection.cs @@ -312,7 +312,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http } } - await ProduceStartAndFireOnStarting(immediate: true); + await ProduceStartAndFireOnStarting(); + + // Force flush + await SocketOutput.WriteAsync(_emptyData); return DuplexStream; } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs index 4c1d096e6f..7272329639 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs @@ -392,19 +392,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http public void Flush() { - ProduceStartAndFireOnStarting(immediate: false).GetAwaiter().GetResult(); + ProduceStartAndFireOnStarting().GetAwaiter().GetResult(); SocketOutput.Write(_emptyData); } public async Task FlushAsync(CancellationToken cancellationToken) { - await ProduceStartAndFireOnStarting(immediate: false); + await ProduceStartAndFireOnStarting(); await SocketOutput.WriteAsync(_emptyData, cancellationToken: cancellationToken); } public void Write(ArraySegment data) { - ProduceStartAndFireOnStarting(immediate: false).GetAwaiter().GetResult(); + ProduceStartAndFireOnStarting().GetAwaiter().GetResult(); if (_autoChunk) { @@ -443,7 +443,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http public async Task WriteAsyncAwaited(ArraySegment data, CancellationToken cancellationToken) { - await ProduceStartAndFireOnStarting(immediate: false); + await ProduceStartAndFireOnStarting(); 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 (_onStarting != null) { - return FireOnStartingProduceStart(immediate); + return ProduceStartAndFireOnStartingAwaited(); } if (_applicationException != null) @@ -509,10 +509,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http _applicationException); } - return ProduceStart(immediate, appCompleted: false); + ProduceStart(appCompleted: false); + + return TaskUtilities.CompletedTask; } - private async Task FireOnStartingProduceStart(bool immediate) + private async Task ProduceStartAndFireOnStartingAwaited() { await FireOnStarting(); @@ -523,17 +525,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http _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; var statusBytes = ReasonPhrases.ToStatusBytes(StatusCode, ReasonPhrase); - return CreateResponseHeader(statusBytes, appCompleted, immediate); + CreateResponseHeader(statusBytes, appCompleted); } protected Task ProduceEnd() @@ -556,7 +558,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http } } - if (!_responseStarted) { return ProduceEndAwaited(); @@ -567,7 +568,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http private async Task ProduceEndAwaited() { - await ProduceStart(immediate: true, appCompleted: true); + ProduceStart(appCompleted: true); + + // Force flush + await SocketOutput.WriteAsync(_emptyData); await WriteSuffix(); } @@ -599,10 +603,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http } } - private Task CreateResponseHeader( + private void CreateResponseHeader( byte[] statusBytes, - bool appCompleted, - bool immediate) + bool appCompleted) { var end = SocketOutput.ProducingStart(); if (_keepAlive) @@ -658,16 +661,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http end.CopyFrom(_bytesEndHeaders, 0, _bytesEndHeaders.Length); SocketOutput.ProducingComplete(end); - - if (immediate) - { - // Force a call to uv_write - return SocketOutput.WriteAsync(default(ArraySegment)); - } - else - { - return TaskUtilities.CompletedTask; - } } protected bool TakeStartLine(SocketInput input)