/// <summary>Try to obtain correct Connection (or create one if not yet existent) </summary> protected virtual Connection getConnection(Address dest, Address primaryAddress, bool reEstablishCon, bool isPrimary, bool withFirstNIC,bool connectingFirstTime) { Connection conn = null; System.Net.Sockets.Socket sock; Address peer_addr = null; try { if (primaryAddress == null) primaryAddress = dest; if (withFirstNIC) { if (isPrimary) conn = (Connection)conns_NIC_1[dest]; else conn = (Connection)secondayrConns_NIC_1[dest]; } else { if (isPrimary) conn = (Connection)conns_NIC_2[primaryAddress]; else conn = (Connection)secondayrConns_NIC_2[primaryAddress]; } if ((conn == null ||!connectingFirstTime) && reEstablishCon) { try { if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.getConnection()", "No Connetion was found found with " + dest.ToString()); if (local_addr == null) return null; //cluster being stopped. sock = Connect(dest, withFirstNIC); conn = new Connection(this, sock, primaryAddress, this.NCacheLog, isPrimary, nagglingSize, _retries, _retryInterval); conn.MemManager = MemManager; conn.IamInitiater = true; ConnectInfo conInfo = null; try { byte connectStatus = connectingFirstTime ? ConnectInfo.CONNECT_FIRST_TIME : ConnectInfo.RECONNECTING; conn.sendLocalAddress(local_addr,connectingFirstTime); conn.readPeerAddress(sock,ref peer_addr); if (((Address)local_addr).CompareTo((Address)dest) > 0) { conInfo = new ConnectInfo(connectStatus, GetConnectionId()); if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.getConnection", dest + " I should send connect_info"); conn.SendConnectInfo(conInfo); } else { conInfo = conn.ReadConnectInfo(sock); } //log.Error("ConnectionTable.getConnection", " conn_info :" + conInfo); conn.ConInfo = conInfo; } catch (System.Exception e) { NCacheLog.Error("ConnectionTable.getConnection()", e.Message); conn.DestroySilent(); return null; } if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.getConnection", "b4 lock conns.SyncRoot"); try { conn_syn_lock.AcquireWriterLock(Timeout.Infinite); if (isPrimary) { if (withFirstNIC) { if (conns_NIC_1.ContainsKey(dest)) { if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.getConnection()", "connection is already in the table"); Connection tmpConn = (Connection)conns_NIC_1[dest]; if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.getConnection", "table_con id :" + tmpConn.ConInfo.Id + " new_con id :" + conn.ConInfo.Id); if (conn.ConInfo.Id < tmpConn.ConInfo.Id) { conn.Destroy(); return tmpConn; } else { if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.getConnection()", dest + "--->connection present in the table is terminated"); tmpConn.Destroy(); conns_NIC_1.Remove(dest); } } notifyConnectionOpened(dest); } else { if (conns_NIC_2.ContainsKey(primaryAddress)) { if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.getConnection()", "connection is already in the table"); Connection tmpConn = (Connection)conns_NIC_1[dest]; if (conn.ConInfo.Id < tmpConn.ConInfo.Id) { conn.Destroy(); return tmpConn; } else { NCacheLog.Warn("ConnectionTable.getConnection()", dest + "connection present in the table is terminated"); tmpConn.Destroy(); conns_NIC_2.Remove(primaryAddress); } } } } addConnection(primaryAddress, conn, isPrimary, withFirstNIC); if (useDedicatedSender) AddDedicatedMessageSender(primaryAddress, conn, withFirstNIC); conn.init(); } finally { conn_syn_lock.ReleaseWriterLock(); } if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.getConnection", "after lock conns.SyncRoot"); if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ConnectionTable.getConnection()", "connection is now working"); } finally { } } } catch (System.Threading.ThreadAbortException e) { if (conn != null) conn.Destroy(); conn = null; } catch (System.Threading.ThreadInterruptedException ex) { if (conn != null) conn.Destroy(); conn = null; } finally { } return conn; }
/// <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 { } } }