示例#1
0
文件: Node.cs 项目: chergey/mpapi
 public void PutMessage(MessageLevel messageLevel, ushort receiverNodeId, ushort receiverWorkerId,
                        ushort senderNodeId, ushort senderWorkerId, int messageType, object content)
 {
     //see if it is a local worker that is the receiver
     lock (_localWorkers)
     {
         //Message msg = new Message(messageLevel, new WorkerAddress(receiverNodeId, receiverWorkerId), new WorkerAddress(senderNodeId, senderWorkerId), messageType, content);
         if (WorkerAddress.IsBroadcastAddress(receiverNodeId, receiverWorkerId)) //broadcast address
         {
             foreach (var worker in _localWorkers.Values)
             {
                 worker.PutMessage(messageLevel, receiverNodeId, receiverWorkerId, senderNodeId, senderWorkerId,
                                   messageType, CloneContent(content)); //clone the message to prevent shared state
             }
         }
         else if (_localWorkers.ContainsKey(receiverWorkerId))
         {
             _localWorkers[receiverWorkerId].PutMessage(messageLevel, receiverNodeId, receiverWorkerId,
                                                        senderNodeId, senderWorkerId, messageType, CloneContent(content));
         }
         else if (!SystemMessages.IsSystemMessageType(messageType)) //we don't care about that
         {
             Log.Error("Node.PutMessage : Cannot dispatch message");
         }
     }
 }
示例#2
0
        /// <summary>
        /// This method handles the dispatching of messages in the send buffer.
        ///
        /// This is done in a separate thread so that local workers do not wait for each other,
        /// or wait for the relatively slow communication over the remoting framework.
        /// </summary>
        /// <param name="state"></param>
        private void SendBufferThreadProc(object state)
        {
            while (!SendBufferThreadTerminate)
            {
                _sendBufferWaitHandle.WaitOne();
                //fetch the first message
                Message msg = null;
                lock (_sendBuffer)
                {
                    LinkedListNode <Message> firstNode = _sendBuffer.First;
                    if (firstNode != null)
                    {
                        msg = firstNode.Value;
                        _sendBuffer.RemoveFirst();
                    }
                    else
                    {
                        _sendBufferWaitHandle.Reset();
                    }
                }

                /* Keep processing messages if there are any (no sleep - the thread
                 * will be switched out naturally), otherwise force the thread to be switched
                 * out of context. */
                if (msg != null)
                {
                    //is it a broad cast message?
                    if (WorkerAddress.IsBroadcastAddress(msg.ReceiverAddress))
                    {
                        //send it to all local workers (except the sender)
                        lock (_localWorkers)
                        {
                            foreach (Worker worker in _localWorkers.Values)
                            {
                                if (msg.SenderAddress.NodeId != _id || worker.Id != msg.SenderAddress.WorkerId)
                                {
                                    worker.PutMessage(msg.MessageLevel, msg.ReceiverAddress.NodeId, msg.ReceiverAddress.WorkerId, msg.SenderAddress.NodeId, msg.SenderAddress.WorkerId, msg.MessageType, CloneContent(msg.Content)); //clone to prevent shared state
                                }
                            }
                        }
                        //broadcast it to all remote nodes
                        lock (_remoteNodes)
                        {
                            foreach (INode remoteNode in _remoteNodes.Values)
                            {
                                remoteNode.PutMessage(msg.MessageLevel, msg.ReceiverAddress.NodeId, msg.ReceiverAddress.WorkerId, msg.SenderAddress.NodeId, msg.SenderAddress.WorkerId, msg.MessageType, msg.Content);
                            }
                        }
                    }
                    else if (msg.ReceiverAddress.NodeId == _id) //it is a local receiver
                    {
                        lock (_localWorkers)
                        {
                            if (_localWorkers.ContainsKey(msg.ReceiverAddress.WorkerId))
                            {
                                _localWorkers[msg.ReceiverAddress.WorkerId].PutMessage(msg.MessageLevel, msg.ReceiverAddress.NodeId, msg.ReceiverAddress.WorkerId, msg.SenderAddress.NodeId, msg.SenderAddress.WorkerId, msg.MessageType, CloneContent(msg.Content));
                            }
                        }
                    }
                    else //not a broadcast, not a local receiver, then find the remote node to send it to
                    {
                        lock (_remoteNodes)
                        {
                            ushort nodeId = msg.ReceiverAddress.NodeId;
                            if (_remoteNodes.ContainsKey(nodeId))
                            {
                                try
                                {
                                    _remoteNodes[nodeId].PutMessage(msg.MessageLevel, msg.ReceiverAddress.NodeId, msg.ReceiverAddress.WorkerId, msg.SenderAddress.NodeId, msg.SenderAddress.WorkerId, msg.MessageType, msg.Content);
                                }
                                catch (Exception)
                                {
                                    Log.Error("Node.SendBufferThreadProc : Remote node {0} appears to be offline", nodeId);
                                    _remoteNodes.Remove(nodeId);
                                    _registrationServerProxy.UnregisterNode(nodeId);
                                }
                            }
                        }
                    }
                }
            }
        }