示例#1
0
 /// <summary>
 /// This method is called by the framework
 /// </summary>
 internal void _Main()
 {
     RegisterWorker(this);
     try
     {
         Main();
         if (_monitoringWorker != null)
         {
             Message msg = new Message(MessageLevel.System, _monitoringWorker, new WorkerAddress(_node.GetId(), _id), SystemMessages.WorkerTerminated, null);
             _node.QueueMessage(msg);
         }
         OnWorkerTerminated();
     }
     catch (Exception e)
     {
         WorkerAddress workerAddress = new WorkerAddress(_node.GetId(), _id);
         Log.Error("Worker {0} crashed with exception {1}", workerAddress, e.Message);
         if (_monitoringWorker != null)
         {
             Message msg = new Message(MessageLevel.System, _monitoringWorker, workerAddress, SystemMessages.WorkerTerminatedAbnormally, e);
             _node.QueueMessage(msg);
         }
         OnWorkerTerminatedAbnormally(e);
     }
     _node.WorkerTerminated(_id);
     UnregisterWorker();
 }
示例#2
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");
         }
     }
 }
示例#3
0
        /// <summary>
        /// Fetches a message from the message queue with the specified sender address and message type.
        /// This method blocks until there are any messages fullfilling the criteria.
        /// </summary>
        /// <param name="senderAddress">The sender address.</param>
        /// <param name="messageType">The message type.</param>
        /// <returns>The first message in the queue with the specified sender address and message type</returns>
        public Message Receive(WorkerAddress senderAddress, int messageType)
        {
            Message msg = null;
            LinkedListNode <Message> msgNode;

            do
            {
                _messageQueueWaitHandle.WaitOne();
                lock (_messageQueue)
                {
                    msgNode = _messageQueue.First;
                    //traverse all messages to see if there are any that matches the search criteria
                    while (msgNode != null && msg == null)
                    {
                        if (msgNode.Value.SenderAddress == senderAddress && msgNode.Value.MessageType == messageType)
                        {
                            msg = msgNode.Value;
                            _messageQueue.Remove(msgNode);
                        }
                        else
                        {
                            msgNode = msgNode.Next;
                        }
                    }
                    if (msg == null) //nothing yet
                    {
                        _messageQueueWaitHandle.Reset();
                    }
                }
            }while (msg == null);
            return(msg);
        }
示例#4
0
 internal void _Monitor(WorkerAddress monitor, WorkerAddress monitoree)
 {
     if (monitoree.NodeId == _id)
     {
         Monitor(monitor, monitoree);
     }
     else
     {
         lock (_remoteNodes)
         {
             ushort monitoreeNodeId = monitoree.NodeId;
             if (_remoteNodes.ContainsKey(monitoreeNodeId))
             {
                 try
                 {
                     _remoteNodes[monitoree.NodeId].Monitor(monitor, monitoree);
                 }
                 catch (Exception)
                 {
                     Log.Error("Node._Monitor({0}, {1}) : Remote node {2} appears to be offline", monitor, monitoree, monitoree.NodeId);
                     _remoteNodes.Remove(monitoreeNodeId);
                     _registrationServerProxy.UnregisterNode(monitoreeNodeId);
                 }
             }
             else
             {
                 Log.Error("Node._Monitor({0}, {1}) : Unable to find remote monitoree", monitor, monitoree);
             }
         }
     }
 }
示例#5
0
 public Message(MessageLevel messageLevel, WorkerAddress receiverAddress, WorkerAddress senderAddress, int messageType, object content)
 {
     _messageLevel    = messageLevel;
     _receiverAddress = receiverAddress;
     _senderAddress   = senderAddress;
     _messageType     = messageType;
     _content         = content;
 }
示例#6
0
 public Message(MessageLevel messageLevel, WorkerAddress receiverAddress, WorkerAddress senderAddress,
                int messageType, object content)
 {
     MessageLevel    = messageLevel;
     ReceiverAddress = receiverAddress;
     SenderAddress   = senderAddress;
     MessageType     = messageType;
     Content         = content;
 }
示例#7
0
        /// <summary>
        /// Spawns a new worker at the specified node.
        /// </summary>
        /// <param name="workerTypeName">Fully qualified name of worker type. Must inherit from Worker.</param>
        /// <param name="nodeId">Id of the node to spawn the worker at.</param>
        /// <returns>The address of the new worker if successfull, otherwise null.</returns>
        public WorkerAddress Spawn(string workerTypeName, ushort nodeId)
        {
            WorkerAddress workerAddress = null;

            if (_node.Spawn(workerTypeName, nodeId, out ushort workerId))
            {
                workerAddress = new WorkerAddress(nodeId, workerId);
            }
            return(workerAddress);
        }
示例#8
0
        /// <summary>
        /// Spawns a new worker at the specified node.
        /// </summary>
        /// <typeparam name="TWorkerType">The type of worker to spawn. Must inherit from Worker.</typeparam>
        /// <param name="nodeId">Id of the node to spawn the worker at.</param>
        /// <returns>The address of the new worker if successfull, otherwise null.</returns>
        public WorkerAddress Spawn <TWorkerType>(ushort nodeId) where TWorkerType : Worker
        {
            WorkerAddress workerAddress = null;

            if (_node.Spawn(typeof(TWorkerType), nodeId, out ushort workerId))
            {
                workerAddress = new WorkerAddress(nodeId, workerId);
            }
            return(workerAddress);
        }
示例#9
0
        /// <summary>
        /// Spawns a new worker locally.
        /// </summary>
        /// <typeparam name="TWorkerType">The type of worker to spawn. Must inherit from Worker.</typeparam>
        /// <returns>The address of the new worker if successfull, otherwise null.</returns>
        public WorkerAddress Spawn <TWorkerType>() where TWorkerType : Worker
        {
            ushort        workerId;
            WorkerAddress workerAddress = null;

            if (_node.Spawn(typeof(TWorkerType), out workerId))
            {
                workerAddress = new WorkerAddress(_node.GetId(), workerId);
            }
            return(workerAddress);
        }
示例#10
0
        /// <summary>
        /// Sends a message.
        /// </summary>
        /// <param name="receiverAddress">Address of the receicer.</param>
        /// <param name="messageType">Type of message - user specific.</param>
        /// <param name="content">The contents of the message.</param>
        public void Send(WorkerAddress receiverAddress, int messageType, object content)
        {
            if (SystemMessages.IsSystemMessageType(messageType))
            {
                Log.Error("Message types smaller than 0 are reserved for system messages. Message type : {0}", messageType);
                return;
            }
            Message msg = new Message(MessageLevel.User, receiverAddress, new WorkerAddress(_node.GetId(), _id), messageType, content);

            _node.QueueMessage(msg);
        }
示例#11
0
 /// <summary>
 /// Checks if there are any message from the specified sender and with the specified message type in the message queue.
 /// </summary>
 /// <param name="senderAddress"></param>
 /// <param name="messageType"></param>
 /// <returns></returns>
 public bool HasMessages(WorkerAddress senderAddress, int messageType)
 {
     lock (_messageQueue)
     {
         foreach (Message msg in _messageQueue)
         {
             if (msg.SenderAddress == senderAddress && msg.MessageType == messageType)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
示例#12
0
 public void Monitor(WorkerAddress monitor, WorkerAddress monitoree)
 {
     if (monitoree.NodeId == _id)
     {
         lock (_localWorkers)
         {
             if (_localWorkers.ContainsKey(monitoree.WorkerId))
             {
                 _localWorkers[monitoree.WorkerId].SetMonitoringWorker(monitor);
             }
             else
             {
                 Log.Error("Node.Monitor({0}, {1}) : unable to find monitoree", monitor, monitoree);
             }
         }
     }
 }
示例#13
0
 internal void SetMonitoringWorker(WorkerAddress monitoringWorker)
 {
     _monitoringWorker = monitoringWorker;
 }
示例#14
0
 public void Monitor(WorkerAddress monitor, WorkerAddress monitoree)
 {
     Proxy.Monitor(monitor, monitoree);
 }
示例#15
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);
                                }
                            }
                        }
                    }
                }
            }
        }
示例#16
0
 public static bool IsBroadcastAddress(WorkerAddress address)
 {
     return(address.NodeId == ushort.MaxValue && address.WorkerId == ushort.MaxValue);
 }
示例#17
0
 /// <summary>
 /// Enables this worker to receive system messages when the monitoree terminates, either
 /// normally or abnormally.
 /// </summary>
 /// <param name="monitoree"></param>
 public void Monitor(WorkerAddress monitoree)
 {
     _node._Monitor(new WorkerAddress(_node.GetId(), _id), monitoree);
 }