// Called with lock(this) private void MarkConnectionReady(NotHttpConnection connection, bool sacrificeWaiter) { if (requestWaiters.Count == 0) { idleConnections.Push(connection); } else { RequestWaiter waiter = requestWaiters.First(); Exception exception = connection.AssignRequest(waiter.request); if (exception == null) { requestWaiters.RemoveFirst(); // Run this asynchronously outside the lock Task.Run(() => waiter.task.SetResult(connection)); } else { if (sacrificeWaiter) { // give the waiter the connection even if it's faulted. // we do this on a failed open so that the client will see // the error rather than just perpetually retrying the open requestWaiters.RemoveFirst(); // do this asynchronously outside the lock Task.Run(() => waiter.task.SetException(new ApplicationException("Stream open failure", exception))); } --openedConnections; logger.Log("Removing faulted connection, " + openedConnections + " remaining: " + exception.Message); ReOpenConnections(); } } }
public async Task <NotHttpConnection> WaitForRequestSlot(NHClientRequest caller) { Task <NotHttpConnection> blockTask = null; lock (this) { // this is where we garbage collection connections that are faulted, so // go through the idle connections throwing them away if they // aren't good until we match one while (blockTask == null && idleConnections.Count > 0) { NotHttpConnection connection = idleConnections.Pop(); Exception exception = connection.AssignRequest(caller); if (exception == null) { blockTask = Task.FromResult(connection); } else { --openedConnections; logger.Log("Removing faulted connection, " + openedConnections + " remaining: " + exception.Message); } } if (blockTask == null) { RequestWaiter waiter = new RequestWaiter(caller); requestWaiters.AddLast(waiter); blockTask = waiter.task.Task; } ReOpenConnections(); } return(await blockTask); }
protected Task <TReturn> SendRequestAndReceive <TReturn>(RequestMessage requestMessage) { return(RequestWaiter.SendRequestAndReceive <TReturn>(Target, requestMessage, Timeout)); }
protected Task SendRequestAndWait(RequestMessage requestMessage) { return(RequestWaiter.SendRequestAndWait(Target, requestMessage, Timeout)); }
// Request & Response protected void SendRequest(RequestMessage requestMessage) { RequestWaiter.SendRequest(Target, requestMessage); }
protected Task <NetDataBufferReader> SendRequestAndReceive(NetDataWriter writer) { return(RequestWaiter.SendRequestAndReceive(Target, writer, Timeout, DeliveryMethod, Extra)); }
protected Task SendRequestAndWait(NetDataWriter writer) { return(RequestWaiter.SendRequestAndWait(Target, writer, Timeout, DeliveryMethod, Extra)); }
protected void SendRequest( NetDataWriter writer) { RequestWaiter.SendRequest(Target, writer, DeliveryMethod, DeliveryTarget, Extra); }