コード例 #1
0
ファイル: ConnectionTable.cs プロジェクト: javithalion/NCache
        /// <summary> Acceptor thread. Continuously accept new connections. Create a new thread for each new
        /// connection and put it in conns. When the thread should stop, it is
        /// interrupted by the thread creator.
        /// </summary>
        public virtual void Run(Object arg)
        {
            Object[] objArr = arg as object[];
            TcpListener listener = objArr[0] as TcpListener;
            bool isPrimaryListener = (bool)objArr[1];

            System.Net.Sockets.Socket client_sock;
            Connection conn = null;
            Address peer_addr = null;

            while (listener != null)
            {
                try
                {
                    client_sock = listener.AcceptSocket();
                    int cport = ((IPEndPoint)client_sock.RemoteEndPoint).Port;

                     if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.Run()", "CONNECTION ACCPETED Remote port = " + cport);
                    client_sock.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
                    
                    client_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, send_buf_size);
                    client_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, recv_buf_size);

                    object size = client_sock.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer);
                    size = client_sock.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer);
                    // create new thread and add to conn table

                    conn = new Connection(this, client_sock, null, _ncacheLog, true, nagglingSize, _retries, _retryInterval); // will call receive(msg)

                    // get peer's address
                    bool connectingFirstTime = conn.readPeerAddress(client_sock, ref peer_addr);
                    conn.sendLocalAddress(local_addr,connectingFirstTime);
                    ConnectInfo conInfo = null;
                    if (((Address)local_addr).CompareTo((Address)peer_addr) > 0)
                    {
                        conInfo = new ConnectInfo(ConnectInfo.CONNECT_FIRST_TIME, GetConnectionId());
                        if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.Run", peer_addr + " I should send connect_info");

                       
                        conn.SendConnectInfo(conInfo);
                    }
                    else
                    {
                        conInfo = conn.ReadConnectInfo(client_sock);
                        
                    }

                    conn.ConInfo = conInfo;
                    conn.ConInfo.ConnectStatus = connectingFirstTime ? ConnectInfo.CONNECT_FIRST_TIME : ConnectInfo.RECONNECTING;

                    if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.Run()", "Read peer address " + peer_addr.ToString() + "at port" + cport);

                    conn.PeerAddress = peer_addr;

                    if (conInfo.ConnectStatus == ConnectInfo.RECONNECTING)
                    {
                        //if other node is reconnecting then we should check for its member ship first.
                        bool ismember = enclosingInstance.IsMember(peer_addr);
                        if (!ismember)
                        {

                            NCacheLog.CriticalInfo("ConnectionTa ble.Run", "ConnectionTable.Run" + peer_addr + " has connected. but it is no more part of the membership");

                            conn.SendLeaveNotification();
                            Thread.Sleep(1000); //just to make sure that peer node receives the leave notification.
                            conn.Destroy();
                            continue;
                        }
                    }

                    bool isPrimary = true;

                    if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.run", "b4 lock conns.SyncRoot");
                    try
                    {
                        conn_syn_lock.AcquireWriterLock(Timeout.Infinite);

                        if (isPrimaryListener)
                        {

                           if (conns_NIC_1.ContainsKey(peer_addr))
                            {

                                if (!secondayrConns_NIC_1.Contains(peer_addr) && useDualConnection)
                                {
                                    secondayrConns_NIC_1[peer_addr] = conn;
                                    isPrimary = false;
                                }
                                else
                                {

                                
                                    Connection tmpConn = (Connection)conns_NIC_1[peer_addr];

                                    if (conn.ConInfo.Id < tmpConn.ConInfo.Id && conn.ConInfo.ConnectStatus != ConnectInfo.CONNECT_FIRST_TIME)

                                    {

                                        NCacheLog.CriticalInfo("ConnectionTable.Run", "1. Destroying Connection (conn.ConInfo.Id < tmpConn.ConInfo.Id)" + conn.ConInfo.Id.ToString() + ":" + tmpConn.ConInfo.Id.ToString() + conn.ToString());

                                        conn.Destroy();
                                        continue;
                                    }
                                    else
                                    {
                                        if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.Run()", "-->connection present in the talble is terminated");
                                        
                                        tmpConn.Destroy();
                                        conns_NIC_1.Remove(peer_addr);
                                    }

                                }

                            }
                            
                        }

                        else
                        {
                            if (conns_NIC_2.ContainsKey(peer_addr))
                            {
                                if (!secondayrConns_NIC_2.Contains(peer_addr) && useDualConnection)
                                {
                                    secondayrConns_NIC_2[peer_addr] = conn;
                                    isPrimary = false;
                                }
                                else
                                {
                                    if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.Run()", "connection alrady exists in the table");
                                    Connection tmpConn = (Connection)conns_NIC_2[peer_addr];

                                  
                                    if (conn.ConInfo.Id < tmpConn.ConInfo.Id)
                                    {
                                        conn.Destroy();
                                        continue;
                                    }
                                    else
                                    {
                                        NCacheLog.Error("ConnectionTable.Run()", "connection present in the talble is terminated");
                                        tmpConn.Destroy();
                                        conns_NIC_2.Remove(peer_addr);
                                    }
                                }
                            }
                        }
                        conn.IsPrimary = isPrimary;
                        addConnection(peer_addr, conn, isPrimary, isPrimaryListener);

                        conn.MemManager = memManager;

                        if (useDedicatedSender) AddDedicatedMessageSender(conn.peer_addr, conn, isPrimaryListener);

                        conn.init(); 
                    }
                    finally
                    {
                        conn_syn_lock.ReleaseWriterLock();
                    }
                    if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.run", "after lock conns.SyncRoot");

                    if (isPrimary && isPrimaryListener)

                        notifyConnectionOpened(peer_addr);



                    if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.Run()", "connection working now");
                }
                catch (ExtSocketException sock_ex)
                {
                    NCacheLog.Error("ConnectionTable.Run", "exception is " + sock_ex);

                    if (conn != null)
                        conn.DestroySilent();
                    if (srv_sock1 == null)
                        break; // socket was closed, therefore stop
                }
                catch (System.Exception ex)
                {
                    NCacheLog.Error("ConnectionTable.Run", "exception is " + ex);

                    if (srv_sock1 == null)
                        break; // socket was closed, therefore stop

                }
                finally
                {

                }
            }
        }