internal void Execute(HostNode host, UseSocket use) { MSocket sock = null; try { //Acquire a socket sock = host.Acquire(); //Use the socket as a parameter to the delegate and return its result. if (sock != null) { use(sock); } } catch (Exception e) { logger.Error("Error in Execute: " + host.Host, e); //Socket is probably broken if (sock != null) { sock.Close(); } } finally { if (sock != null) { sock.ReturnPool(); } } }
/// <summary> /// Gets a socket from the pool. /// If there are no free sockets, a new one will be created. If something goes /// wrong while creating the new socket, this pool's endpoint will be marked as dead /// and all subsequent calls to this method will return null until the retry interval /// has passed. /// 这个方法扩展(备份链接池) /// </summary> internal MSocket Acquire() { //检测当前是否挂科,如果是(15分钟内),由备份服务器提供服务 if (socketDeadTime.AddMinutes(15) >= DateTime.Now && HostNodeBak != null) { return(HostNodeBak.Acquire()); } //Do we have free sockets in the pool? //if so - return the first working one. //if not - create a new one. Interlocked.Increment(ref Acquired); lock (socketQueue) { while (socketQueue.Count > 0) { MSocket socket = socketQueue.Dequeue(); if (socket != null && socket.IsAlive) { Interlocked.Increment(ref ReusedSockets); return(socket); } Interlocked.Increment(ref DeadSocketsInPool); } } //If we know the endpoint is dead, check if it is time for a retry, otherwise return null. if (IsEndPointDead) { if (DateTime.Now > DeadEndPointRetryTime) { //Retry IsEndPointDead = false; } else { //Still dead return(null); } } //Try to create a new socket. On failure, mark endpoint as dead and return null. try { MSocket socket = new MSocket(this, Host); Interlocked.Increment(ref NewSockets); //Reset retry timer on success. //不抛异常,则正常链接。 if (OnAfterSocketCreateEvent != null) { OnAfterSocketCreateEvent(socket); } deadEndPointSecondsUntilRetry = 1; return(socket); } catch (Exception e) { Interlocked.Increment(ref FailedNewSockets); logger.Error("Error connecting to: " + Host, e); //Mark endpoint as dead IsEndPointDead = true; //Retry in 2 minutes DeadEndPointRetryTime = DateTime.Now.AddSeconds(deadEndPointSecondsUntilRetry); if (deadEndPointSecondsUntilRetry < maxDeadEndPointSecondsUntilRetry) { deadEndPointSecondsUntilRetry = deadEndPointSecondsUntilRetry * 2; //Double retry interval until next time } socketDeadTime = DateTime.Now; //返回备份的池 if (HostNodeBak != null) { return(HostNodeBak.Acquire()); } return(null); } }