MockConnection Abort
This commit is contained in:
parent
73bb0ab5b8
commit
a97cb81f92
|
|
@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Abort()
|
public virtual void Abort()
|
||||||
{
|
{
|
||||||
if (_frame != null)
|
if (_frame != null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
// The number of write operations that have been scheduled so far
|
// The number of write operations that have been scheduled so far
|
||||||
// but have not completed.
|
// but have not completed.
|
||||||
private bool _writePending = false;
|
private bool _writePending = false;
|
||||||
|
private bool _cancelled = false;
|
||||||
private int _numBytesPreCompleted = 0;
|
private int _numBytesPreCompleted = 0;
|
||||||
private Exception _lastWriteError;
|
private Exception _lastWriteError;
|
||||||
private WriteContext _nextWriteContext;
|
private WriteContext _nextWriteContext;
|
||||||
|
|
@ -90,7 +91,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
|
|
||||||
lock (_contextLock)
|
lock (_contextLock)
|
||||||
{
|
{
|
||||||
if (_lastWriteError != null || _socket.IsClosed)
|
if (_socket.IsClosed)
|
||||||
{
|
{
|
||||||
_log.ConnectionDisconnectedWrite(_connectionId, buffer.Count, _lastWriteError);
|
_log.ConnectionDisconnectedWrite(_connectionId, buffer.Count, _lastWriteError);
|
||||||
|
|
||||||
|
|
@ -164,7 +165,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
_connection.Abort();
|
_connection.Abort();
|
||||||
|
_cancelled = true;
|
||||||
return TaskUtilities.GetCancelledTask(cancellationToken);
|
return TaskUtilities.GetCancelledTask(cancellationToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -295,7 +296,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
// Abort the connection for any failed write
|
// Abort the connection for any failed write
|
||||||
// Queued on threadpool so get it in as first op.
|
// Queued on threadpool so get it in as first op.
|
||||||
_connection?.Abort();
|
_connection.Abort();
|
||||||
|
_cancelled = true;
|
||||||
|
|
||||||
CompleteAllWrites();
|
CompleteAllWrites();
|
||||||
}
|
}
|
||||||
|
|
@ -346,9 +348,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
// This may called on the libuv event loop
|
// This may called on the libuv event loop
|
||||||
// This is always called with the _contextLock already acquired
|
|
||||||
private void OnWriteCompleted(WriteContext writeContext)
|
private void OnWriteCompleted(WriteContext writeContext)
|
||||||
{
|
{
|
||||||
|
// Called inside _contextLock
|
||||||
var bytesWritten = writeContext.ByteCount;
|
var bytesWritten = writeContext.ByteCount;
|
||||||
var status = writeContext.WriteStatus;
|
var status = writeContext.WriteStatus;
|
||||||
var error = writeContext.WriteError;
|
var error = writeContext.WriteError;
|
||||||
|
|
@ -358,6 +360,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
// Abort the connection for any failed write
|
// Abort the connection for any failed write
|
||||||
// Queued on threadpool so get it in as first op.
|
// Queued on threadpool so get it in as first op.
|
||||||
_connection.Abort();
|
_connection.Abort();
|
||||||
|
_cancelled = true;
|
||||||
_lastWriteError = error;
|
_lastWriteError = error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -381,6 +384,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
|
|
||||||
private void CompleteNextWrite(ref int bytesLeftToBuffer)
|
private void CompleteNextWrite(ref int bytesLeftToBuffer)
|
||||||
{
|
{
|
||||||
|
// Called inside _contextLock
|
||||||
var waitingTask = _tasksPending.Dequeue();
|
var waitingTask = _tasksPending.Dequeue();
|
||||||
var bytesToWrite = waitingTask.BytesToWrite;
|
var bytesToWrite = waitingTask.BytesToWrite;
|
||||||
|
|
||||||
|
|
@ -416,6 +420,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
|
|
||||||
private void CompleteFinishedWrites(int status)
|
private void CompleteFinishedWrites(int status)
|
||||||
{
|
{
|
||||||
|
// Called inside _contextLock
|
||||||
// bytesLeftToBuffer can be greater than _maxBytesPreCompleted
|
// bytesLeftToBuffer can be greater than _maxBytesPreCompleted
|
||||||
// This allows large writes to complete once they've actually finished.
|
// This allows large writes to complete once they've actually finished.
|
||||||
var bytesLeftToBuffer = _maxBytesPreCompleted - _numBytesPreCompleted;
|
var bytesLeftToBuffer = _maxBytesPreCompleted - _numBytesPreCompleted;
|
||||||
|
|
@ -428,6 +433,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
|
|
||||||
private void CompleteAllWrites()
|
private void CompleteAllWrites()
|
||||||
{
|
{
|
||||||
|
// Called inside _contextLock
|
||||||
var writesToComplete = _tasksPending.Count > 0;
|
var writesToComplete = _tasksPending.Count > 0;
|
||||||
var bytesLeftToBuffer = _maxBytesPreCompleted - _numBytesPreCompleted;
|
var bytesLeftToBuffer = _maxBytesPreCompleted - _numBytesPreCompleted;
|
||||||
while (_tasksPending.Count > 0)
|
while (_tasksPending.Count > 0)
|
||||||
|
|
@ -468,7 +474,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
|
|
||||||
private void PoolWriteContext(WriteContext writeContext)
|
private void PoolWriteContext(WriteContext writeContext)
|
||||||
{
|
{
|
||||||
// called inside _contextLock
|
// Called inside _contextLock
|
||||||
if (_writeContextPool.Count < _maxPooledWriteContexts)
|
if (_writeContextPool.Count < _maxPooledWriteContexts)
|
||||||
{
|
{
|
||||||
writeContext.Reset();
|
writeContext.Reset();
|
||||||
|
|
@ -485,9 +491,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
_connection?.Abort();
|
_connection.Abort();
|
||||||
|
_cancelled = true;
|
||||||
return TaskUtilities.GetCancelledTask(cancellationToken);
|
return TaskUtilities.GetCancelledTask(cancellationToken);
|
||||||
}
|
}
|
||||||
|
else if (_cancelled)
|
||||||
|
{
|
||||||
|
return TaskUtilities.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
return WriteAsync(buffer, cancellationToken, immediate, chunk);
|
return WriteAsync(buffer, cancellationToken, immediate, chunk);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.KestrelTests.TestHelpers
|
||||||
|
{
|
||||||
|
public class MockConnection : Connection
|
||||||
|
{
|
||||||
|
public MockConnection(UvStreamHandle socket)
|
||||||
|
: base (new ListenerContext(), socket)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Abort()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -224,7 +224,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
var socket = new MockSocket(kestrelThread.Loop.ThreadId, new TestKestrelTrace());
|
var socket = new MockSocket(kestrelThread.Loop.ThreadId, new TestKestrelTrace());
|
||||||
var trace = new KestrelTrace(new TestKestrelTrace());
|
var trace = new KestrelTrace(new TestKestrelTrace());
|
||||||
var ltp = new LoggingThreadPool(trace);
|
var ltp = new LoggingThreadPool(trace);
|
||||||
ISocketOutput socketOutput = new SocketOutput(kestrelThread, socket, memory, null, 0, trace, ltp, new Queue<UvWriteReq>());
|
ISocketOutput socketOutput = new SocketOutput(kestrelThread, socket, memory, new MockConnection(socket), 0, trace, ltp, new Queue<UvWriteReq>());
|
||||||
|
|
||||||
var bufferSize = maxBytesPreCompleted;
|
var bufferSize = maxBytesPreCompleted;
|
||||||
|
|
||||||
|
|
@ -302,7 +302,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
Assert.False(task6Throw.IsCanceled);
|
Assert.False(task6Throw.IsCanceled);
|
||||||
Assert.False(task6Throw.IsFaulted);
|
Assert.False(task6Throw.IsFaulted);
|
||||||
|
|
||||||
Assert.Throws<TaskCanceledException>(() => task6Throw.GetAwaiter().GetResult());
|
task6Throw.GetAwaiter().GetResult();
|
||||||
|
|
||||||
Assert.True(true);
|
Assert.True(true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue