Example #1
0
		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;
				
			}
		}
Example #2
0
        /// <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;
            }

        }