/// <summary> /// Check capacity of SpanPool and allocate a new one if capacity is /// not sufficient. /// </summary> private Span <byte> GetSpan(int length) { if (_pool.Capacity < length) { _pool = new SpanPool <byte>(Math.Max(length * 2, _pool.Capacity * 2)); } return(_pool.GetSpan(length)); }
public bool HandleResponse() { if (!_outbox.CanPeek) { return(false); } var next = _outbox.Peek().Span; try { var message = new Message(next); var kind = message.Header.MessageKind; // Remove client ID from message message.Header.ClientId = default; if (_requestsInProgress >= ResponseBatchSize || _responseCountInPool > 0) { var nextResponse = _responsePool.GetSpan(next.Length); next.CopyTo(nextResponse); _responseCountInPool++; if (_responseCountInPool >= ResponseBatchSize) { _socket.Send(_responsePool.Allocated()); _responsePool.Reset(); _responseCountInPool = 0; } } else { _socket.Send(next); } Interlocked.Decrement(ref _requestsInProgress); // Some responses trigger the termination of the controller. if (kind == MessageKind.CloseConnectionResponse || kind == MessageKind.ProtocolErrorResponse) { if (kind == MessageKind.ProtocolErrorResponse) { var protocolResponse = new ProtocolErrorResponse(next); _log?.Log(LogSeverity.Info, $"ConnectionController({ClientId}) on protocol error {protocolResponse.Status}."); } if (_responseCountInPool > 0) { _socket.Send(_responsePool.Allocated()); _responsePool.Reset(); _responseCountInPool = 0; } _tokenSource.Cancel(); } } finally { _outbox.Next(); } return(true); }