public void ReceivedHeartBeat(Address sender, TCPHearBeat hrtBeat) { Message rspMsg; switch (hrtBeat.Type) { case TCPHearBeat.HEART_BEAT: if (_enclosingInstance.Stack.NCacheLog.IsInfoEnabled) { _enclosingInstance.Stack.NCacheLog.Info("ConnectionKeepAlive.ReceivedHeartBeat", "received heartbeat from ->:" + sender.ToString()); } lock (_idleConnections.SyncRoot) { _idleConnections.Remove(sender); } break; case TCPHearBeat.SEND_HEART_BEAT: rspMsg = new Message(sender, null, new byte[0]); rspMsg.putHeader(HeaderType.KEEP_ALIVE, new TCPHearBeat(TCPHearBeat.HEART_BEAT)); if (_enclosingInstance.Stack.NCacheLog.IsInfoEnabled) { _enclosingInstance.Stack.NCacheLog.Info("ConnectionKeepAlive.ReceivedHeartBeat", "seding heartbeat to ->:" + sender.ToString()); } _enclosingInstance.sendUnicastMessage(rspMsg, false, rspMsg.Payload, Priority.High); break; case TCPHearBeat.ARE_YOU_ALIVE: rspMsg = new Message(sender, null, new byte[0]); TCPHearBeat rsphrtBeat = (_enclosingInstance.isClosing || _enclosingInstance._leaving) ? new TCPHearBeat(TCPHearBeat.I_AM_LEAVING) : new TCPHearBeat(TCPHearBeat.I_AM_NOT_DEAD); rsphrtBeat = _enclosingInstance.isStarting ? new TCPHearBeat(TCPHearBeat.I_AM_STARTING) : rsphrtBeat; rspMsg.putHeader(HeaderType.KEEP_ALIVE, rsphrtBeat); if (_enclosingInstance.Stack.NCacheLog.IsInfoEnabled) { _enclosingInstance.Stack.NCacheLog.Info("ConnectionKeepAlive.ReceivedHeartBeat", "seding status" + rsphrtBeat + " to ->:" + sender.ToString()); } _enclosingInstance.sendUnicastMessage(rspMsg, false, rspMsg.Payload, Priority.High); break; case TCPHearBeat.I_AM_STARTING: case TCPHearBeat.I_AM_LEAVING: case TCPHearBeat.I_AM_NOT_DEAD: lock (_status_mutex) { if (_currentSuspect != null && _currentSuspect.Equals(sender)) { _statusReceived = hrtBeat; Monitor.Pulse(_status_mutex); } } break; } }
/// <summary> /// Checks the status of a node whether he is running or not. We send a status request /// message and wait for the response for a particular timeout. If the node is alive /// it sends backs its status otherwise timeout occurs and we consider hime DEAD. /// </summary> private void CheckStatus() { while (_statusCheckingThread != null) { lock (_checkStatusList.SyncRoot) { if (_checkStatusList.Count > 0) { _currentSuspect = _checkStatusList[0] as Address; _checkStatusList.Remove(_currentSuspect); } else { _currentSuspect = null; } if (_currentSuspect == null) { _statusCheckingThread = null; continue; } } lock (_status_mutex) { try { NodeStatus nodeStatus = null; if (_enclosingInstance.ct.ConnectionExist(_currentSuspect)) { Message msg = new Message(_currentSuspect, null, new byte[0]); msg.putHeader(HeaderType.KEEP_ALIVE, new TCPHearBeat(TCPHearBeat.ARE_YOU_ALIVE)); if (_enclosingInstance.Stack.NCacheLog.IsInfoEnabled) { _enclosingInstance.Stack.NCacheLog.Info("ConnectionKeepAlive.CheckStatus", "sending status request to " + _currentSuspect); } _enclosingInstance.sendUnicastMessage(msg, false, msg.Payload, Priority.High); _statusReceived = null; //wait for the result or timeout occurs first; Monitor.Wait(_status_mutex, _statusTimeout); if (_statusReceived != null) { TCPHearBeat status = _statusReceived as TCPHearBeat; if (_enclosingInstance.Stack.NCacheLog.IsInfoEnabled) { _enclosingInstance.Stack.NCacheLog.Info("ConnectionKeepAlive.CheckStatus", "received status " + status + " from " + _currentSuspect); } if (status.Type == TCPHearBeat.I_AM_NOT_DEAD) { nodeStatus = new NodeStatus(_currentSuspect, NodeStatus.IS_ALIVE); } else if (status.Type == TCPHearBeat.I_AM_LEAVING) { nodeStatus = new NodeStatus(_currentSuspect, NodeStatus.IS_LEAVING); } else if (status.Type == TCPHearBeat.I_AM_STARTING) { nodeStatus = new NodeStatus(_currentSuspect, NodeStatus.IS_DEAD); } } else { nodeStatus = new NodeStatus(_currentSuspect, NodeStatus.IS_DEAD); if (_enclosingInstance.Stack.NCacheLog.IsInfoEnabled) { _enclosingInstance.Stack.NCacheLog.Info("ConnectionKeepAlive.CheckStatus", "did not receive status from " + _currentSuspect + "; consider him DEAD"); } } } else { if (_enclosingInstance.Stack.NCacheLog.IsInfoEnabled) { _enclosingInstance.Stack.NCacheLog.Info("ConnectionKeepAlive.CheckStatus", "no connection exists for " + _currentSuspect); } nodeStatus = new NodeStatus(_currentSuspect, NodeStatus.IS_DEAD); } Event statusEvent = new Event(Event.GET_NODE_STATUS_OK, nodeStatus); _enclosingInstance.passUp(statusEvent); } catch (Exception e) { _enclosingInstance.Stack.NCacheLog.Error("ConnectionKeepAlive.CheckStatus", e.ToString()); } finally { _currentSuspect = null; _statusReceived = null; } } } }