public async Task ResetsCountWhenConnectionClosed() { var requestTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); var releasedTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); var lockedTcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var counter = new EventRaisingResourceCounter(ResourceCounter.Quota(1)); counter.OnLock += (s, e) => lockedTcs.TrySetResult(e); counter.OnRelease += (s, e) => releasedTcs.TrySetResult(null); using (var server = CreateServerWithMaxConnections(async context => { await context.Response.WriteAsync("Hello"); await requestTcs.Task; }, counter)) using (var connection = server.CreateConnection()) { await connection.SendEmptyGetAsKeepAlive();; await connection.Receive("HTTP/1.1 200 OK"); Assert.True(await lockedTcs.Task.DefaultTimeout()); requestTcs.TrySetResult(null); } await releasedTcs.Task.DefaultTimeout(); }
private (TestServiceContext serviceContext, EventRaisingResourceCounter counter) SetupMaxConnections(long max) { var counter = new EventRaisingResourceCounter(ResourceCounter.Quota(max)); var serviceContext = new TestServiceContext(); serviceContext.ConnectionManager = new FrameConnectionManager(serviceContext.Log, counter, ResourceCounter.Unlimited); return(serviceContext, counter); }
public async Task ConnectionCountingReturnsToZero() { const int count = 100; var opened = 0; var closed = 0; var openedTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); var closedTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); var counter = new EventRaisingResourceCounter(ResourceCounter.Quota(uint.MaxValue)); counter.OnLock += (o, e) => { if (e && Interlocked.Increment(ref opened) >= count) { openedTcs.TrySetResult(null); } }; counter.OnRelease += (o, e) => { if (Interlocked.Increment(ref closed) >= count) { closedTcs.TrySetResult(null); } }; using (var server = CreateServerWithMaxConnections(_ => Task.CompletedTask, counter)) { // open a bunch of connections in parallel Parallel.For(0, count, async i => { try { using (var connection = server.CreateConnection()) { await connection.SendEmptyGetAsKeepAlive(); await connection.Receive("HTTP/1.1 200"); } } catch (Exception ex) { openedTcs.TrySetException(ex); } }); // wait until resource counter has called lock for each connection await openedTcs.Task.TimeoutAfter(TimeSpan.FromSeconds(120)); // wait until resource counter has released all normal connections await closedTcs.Task.TimeoutAfter(TimeSpan.FromSeconds(120)); Assert.Equal(count, opened); Assert.Equal(count, closed); await server.StopAsync(); } }