/// <summary> /// Retrieves the next message for writing from the queue. /// </summary> /// <param name="length"></param> /// <returns></returns> public byte[] TakePendingWrite(out int length) { BlockingQueue <PendingMethodCall> pendingWrites = _pendingWrites; if (pendingWrites == null) { throw new OperationCanceledException(_endPointName); } PendingMethodCall message = pendingWrites.Dequeue(); PendingMethodsEventSource.Instance.Dequeued(_endPointName, message.RpcId); PendingMethodsEventSource.Instance.QueueCountChanged(_endPointName, pendingWrites.Count); return(message.GetMessage(out length)); }
/// <summary> /// Shall be called once a pending call has been completely handled. /// </summary> /// <param name="methodCall"></param> public void Recycle(PendingMethodCall methodCall) { lock (_syncRoot) { var id = methodCall.RpcId; if (Log.IsDebugEnabled) { Log.DebugFormat("Removing method call '#{0}'...", id); } _pendingCalls.Remove(id); if (Log.IsDebugEnabled) { Log.DebugFormat("Method call '#{0}' removed", id); } // We do not want to recycle thousands of messages because that can require // lots of memory ("big" messages may take 1Mb of memory or even more). // Therefore we limit the amount to a constant value (for now). // In the future, we might want to limit the amount of used memory instead? if (_recycledMessages.Count < MaxNumRecycledCalls) { Log.Debug("Recycling method call object..."); _recycledMessages.Enqueue(methodCall); if (Log.IsDebugEnabled) { Log.DebugFormat("Method call object recycled, {0} objects available for re-use", _recycledMessages.Count); } } else { Log.DebugFormat("Method call object won't be recycled: We're keeping enough alive already!"); } } }