/// <summary> /// /// </summary> /// <param name="entity"></param> public void AddExecutionEntity(ExecutionEntity entity) { TracerHelper.TraceEntry(); lock (this) { if (_pendingEntities.Count > _maxPendingExecutionItems) { TracerHelper.TraceError("Too many pending entities in system. Some older entities are being dropped."); if ((DateTime.Now - _maxPendingItemsWarningShownTime) > _warningsTimeSpan) { _maxPendingItemsWarningShownTime = DateTime.Now; SystemMonitor.Error("Too many pending entities in system. Some older entities are being dropped."); } // Loose the oldest entity in line. _timeOutMonitor.RemoveEntity(_pendingEntities[0]); _pendingEntities.RemoveAt(0); } _timeOutMonitor.AddEntity(entity); _pendingEntities.Add(entity); } // Continue execution chain. UpdatePendingExecution(); }
///// <summary> ///// The direct call allows to circumvent the many steps (incl serialization) of typical message sending ///// and make a direct call to another Arbiter member; thus making a much faster delivery. This path ///// has a maximum optimization for speed, so tracing etc. are disabled. ///// ///// Also this mechanism only works for TransportClients currently. ///// ///// The mechanism does not utilize any new threads, and the execution is performed on the calling thread. ///// ///// Direct calls can only be made to participants on the same arbiter, and no addressing is applied ///// for the messages. ///// </summary> //public Message DirectCall(ArbiterClientId senderID, ArbiterClientId receiverID, Message message) //{ // IArbiterClient receiver = GetClientByID(receiverID, true); // if (receiver == null || receiver is TransportClient == false) // { // SystemMonitor.OperationWarning("Sender [" + senderID.Id.Print() + "] creating conversation message [" + message.GetType().Name + " ] by not present receiver [" + receiverID.Id.Print() + "] or receiver not a TransportClient"); // return null; // } // Message response = receiver.ReceiveDirectCall(message); // return response; //} /// <summary> /// Will send a point to point requestMessage and start a conversation that can have many replies. /// </summary> public ConversationPointToPoint CreateConversation(ArbiterClientId senderID, ArbiterClientId receiverID, Message message, TimeSpan timeout) { SystemMonitor.CheckError(((TransportMessage)message).TransportInfo.CurrentTransportInfo != null); if (message is TransportMessage) { SystemMonitor.CheckError(((TransportMessage)message).TransportInfo.CurrentTransportInfo != null); TracerHelper.Trace("sender[" + senderID.Id.Name + "], receiver [" + receiverID.Id.Name + "], message [" + message.GetType().Name + "] [" + ((TransportMessage)message).TransportInfo.TransportInfoCount + "]"); } else { TracerHelper.Trace("sender[" + senderID.Id.Name + "], message [" + message.GetType().Name + "]"); } if (GetClientByID(senderID, false) == null) { SystemMonitor.Error("Creating conversation from a not present sender [" + message.GetType().Name + ", " + senderID.Id.Print() + "]."); return(null); } if (GetClientByID(receiverID, false) == null) { SystemMonitor.OperationWarning("Sender [" + senderID.Id.Print() + "] creating conversation message [" + message.GetType().Name + " ] by not present receiver [" + receiverID.Id.Print() + "]"); return(null); } ConversationPointToPoint conversation = new ConversationPointToPoint(_executionManager, message, senderID, receiverID, timeout); if (_isDisposed) {// Possible to get disposed while operating here. return(null); } lock (_timeOutMonitor) { _timeOutMonitor.AddEntity(conversation); } return(conversation); }