/// <summary> /// Put the node into the pending work queue. /// </summary> /// <param name="node"></param> public void NeedsIO(INode node) { LogTo.Trace($"Node {node} is requeued for IO"); ioQueue.Add(node); }
private void TryProcessReceivedData() { // process the commands in the readQueue while (readQueue.Count > 0) { // continue filling the previously unfinished response, // or create a new one var response = inprogressResponse ?? CreateResponse(); // continue filling the Response object from the buffer // Read() returns true if further data (IO) is required // (usually when the current response data is larger than the receive buffer size) if (response.Read(socket.ReadBuffer)) { inprogressResponse = response; LogTo.Trace("Response is not read fully, continue reading from the socket."); // refill the buffer _FinishedReading(); owner.NeedsIO(this); return; } // successfully read a response from the read buffer inprogressResponse = null; var isHandled = false; while (!isHandled && readQueue.Count > 0) { var data = readQueue.Peek(); Debug.Assert(!data.IsEmpty); // If the response does not matches the current op, it means it's a // response to a later command in the queue, so all commands before it // were silent commands without a response (== usually success). // So, successful silent ops will receive null as response (since // we have no real response (or we've ran into a bug)) isHandled = data.Op.Handles(response); LogTo.Trace($"Command {data.Op} handles reponse: {isHandled}"); // operations are allowed to hanndle subsequent responses // they returns false when no more IO (response) is required => done processing if (!data.Op.ProcessResponse(isHandled ? response : null)) { readQueue.Dequeue(); data.Task.TrySetResult(data.Op); #region Diagnostics npm.DequeueReadOp(); CoreEventSource.DequeueReadOp(name); #endregion } } response.Dispose(); } LogTo.Trace($"{name} fininshed RECEIVE, unlock read"); _FinishedReading(); }