public override void up(Event evt) { switch (evt.Type) { case Event.VIEW_CHANGE: if (is_member) // pass the view change up if we are already a member of the group break; System.Collections.ArrayList new_members = ((View) evt.Arg).Members; if (new_members == null || new_members.Count == 0) break; if (local_addr == null) { Stack.NCacheLog.Error("VIEW_ENFORCER.up(VIEW_CHANGE): local address is null; cannot check " + "whether I'm a member of the group; discarding view change"); return ; } if (new_members.Contains(local_addr)) is_member = true; else return ; break; case Event.SET_LOCAL_ADDRESS: local_addr = (Address) evt.Arg; break; case Event.MSG: if (!is_member) { // drop message if we are not yet member of the group Stack.NCacheLog.Info("dropping message " + evt.Arg); return ; } Message msg = evt.Arg as Message; if (msg != null && msg.HandledAysnc) { System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(AsyncPassUp), evt); return; } break; } passUp(evt); // Pass up to the layer above us }
/// <summary> Send the bcast request with the given localSeqID /// /// </summary> /// <param name="seqID">the local sequence id of the /// </param> private void _transmitBcastRequest(long seqID) { Message reqMsg; // i. If NULL_STATE, then ignore, just transient state before // shutting down the retransmission thread // ii. If blocked, be patient - reschedule // iii. If the request is not pending any more, acknowledge it // iv. Create a broadcast request and send it to the sequencer if (state == NULL_STATE) { if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("Transmit BCAST_REQ[" + seqID + "] in NULL_STATE"); return; } if (state == BLOCK) return; request_lock.AcquireReaderLock(Timeout.Infinite); try { if (!reqTbl.Contains((long)seqID)) { retransmitter.ack(seqID); return; } } finally { request_lock.ReleaseReaderLock(); } reqMsg = new Message(); reqMsg.Dest = sequencerAddr; reqMsg.Src = addr; reqMsg.setBuffer(new byte[0]); HDR hdr = new HDR(); hdr.type = HDR.REQ; hdr.localSeqID = seqID; hdr.seqID = NULL_ID; reqMsg.putHeader(HeaderType.TOTAL, hdr); reqMsg.IsUserMsg = true; reqMsg.Type = MsgType.TOKEN_SEEKING; Event evt = new Event(); evt.Type = Event.MSG; evt.Arg = reqMsg; passDown(evt); }
public override bool handleUpEvent(Event evt) { ArrayList tmp; switch (evt.Type) { case Event.FIND_INITIAL_MBRS_OK: tmp = (ArrayList)evt.Arg; lock (initial_mbrs.SyncRoot) { if (tmp != null && tmp.Count > 0) for (int i = 0; i < tmp.Count; i++) initial_mbrs.Add(tmp[i]); initial_mbrs_received = true; System.Threading.Monitor.Pulse(initial_mbrs.SyncRoot); } return false; // don't pass up the stack } return true; }
/// <summary> /// Sends a configuration event on the channel of the cluster. /// </summary> /// <param name="configurationEvent"></param> public void ConfigureLocalCluster(Event configurationEvent) { if (_channel != null) _channel.down(configurationEvent); }
public override void up(Event evt) { Message msg, rsp_msg; System.Object obj; PingHeader hdr, rsp_hdr; PingRsp rsp; Address coord; switch (evt.Type) { case Event.MSG: msg = (Message) evt.Arg; obj = msg.getHeader(HeaderType.TCPPING); if (obj == null || !(obj is PingHeader)) { passUp(evt); return ; } hdr = (PingHeader)msg.removeHeader(HeaderType.TCPPING); switch (hdr.type) { case PingHeader.GET_MBRS_REQ: if( !hdr.group_addr.Equals(group_addr)) { if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TcpPing.up()", "GET_MBRS_REQ from different group , so discarded"); return; } Address src = (Address) hdr.arg; msg.Src = src; if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCPPING.up()", "GET_MBRS_REQ from " + msg.Src.ToString()); lock (members.SyncRoot) { coord = members.Count > 0 ? (Address)members[0] : local_addr; } if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCPPING.up()", "my coordinator is " + coord.ToString()); rsp_msg = new Message(msg.Src, null, null); rsp_hdr = new PingHeader(PingHeader.GET_MBRS_RSP, new PingRsp(local_addr, coord, Stack.IsOperational,Stack.IsOperational)); rsp_msg.putHeader(HeaderType.TCPPING, rsp_hdr); if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCPPING.up()", "responding to GET_MBRS_REQ back to " + msg.Src.ToString()); if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info(local_addr + " - [FIND_INITIAL_MBRS] replying PING request to " + rsp_msg.Dest); passDown(new Event(Event.MSG, rsp_msg, Priority.Critical)); return ; case PingHeader.GET_MBRS_RSP: // add response to vector and notify waiting thread if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCPPING.up()", "GET_MBRS_RSP from " + msg.Src.ToString()); rsp = (PingRsp) hdr.arg; //muds: //check if the received response is valid i.e. successful security authorization //at other end. if (rsp.OwnAddress == null && rsp.CoordAddress == null && rsp.HasJoined == false) { lock (initial_members.SyncRoot) { if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCPPING.up()", "I am not authorized to join to " + msg.Src.ToString()); System.Threading.Monitor.PulseAll(initial_members.SyncRoot); } } else { if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCPPING.up()", "Before Adding initial members response"); lock (initial_members.SyncRoot) { if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCPPING.up()", "Adding initial members response"); if (!initial_members.Contains(rsp)) { initial_members.Add(rsp); if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCPPING.up()", "Adding initial members response for " + rsp.OwnAddress); } else if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TcpPing.up()", "response already received"); System.Threading.Monitor.PulseAll(initial_members.SyncRoot); } } return ; default: Stack.NCacheLog.Warn("got TCPPING header with unknown type (" + hdr.type + ')'); return ; } //goto case Event.SET_LOCAL_ADDRESS; case Event.SET_LOCAL_ADDRESS: passUp(evt); local_addr = (Address) evt.Arg; // Add own address to initial_hosts if not present: we must always be able to ping ourself ! if (initial_hosts != null && local_addr != null) { if (!initial_hosts.Contains(local_addr)) { Stack.NCacheLog.Debug("[SET_LOCAL_ADDRESS]: adding my own address (" + local_addr + ") to initial_hosts; initial_hosts=" + Global.CollectionToString(initial_hosts)); initial_hosts.Add(local_addr); } } break; case Event.CONNECT_OK: obj = evt.Arg; if(obj != null && obj is Address) { tcpServerPort = ((Address)obj).Port; } passUp(evt); break; case Event.CONNECTION_NOT_OPENED: if (mbrDiscoveryInProcess) { Address node = evt.Arg as Address; PingRsp response = new PingRsp(node, node, true, false); lock (initial_members.SyncRoot) { initial_members.Add(response); System.Threading.Monitor.PulseAll(initial_members.SyncRoot); } Stack.NCacheLog.CriticalInfo(Name + ".up", "connection failure with " + node); } break; // end services default: passUp(evt); // Pass up to the layer above us break; } }
/// <summary> An event is to be sent down the stack. The layer may want to examine its type and perform /// some action on it, depending on the event's type. If the event is a message MSG, then /// the layer may need to add a header to it (or do nothing at all) before sending it down /// the stack using <code>passDown()</code>. In case of a GET_ADDRESS event (which tries to /// retrieve the stack's address from one of the bottom layers), the layer may need to send /// a new response event back up the stack using <code>passUp()</code>. /// </summary> public virtual void down(Event evt) { passDown(evt); }
/// <summary> Causes the event to be forwarded to the next layer down in the hierarchy.Typically called /// by the implementation of <code>Down</code> (when done). /// </summary> public virtual void passDown(Event evt) { if (down_prot != null) { down_prot.receiveDownEvent(evt); } else stack.NCacheLog.Error("Protocol", "no lower layer available"); }
/// <summary> Internal method, should not be called by clients. Used by ProtocolStack. I would have /// used the 'friends' modifier, but this is available only in C++ ... If the down_handler thread /// is not available (down_thread == false), then directly call the down() method: we will run on the /// caller's thread (e.g. the protocol layer above us). /// </summary> public virtual void receiveDownEvent(Event evt) { int type = evt.Type; if (down_handler == null) { if (type == Event.ACK || type == Event.START || type == Event.STOP) { if (handleSpecialDownEvent(evt) == false) return ; } if (_printMsgHdrs && type == Event.MSG) printMsgHeaders(evt,"down()"); down(evt); return ; } try { if (type == Event.STOP || type == Event.VIEW_BCAST_MSG) { if (handleSpecialDownEvent(evt) == false) return ; if (down_prot != null) { down_prot.receiveDownEvent(evt); } return; } down_queue.add(evt, evt.Priority); } catch (System.Exception e) { stack.NCacheLog.Warn("Protocol.receiveDownEvent():2", e.ToString()); } }
protected override bool handleSpecialDownEvent(Event evt) { //We handle the view message differently to handle the situation //where coordinator itself is leaving if (evt.Type == Event.VIEW_BCAST_MSG) { Stack.NCacheLog.Error("TCP.handleSpecialDownEvent", evt.ToString()); down(new Event(Event.MSG, evt.Arg, evt.Priority)); Stack.NCacheLog.Error("TCP.handleSpecialDownEvent", "view broadcast is complete"); return false; } return base.handleSpecialDownEvent(evt); }
public override void receiveUpEvent(Event evt) { int type = evt.Type; if (_printMsgHdrs && type == Event.MSG) printMsgHeaders(evt, "up()"); if (!up_thread) { up(evt); return; } try { if (evt.Type == Event.MSG || evt.Type == Event.MSG_URGENT) { Message msg = evt.Arg as Message; //We don't queue the critical priority events if (evt.Priority == Priority.Critical) { GMS.HDR hdr = msg.getHeader(HeaderType.GMS) as GMS.HDR; bool allowAsyncPassup = false; if (hdr != null) { switch (hdr.type) { case GMS.HDR.VIEW: if (msg.Src != null && msg.Src.Equals(local_addr)) allowAsyncPassup = true; break; case GMS.HDR.IS_NODE_IN_STATE_TRANSFER: case GMS.HDR.IS_NODE_IN_STATE_TRANSFER_RSP: case GMS.HDR.VIEW_RESPONSE: allowAsyncPassup = true; break; } } //passing up GET_MBRS_REQ for faster delivery PingHeader pingHdr = msg.getHeader(HeaderType.TCPPING) as PingHeader; if (pingHdr != null && pingHdr.type == PingHeader.GET_MBRS_REQ) allowAsyncPassup = true; if (allowAsyncPassup) { System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolPassup), evt); return; } } switch (msg.Type) { case MsgType.TOKEN_SEEKING: _tokenMsgUpQueue.add(evt, evt.Priority); break; case MsgType.SEQUENCED: _sequenecedMsgUpQueue.add(evt, evt.Priority); break; case MsgType.SEQUENCE_LESS: _sequencelessMsgUpQueue.add(evt, evt.Priority); break; default: _sequencelessMsgUpQueue.add(evt, evt.Priority); break; } } } catch (System.Exception e) { Stack.NCacheLog.Info("Protocol.receiveUpEvent()", e.ToString()); } }
public override void receiveDownEvent(Event evt) { int type = evt.Type; if (evt.Type == Event.I_AM_LEAVING) { //Set leaving flag to true _leaving = true; return; } if (_unicastDownHandler == null) { if (type == Event.ACK || type == Event.START || type == Event.STOP) { if (handleSpecialDownEvent(evt) == false) return; } if (evt.Type == Event.HAS_STARTED) { HasStarted(); return; } if (_printMsgHdrs && type == Event.MSG) printMsgHeaders(evt, "down()"); down(evt); return; } try { if (type == Event.STOP || type == Event.VIEW_BCAST_MSG) { if (handleSpecialDownEvent(evt) == false) return; if (down_prot != null) { down_prot.receiveDownEvent(evt); } return; } if (evt.Type == Event.HAS_STARTED) { HasStarted(); return; } if (evt.Type == Event.MSG || evt.Type == Event.MSG_URGENT) { Message msg = evt.Arg as Message; if (msg != null) { if ((msg.Type & MsgType.TOKEN_SEEKING) == MsgType.TOKEN_SEEKING) { _tokenSeekingMsgDownQueue.add(evt, evt.Priority); return; } if (msg.Dests != null || msg.Dest == null) { _multicastDownQueue.add(evt, evt.Priority); return; } else { _unicastDownQueue.add(evt, evt.Priority); return; } } } _unicastDownQueue.add(evt, evt.Priority); } catch (System.Exception e) { Stack.NCacheLog.Info("Protocol.receiveDownEvent():2", e.ToString()); } }
/// <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 HearBeat(HearBeat.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.Critical); _statusReceived = null; //wait for the result or timeout occurs first; Monitor.Wait(_status_mutex, _statusTimeout); if (_statusReceived != null) { HearBeat status = _statusReceived as HearBeat; if (_enclosingInstance.Stack.NCacheLog.IsInfoEnabled) _enclosingInstance.Stack.NCacheLog.Info("ConnectionKeepAlive.CheckStatus", "received status " + status + " from " + _currentSuspect); if (status.Type == HearBeat.I_AM_NOT_DEAD) nodeStatus = new NodeStatus(_currentSuspect, NodeStatus.IS_ALIVE); else if (status.Type == HearBeat.I_AM_LEAVING) nodeStatus = new NodeStatus(_currentSuspect, NodeStatus.IS_LEAVING); else if (status.Type == HearBeat.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; } } } }
private void handleDownEvent(Event evt) { switch (evt.Type) { case Event.GET_NODE_STATUS: Address suspect = evt.Arg as Address; if (_keepAlive != null) _keepAlive.CheckStatus(suspect); break; case Event.FIND_INITIAL_MBRS: lock (async_mutex) { Stack.NCacheLog.Flush(); for (int i = 0; i < asyncThreads.Count; i++) { Thread t = asyncThreads[i] as Thread; if (t != null && t.IsAlive) t.Abort(); } asyncThreads.Clear(); } break; case Event.GET_STATE: passUp(new Event(Event.GET_STATE_OK)); break; case Event.TMP_VIEW: case Event.VIEW_CHANGE: ArrayList temp_mbrs = new ArrayList(); ArrayList nodeJoiningList = new ArrayList(); lock_members.AcquireWriterLock(Timeout.Infinite); try { members.Clear(); ArrayList tmpvec = ((View)evt.Arg).Members; if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("Tcp.down()", ((evt.Type == Event.TMP_VIEW) ? "TMP_VIEW" : "VIEW_CHANGE")); if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("Tcp.down()", " View change members count" + tmpvec.Count); Address address = null; for (int i = 0; i < tmpvec.Count; i++) { address = tmpvec[i] as Address; //Goes false only when isStarting is true along with the ip matches //Dont want to exclude membership of the physical node replica since membership is changing and to avoid thread synchronization to go haywire if (address != null && !(isStarting && address.IpAddress.Equals(local_addr.IpAddress))) { temp_mbrs.Add(tmpvec[i]); } members.Add(tmpvec[i]); nodeJoiningList.Add(tmpvec[i]); } } finally { lock_members.ReleaseWriterLock(); } if (_asyncProcessor != null) _asyncProcessor.Stop(); lock (async_mutex) { if (Stack.NCacheLog != null) Stack.NCacheLog.Flush(); for (int i = 0; i < asyncThreads.Count; i++) { Thread t = asyncThreads[i] as Thread; if (t != null && t.IsAlive) t.Abort(); } asyncThreads.Clear(); } ct.ConfigureNodeRejoining(nodeJoiningList); ArrayList failedNodes = ct.synchronzeMembership(temp_mbrs, false); passUp(evt); if (failedNodes.Count > 0) { if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCP.HandleDownEvent()", " can not establish connection with all the nodes "); passUp(new Event(Event.CONNECTION_FAILURE, failedNodes, Priority.Critical)); } break; case Event.GET_LOCAL_ADDRESS: // return local address -> Event(SET_LOCAL_ADDRESS, local) passUp(new Event(Event.SET_LOCAL_ADDRESS, local_addr)); break; case Event.CONNECT: object[] addrs = ((object[])evt.Arg); group_addr = (string)addrs[0]; subGroup_addr = (string)addrs[1]; bool twoPhaseConnect = (bool)addrs[2]; synchronizeConnections = !twoPhaseConnect; if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCP.HandleDownEvent()", " group_address is : " + group_addr); // removed March 18 2003 (bela), not needed (handled by GMS) // Can't remove it; otherwise TCPGOSSIP breaks (bela May 8 2003) ! Address addr = new Address(ct.srv_port); passUp(new Event(Event.CONNECT_OK, (object)addr)); break; case Event.DISCONNECT: passUp(new Event(Event.DISCONNECT_OK)); break; case Event.CONFIG: if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("received CONFIG event: " + evt.Arg); handleConfigEvent((System.Collections.Hashtable)evt.Arg); break; case Event.ACK: passUp(new Event(Event.ACK_OK)); break; } }
/// <summary>Send a message to the address specified in msg.dest </summary> private void sendUnicastMessage(Address dest, byte[] msg, bool reEstablishCon, Array UserPayload, Priority priority) { try { if (skip_suspected_members) { if (suspected_mbrs.contains(dest)) { if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("will not send unicast message to " + dest + " as it is currently suspected"); return; } } long bytesSent = ct.send(dest, msg, reEstablishCon, UserPayload, priority); } catch (ExtSocketException) { if (members.Contains(dest)) { if (!suspected_mbrs.contains(dest) && local_addr != null) { suspected_mbrs.add(dest); Event evt = new Event(Event.SUSPECT, dest, Priority.Critical); evt.Reason = "Tcp.sendUnicastMesssage caused suspect event"; passUp(evt); } } } catch (ThreadAbortException) { } catch (ThreadInterruptedException) { } catch (System.Exception e)//Taimoor's code { stack.NCacheLog.Error("TCP.sendUnicastMessage()", e.ToString()); } }
/// <summary>Send a message to the address specified in msg.dest </summary> private void sendLocalMessage(Message msg) { Message copy; System.Object hdr; Event evt; SourceAddress = msg; /* Don't send if destination is local address. Instead, switch dst and src and put in up_queue */ if (loopback && local_addr != null) { copy = msg.copy(); copy.Type = msg.Type; hdr = copy.getHeader(HeaderType.TCP); if (hdr != null && hdr is TcpHeader) { copy.removeHeader(HeaderType.TCP); } copy.Src = local_addr; copy.Dest = local_addr; if (msg.IsProfilable) { stack.NCacheLog.Error("TCP", msg.TraceMsg + " sending to ---> " + msg.Dest.ToString()); } evt = new Event(Event.MSG, copy, copy.Priority); /* Because Protocol.up() is never called by this bottommost layer, we call up() directly in the observer. This allows e.g. PerfObserver to get the time of reception of a message */ if (!asyncPassup) this.receiveUpEvent(evt); else System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolPassup), evt); if (msg.IsProfilable) { stack.NCacheLog.Error("TCP", msg.TraceMsg + " sent to ---> " + msg.Dest.ToString()); } return; } }
/// <summary> Internal method, should not be called by clients. Used by ProtocolStack. I would have /// used the 'friends' modifier, but this is available only in C++ ... If the up_handler thread /// is not available (down_thread == false), then directly call the up() method: we will run on the /// caller's thread (e.g. the protocol layer below us). /// </summary> public virtual void receiveUpEvent(Event evt) { int type = evt.Type; if (_printMsgHdrs && type == Event.MSG) printMsgHeaders(evt,"up()"); if (up_handler == null) { up(evt); return ; } try { if (stack.NCacheLog.IsInfoEnabled) stack.NCacheLog.Info(Name + ".receiveUpEvent()", "RentId :" + evt.RentId + "up queue count : " + up_queue.Count); up_queue.add(evt, evt.Priority); } catch (System.Exception e) { stack.NCacheLog.Warn("Protocol.receiveUpEvent()", e.ToString()); } }
/// <summary> /// Prints the header of a message. Used for debugging purpose. /// </summary> /// <param name="evt"></param> protected void printMsgHeaders(Event evt,string extra) { Message m = (Message)evt.Arg; try { if(m != null) { if (stack.NCacheLog.IsInfoEnabled) stack.NCacheLog.Info(this.Name + "." + extra + ".printMsgHeaders()", Global.CollectionToString(m.Headers)); } } catch(Exception e) { stack.NCacheLog.Error(this.Name + ".printMsgHeaders()", e.ToString()); } }
/// <summary>Sent to destination(s) using the ConnectionTable class.</summary> public override void down(Event evt) { Message msg; System.Object dest_addr; bool reEstablishCon = false; stats = new TimeStats(1); if (evt.Type != Event.MSG && evt.Type != Event.MSG_URGENT) { handleDownEvent(evt); return; } reEstablishCon = evt.Type == Event.MSG_URGENT ? true : false; msg = (Message)evt.Arg; msg.Priority = evt.Priority; if (Stack.NCacheLog.IsInfoEnabled) stack.NCacheLog.Info("Tcp.down()", " message headers = " + Global.CollectionToString(msg.Headers)); if (group_addr != null) { msg.putHeader(HeaderType.TCP, new TcpHeader(group_addr)); } dest_addr = msg.Dest; /* Because we don't call Protocol.passDown(), we notify the observer directly (e.g. PerfObserver). This way, we still have performance numbers for TCP */ try { if (dest_addr == null) { // broadcast (to all members) if (group_addr == null) { Stack.NCacheLog.Info("dest address of message is null, and " + "sending to default address fails as group_addr is null, too !" + " Discarding message."); return; } else { if (reEstablishCon && _asyncProcessor != null) { lock (async_mutex) { if (asyncThreads != null) { TCP.AsnycMulticast asyncMcast = new TCP.AsnycMulticast(this, msg, reEstablishCon); Thread asyncThread = new Thread(new ThreadStart(asyncMcast.Process)); asyncThreads.Add(asyncThread); asyncThread.Start(); } } if (Stack.NCacheLog.IsInfoEnabled) stack.NCacheLog.Info("Tcp.down", "broadcasting message asynchronously "); } else { sendMulticastMessage(msg, reEstablishCon, evt.Priority); // send to current membership } } } else { if (Stack.NCacheLog.IsInfoEnabled) stack.NCacheLog.Info("Tcp.down()", " destination address " + msg.Dest.ToString()); if (reEstablishCon && _asyncProcessor != null) { lock (async_mutex) { if (asyncThreads != null) { TCP.AsnycUnicast asyncUcast = new TCP.AsnycUnicast(this, msg, reEstablishCon); Thread asyncThread = new Thread(new ThreadStart(asyncUcast.Process)); asyncThreads.Add(asyncThread); asyncThread.Start(); } } } else { sendUnicastMessage(msg, reEstablishCon, msg.Payload, evt.Priority); // send to a single member } } } finally { } }
/// <summary> Causes the event to be forwarded to the next layer up in the hierarchy. Typically called /// by the implementation of <code>Up</code> (when done). /// </summary> public virtual void passUp(Event evt) { if (up_prot != null) { up_prot.receiveUpEvent(evt); } else stack.NCacheLog.Error("Protocol", "no upper layer available"); }
/// <summary>ConnectionTable.Receiver interface </summary> public virtual void receive(Message msg) { TcpHeader hdr = null; msg.Dest = local_addr; Event evt = new Event(); evt.Arg = msg; evt.Priority = msg.Priority; evt.Type = Event.MSG; HearBeat hrtBeat = msg.removeHeader(HeaderType.KEEP_ALIVE) as HearBeat; if (hrtBeat != null && _keepAlive != null) { _keepAlive.ReceivedHeartBeat(msg.Src, hrtBeat); return; } TOTAL.HDR totalhdr = msg.getHeader(HeaderType.TOTAL) as TOTAL.HDR; if (!asyncPassup) this.receiveUpEvent(evt); else System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolPassup), evt); }
/// <summary> An event was received from the layer below. Usually the current layer will want to examine /// the event type and - depending on its type - perform some computation /// (e.g. removing headers from a MSG event type, or updating the internal membership list /// when receiving a VIEW_CHANGE event). /// Finally the event is either a) discarded, or b) an event is sent down /// the stack using <code>passDown()</code> or c) the event (or another event) is sent up /// the stack using <code>passUp()</code>. /// </summary> public virtual void up(Event evt) { passUp(evt); }
public void ThreadPoolLocalPassUp(Event evt) { System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolPassup), evt); }
/// <summary>These are special internal events that should not be handled by protocols</summary> /// <returns> boolean True: the event should be passed further down the stack. False: the event should /// be discarded (not passed down the stack) /// </returns> protected virtual bool handleSpecialDownEvent(Event evt) { switch (evt.Type) { case Event.ACK: if (down_prot == null) { passUp(new Event(Event.ACK_OK)); return false; // don't pass down the stack } goto case Event.START; case Event.START: try { start(); // if we're the transport protocol, reply with a START_OK up the stack if (down_prot == null) { passUp(new Event(Event.START_OK, (object) true)); return false; // don't pass down the stack } return true; // pass down the stack } catch (System.Exception e) { stack.NCacheLog.Error("Protocol.handleSpecialDownEvent", e.ToString()); passUp(new Event(Event.START_OK, new System.Exception(e.Message,e))); } return false; case Event.STOP: try { stop(); } catch (System.Exception e) { stack.NCacheLog.Error("Protocol.handleSpecialDownEvent()", e.ToString()); } if (down_prot == null) { passUp(new Event(Event.STOP_OK, (object) true)); return false; // don't pass down the stack } return true; // pass down the stack default: return true; // pass down by default } }
public virtual void connectionClosed(Address peer_addr) { if (peer_addr != null && local_addr != null) { if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("closed connection to " + peer_addr + " added to the suspected list"); suspected_mbrs.add(peer_addr); Event evt = new Event(Event.SUSPECT, peer_addr, Priority.Critical); evt.Reason = "Connection closed called for suspect event"; passUp(evt); } }
public override void down(Event evt) { Message msg; long time_to_wait, start_time; switch (evt.Type) { case Event.FIND_INITIAL_MBRS: // sent by GMS layer, pass up a GET_MBRS_OK event //We pass this event down to tcp so that it can take some measures. passDown(evt); initial_members.Clear(); msg = new Message(null, null, null); msg.putHeader(HeaderType.TCPPING, new PingHeader(PingHeader.GET_MBRS_REQ, (System.Object)local_addr,group_addr)); // if intitial nodes have been specified and static is true, then only those // members will form the cluster, otherwise, nodes having the same IP Multicast and port // will form the cluster dyanamically. mbrDiscoveryInProcess = true; lock (members.SyncRoot) { if( initial_hosts != null) { for (System.Collections.IEnumerator it = initial_hosts.GetEnumerator(); it.MoveNext(); ) { Address addr = (Address) it.Current; msg.Dest = addr; if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("[FIND_INITIAL_MBRS] sending PING request to " + msg.Dest); passDown(new Event(Event.MSG_URGENT, msg.copy(), Priority.Critical)); } } } // 2. Wait 'timeout' ms or until 'num_initial_members' have been retrieved if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TcpPing.down()", "[FIND_INITIAL_MBRS] waiting for results..............."); lock (initial_members.SyncRoot) { start_time = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; time_to_wait = timeout; while (initial_members.Count < num_initial_members && time_to_wait > 0) { try { if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TcpPing.down()", "initial_members Count: " + initial_members.Count + "initialHosts Count: " + num_initial_members); if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TcpPing.down()", "Time to wait for next response: " + time_to_wait); ///Big_clusterd: initial members will be pulsed in case connection is not available. ///so here we dont have to wait till each member is timed out. ///this significantly improves time for initial member discovery. bool timeExpire = System.Threading.Monitor.Wait(initial_members.SyncRoot, TimeSpan.FromMilliseconds(time_to_wait)); } catch (System.Exception e) { Stack.NCacheLog.Error("TCPPing.down(FIND_INITIAL_MBRS)", e.ToString()); } time_to_wait = timeout - ((System.DateTime.Now.Ticks - 621355968000000000) / 10000 - start_time); } mbrDiscoveryInProcess = false; } if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TcpPing.down()", "[FIND_INITIAL_MBRS] initial members are " + Global.CollectionToString(initial_members)); if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TcpPing.down()", "[FIND_INITIAL_MBRS] initial members count " + initial_members.Count); //remove those which are not functional due to twoPhaseConnect for (int i = initial_members.Count - 1; i >= 0; i--) { PingRsp rsp = initial_members[i] as PingRsp; if (!rsp.IsStarted) initial_members.RemoveAt(i); } // 3. Send response passUp(new Event(Event.FIND_INITIAL_MBRS_OK, initial_members)); break; case Event.TMP_VIEW: case Event.VIEW_CHANGE: System.Collections.ArrayList tmp; if ((tmp = ((View) evt.Arg).Members) != null) { lock (members.SyncRoot) { members.Clear(); members.AddRange(tmp); } } passDown(evt); break; /****************************After removal of NackAck *********************************/ //TCPPING emulates a GET_DIGEST call, which is required by GMS. This is needed //since we have now removed NAKACK from the stack! case Event.GET_DIGEST: pbcast.Digest digest = new pbcast.Digest(members.Count); for (int i = 0; i < members.Count; i++) { Address sender = (Address)members[i]; digest.add(sender, 0, 0); } passUp(new Event(Event.GET_DIGEST_OK, digest)); return; case Event.SET_DIGEST: // Not needed! Just here to let you know that it is needed by GMS! return; /********************************************************************************/ case Event.BECOME_SERVER: // called after client has joined and is fully working group member if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TcpPing.down()", "received BECOME_SERVER event"); passDown(evt); is_server = true; break; case Event.CONNECT: object[] addrs = ((object[])evt.Arg); group_addr = (string)addrs[0]; subGroup_addr = (string)addrs[1]; twoPhaseConnect = (bool)addrs[3]; if (twoPhaseConnect) timeout = 1000; passDown(evt); break; case Event.DISCONNECT: passDown(evt); break; case Event.HAS_STARTED: hasStarted = true; passDown(evt); break; default: passDown(evt); // Pass on to the layer below us break; } }
public override void up(Event evt) { TcpHeader hdr = null; Message msg = null; switch (evt.Type) { case Event.MSG: msg = (Message)evt.Arg; if (msg.IsProfilable) { stack.NCacheLog.Error("--------------------------------------", " ---------------Request.Add-->" + msg.TraceMsg + "----------"); stack.NCacheLog.Error("TCP", msg.TraceMsg + " received from ---> " + msg.Src.ToString()); } if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("TCP.up()", "src: " + msg.Src + " ,priority: " + evt.Priority + ", hdrs: " + Global.CollectionToString(msg.Headers)); if (msg.IsProfilable) { } hdr = (TcpHeader)msg.removeHeader(HeaderType.TCP); if (hdr != null) { /* Discard all messages destined for a channel with a different name */ System.String ch_name = null; if (hdr.group_addr != null) ch_name = hdr.group_addr; // Discard if message's group name is not the same as our group name unless the // message is a diagnosis message (special group name DIAG_GROUP) if (ch_name != null && !group_addr.Equals(ch_name)) { Stack.NCacheLog.Info("discarded message from different group (" + ch_name + "). Sender was " + msg.Src); return; } } passUp(evt); break; } }
protected void ConfigureClusterForRejoining(ArrayList nodes) { Event evt = new Event(Event.CONFIGURE_NODE_REJOINING, nodes, Priority.Critical); _cluster.ConfigureLocalCluster(evt); }
private void InformConnectionClose(Address node) { if (!stopped) { Event evt = new Event(Event.CONNECTION_BREAKAGE, node, Priority.Critical); enclosingInstance.passUp(evt); } }
public virtual bool handleDownEvent(Event evt) { return true; }
private void InformConnectionReestablishment(Address node) { if (!stopped) { Event evt = new Event(Event.CONNECTION_RE_ESTABLISHED, node, Priority.Critical); enclosingInstance.passUp(evt); } }