Example #1
0
        /// <summary>
        /// Allows to send a message to receiver, by "hiding" the current node, this way all responce messages
        /// are targeted to the original sender (incl. responce of this message if it is request).
        /// This allows to implement a message proxy.
        /// </summary>
        /// <param name="receiverId"></param>
        /// <param name="message"></param>
        protected void ProxySend(ArbiterClientId receiverId, TransportMessage message)
        {
            TransportInfoUnit?info = message.TransportInfo.PopTransportInfo();

            if (info == null)
            {
                SystemMonitor.Error("Failed to establish message pending transport info.");
                return;
            }

            DoSendCustom(message.IsRequest, info.Value.Id, null, 0, receiverId, info.Value.SenderID, message, DefaultTimeOut);
        }
Example #2
0
        /// <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>
        /// Do not use this in normal circumstances, this is automatically assigned.
        /// Allows to assign element with an existing ID, in order to be recognized in existing paths after de-persistence.
        /// </summary>
        /// <param name="id"></param>
        public bool SetArbiterSubscriptionClientId(ArbiterClientId id)
        {
            if (_arbiter != null)
            {
                SystemMonitor.Error("CAn not assign arbiter subscription id, after item already added to arbiter.");
                return(false);
            }

            lock (this)
            {
                _subscriptionClientId = id;
            }

            return(true);
        }
Example #4
0
        /// <summary>
        /// Message received from the "Pipe".
        /// </summary>
        void _transport_MessageReceivedEvent(string operationContextSessionID, MessageContainer messageContainer)
        {
            TransportMessage message = (TransportMessage)messageContainer.CreateMessageInstance();

            TracerHelper.Trace("[" + message.GetType().Name + "], length [" + messageContainer.MessageStreamLength + "]");

            if (message.IsRequest)
            {     // Request requestMessage.
                { // Mark the request requestMessage with additional fragment in the transportation stack.
                    ArbiterClientId senderID = new ArbiterClientId("PipeChannelID", null, null);
                    senderID.SessionTag = operationContextSessionID;
                    message.TransportInfo.AddTransportInfoUnit(new TransportInfoUnit(Guid.NewGuid(), senderID, this.SubscriptionClientID));
                }

                if (MandatoryRequestMessageReceiverID.HasValue)
                {// There is a default receiver assigned for all messages from this integrator.
                    DoSendCustom(true, Guid.NewGuid(), null, 0, MandatoryRequestMessageReceiverID.Value, this.SubscriptionClientID, message, TimeSpan.Zero);
                }
                else
                {// No explicit mandatory receiver.
                    if (message.TransportInfo.ForwardTransportInfoCount > 0)
                    {
                        // First pop the Session stack, than send the cleared requestMessage.
                        ArbiterClientId?receiverID = message.TransportInfo.PopForwardTransportInfo();
                        DoSendCustom(true, Guid.NewGuid(), null, 0, receiverID, this.SubscriptionClientID, message, TimeSpan.Zero);
                    }
                    else
                    {
                        DoSendCustom(true, Guid.NewGuid(), null, 0, null, this.SubscriptionClientID, message, TimeSpan.Zero);
                    }
                }
            }
            else
            {// Responce requestMessage - send back to whoever sent it to us before.
                // And clear off the initial request information, we are responding now to.
                Guid            sessionID  = message.TransportInfo.CurrentTransportInfo.Value.Id;
                ArbiterClientId?receiverID = message.TransportInfo.CurrentTransportInfo.Value.SenderID;
                message.TransportInfo.PopTransportInfo();

                this.DoSendCustom(false, sessionID, null, 0,
                                  receiverID, this.SubscriptionClientID, message, TimeSpan.Zero);
            }
        }
Example #5
0
        /// <summary>
        /// Find out what clients need to receive this requestMessage.
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <returns></returns>
        public IEnumerable <ArbiterClientId> GatherMessageClients(Message message, ArbiterClientId senderID)
        {
            List <ArbiterClientId> clients = new List <ArbiterClientId>();

            if (_isDisposed)
            {// Possible to get disposed while operating here.
                return(null);
            }

            lock (_clientsAndFilters)
            {
                foreach (IArbiterClient client in _clientsAndFilters.Keys)
                {
                    if (_clientsAndFilters[client].MessageAllowed(message))
                    {
                        clients.Add(client.SubscriptionClientID);
                    }
                }
            }
            return(clients);
        }
Example #6
0
        ///// <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);
        }
        /// <summary>
        /// Entity execution has finished.
        /// </summary>
        public override void EntityExecutionFinished(ExecutionEntity entity)
        {
            ExecutionEntityWithReply entityWithReply = (ExecutionEntityWithReply)entity;

            if (entityWithReply.ReplyMessage != null)
            {// The other side replied.
                ArbiterClientId messageReceiver = ReceiverID;

                if (_receiverID.Equals(entity.ReceiverID))
                {// Swap direction, receiver must now send.
                    messageReceiver = SenderID;
                }

                ExecutionEntityWithReply replyEntity = new ExecutionEntityWithReply(this, messageReceiver, entityWithReply.TimeOut,
                                                                                    MessageContainer.DuplicateMessage(entityWithReply.ReplyMessage, false));

                ExecutionManager.AddExecutionEntity(replyEntity);
            }
            else
            {// We received a nothing, conversation done, die.
                this.Die();
            }
        }
Example #8
0
 /// <summary>
 ///
 /// </summary>
 public Message DirectCall(ArbiterClientId receiverID, TransportMessage message)
 {
     return(base.DirectCall(receiverID, message));
 }
Example #9
0
 /// <summary>
 ///
 /// </summary>
 protected void SendAddressed(ArbiterClientId receiverID, TransportMessage message)
 {
     DoSendCustom(true, Guid.NewGuid(), null, 0, receiverID, this.SubscriptionClientID, message, DefaultTimeOut);
 }
Example #10
0
 /// <summary>
 /// Allows to retrieve an instance of a client by its ID. Use with caution since it breaks the independence model
 /// and is applied only in special cases.
 /// </summary>
 public IArbiterClient GetClientByID(ArbiterClientId id)
 {
     return(GetClientByID(id, false));
 }
Example #11
0
 public ExecutionEntityWithReply(Conversation conversation, ArbiterClientId receiverID, TimeSpan timeOut, Message message)
     : base(conversation, receiverID, timeOut, message)
 {
 }
 /// <summary>
 /// Deserialization constructor.
 /// </summary>
 /// <param name="singleThreadOnly"></param>
 public ArbiterClientBase(SerializationInfo info, StreamingContext context)
 {
     _subscriptionClientId = (ArbiterClientId)info.GetValue("clientId", typeof(ArbiterClientId));
     _messageFilter        = (MessageFilter)info.GetValue("messageFilter", typeof(MessageFilter));
 }
Example #13
0
 /// <summary>
 ///
 /// </summary>
 public Conversation(ExecutionManager executionManager, ArbiterClientId ownerID, TimeSpan timeOut)
     : base(timeOut)
 {
     _ownerID          = ownerID;
     _executionManager = executionManager;
 }
 /// <summary>
 ///
 /// </summary>
 public TransportMessageFilter(ArbiterClientId ownerID) : base(true)
 {
     _ownerID = ownerID;
 }
Example #15
0
        ///
        /// </summary>
        public ConversationMultiPoint(ExecutionManager executionManager, Message message, ArbiterClientId senderID, IEnumerable <ArbiterClientId> receivers, TimeSpan timeOut)
            : base(executionManager, senderID, timeOut)
        {
            _receivers.AddRange(receivers);

            foreach (ArbiterClientId receiverID in receivers)
            {
                ExecutionEntity entity = new ExecutionEntity(this, receiverID, TimeSpan.Zero, MessageContainer.DuplicateMessage(message, false));
                _executingEntities.Add(entity);
                ExecutionManager.AddExecutionEntity(entity);
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        public ConversationPointToPoint(ExecutionManager executionManager, Message message, ArbiterClientId senderID, ArbiterClientId receiverID, TimeSpan timeOut)
            : base(executionManager, senderID, timeOut)
        {
            _receiverID = receiverID;

            ExecutionEntityWithReply entity = new ExecutionEntityWithReply(this, receiverID, timeOut,
                                                                           MessageContainer.DuplicateMessage(message, false));

            ExecutionManager.AddExecutionEntity(entity);
        }
 public TExpectedMessageClass SendAndReceiveAddressed <TExpectedMessageClass>(
     ArbiterClientId receiverID, TransportMessage message, TimeSpan timeOut)
     where TExpectedMessageClass : TransportMessage
 {
     return(base.SendAndReceiveAddressed <TExpectedMessageClass>(receiverID, message, timeOut));
 }
        ///// <summary>
        /////
        ///// </summary>
        //public Message DirectCall(ArbiterClientId receiverID, TransportMessage message)
        //{
        //    return base.DirectCall(receiverID, message);
        //}

        public new void SendAddressed(ArbiterClientId receiverID, TransportMessage message)
        {
            base.SendAddressed(receiverID, message);
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="receiver"></param>
 /// <param name="timeOut"></param>
 /// <param name="requestMessage"></param>
 public ExecutionEntity(IExecutor executor, ArbiterClientId receiverID, TimeSpan timeOut, Message message) : base(timeOut)
 {
     _executor = executor;
     _receiverID = receiverID;
     _message = message;
 }