internal void OnFullyEstablished(PhysicalConnection connection) { Trace("OnFullyEstablished"); connection?.SetIdle(); if (physical == connection && !isDisposed && ChangeState(State.ConnectedEstablishing, State.ConnectedEstablished)) { reportNextFailure = reconfigureNextFailure = true; LastException = null; Interlocked.Exchange(ref failConnectCount, 0); ServerEndPoint.OnFullyEstablished(connection); bool createWorker; lock (_backlog) // do we have pending system things to do? { createWorker = _backlog.Count != 0; } if (createWorker) { StartBacklogProcessor(); } if (ConnectionType == ConnectionType.Interactive) { ServerEndPoint.CheckInfoReplication(); } } else { try { connection.Dispose(); } catch { } } }
internal void OnFullyEstablished(PhysicalConnection connection) { Trace("OnFullyEstablished"); if (physical == connection && !isDisposed && ChangeState(State.ConnectedEstablishing, State.ConnectedEstablished)) { reportNextFailure = reconfigureNextFailure = true; Interlocked.Exchange(ref failConnectCount, 0); serverEndPoint.OnFullyEstablished(connection); multiplexer.RequestWrite(this, true); if (connectionType == ConnectionType.Interactive) { serverEndPoint.CheckInfoReplication(); } } else { try { connection.Dispose(); } catch { } } }
internal void OnFullyEstablished(PhysicalConnection connection) { Trace("OnFullyEstablished"); connection?.SetIdle(); if (physical == connection && !isDisposed && ChangeState(State.ConnectedEstablishing, State.ConnectedEstablished)) { reportNextFailure = reconfigureNextFailure = true; LastException = null; Interlocked.Exchange(ref failConnectCount, 0); ServerEndPoint.OnFullyEstablished(connection); WritePendingBacklog(connection); if (ConnectionType == ConnectionType.Interactive) { ServerEndPoint.CheckInfoReplication(); } } else { try { connection.Dispose(); } catch { } } }
internal void OnHeartbeat(bool ifConnectedOnly) { bool runThisTime = false; try { runThisTime = !isDisposed && Interlocked.CompareExchange(ref beating, 1, 0) == 0; if (!runThisTime) { return; } uint index = (uint)Interlocked.Increment(ref profileLogIndex); long newSampleCount = Interlocked.Read(ref operationCount); Interlocked.Exchange(ref profileLog[index % ProfileLogSamples], newSampleCount); Interlocked.Exchange(ref profileLastLog, newSampleCount); Trace("OnHeartbeat: " + (State)state); switch (state) { case (int)State.Connecting: int connectTimeMilliseconds = unchecked (Environment.TickCount - Thread.VolatileRead(ref connectStartTicks)); bool shouldRetry = Multiplexer.RawConfig.ReconnectRetryPolicy.ShouldRetry(Interlocked.Read(ref connectTimeoutRetryCount), connectTimeMilliseconds); if (shouldRetry) { Interlocked.Increment(ref connectTimeoutRetryCount); LastException = ExceptionFactory.UnableToConnect(Multiplexer, "ConnectTimeout"); Trace("Aborting connect"); // abort and reconnect var snapshot = physical; OnDisconnected(ConnectionFailureType.UnableToConnect, snapshot, out bool isCurrent, out State oldState); using (snapshot) { } // dispose etc TryConnect(null); } break; case (int)State.ConnectedEstablishing: case (int)State.ConnectedEstablished: var tmp = physical; if (tmp != null) { if (state == (int)State.ConnectedEstablished) { Interlocked.Exchange(ref connectTimeoutRetryCount, 0); tmp.BridgeCouldBeNull?.ServerEndPoint?.ClearUnselectable(UnselectableFlags.DidNotRespond); } tmp.OnBridgeHeartbeat(); int writeEverySeconds = ServerEndPoint.WriteEverySeconds, checkConfigSeconds = Multiplexer.RawConfig.ConfigCheckSeconds; if (state == (int)State.ConnectedEstablished && ConnectionType == ConnectionType.Interactive && checkConfigSeconds > 0 && ServerEndPoint.LastInfoReplicationCheckSecondsAgo >= checkConfigSeconds && ServerEndPoint.CheckInfoReplication()) { // that serves as a keep-alive, if it is accepted } else if (writeEverySeconds > 0 && tmp.LastWriteSecondsAgo >= writeEverySeconds) { Trace("OnHeartbeat - overdue"); if (state == (int)State.ConnectedEstablished) { KeepAlive(); } else { OnDisconnected(ConnectionFailureType.SocketFailure, tmp, out bool ignore, out State oldState); } } else if (writeEverySeconds <= 0 && tmp.IsIdle() && tmp.LastWriteSecondsAgo > 2 && tmp.GetSentAwaitingResponseCount() != 0) { // there's a chance this is a dead socket; sending data will shake that // up a bit, so if we have an empty unsent queue and a non-empty sent // queue, test the socket KeepAlive(); } } break; case (int)State.Disconnected: Interlocked.Exchange(ref connectTimeoutRetryCount, 0); if (!ifConnectedOnly) { Multiplexer.Trace("Resurrecting " + ToString()); Multiplexer.OnResurrecting(ServerEndPoint?.EndPoint, ConnectionType); GetConnection(null); } break; default: Interlocked.Exchange(ref connectTimeoutRetryCount, 0); break; } } catch (Exception ex) { OnInternalError(ex); Trace("OnHeartbeat error: " + ex.Message); } finally { if (runThisTime) { Interlocked.Exchange(ref beating, 0); } } }