public void RecordConnectionFailed(ConnectionFailureType failureType, Exception innerException = null, [CallerMemberName] string origin = null) { IdentifyFailureType(innerException, ref failureType); if (failureType == ConnectionFailureType.InternalFailure) { OnInternalError(innerException, origin); } // stop anything new coming in... bridge.Trace("Failed: " + failureType); bool isCurrent; PhysicalBridge.State oldState; bridge.OnDisconnected(failureType, this, out isCurrent, out oldState); if (isCurrent && Interlocked.CompareExchange(ref failureReported, 1, 0) == 0) { int now = Environment.TickCount, lastRead = Thread.VolatileRead(ref lastReadTickCount), lastWrite = Thread.VolatileRead(ref lastWriteTickCount), lastBeat = Thread.VolatileRead(ref lastBeatTickCount); int unansweredRead = Thread.VolatileRead(ref firstUnansweredWriteTickCount); string message = failureType + " on " + Format.ToString(bridge.ServerEndPoint.EndPoint) + "/" + connectionType + ", origin: " + origin + ", input-buffer: " + ioBufferBytes + ", outstanding: " + GetSentAwaitingResponseCount() + ", last-read: " + unchecked (now - lastRead) / 1000 + "s ago, last-write: " + unchecked (now - lastWrite) / 1000 + "s ago" + ", unanswered-write: " + unchecked (now - unansweredRead) / 1000 + "s ago" + ", keep-alive: " + bridge.ServerEndPoint.WriteEverySeconds + "s, pending: " + bridge.GetPendingCount() + ", state: " + oldState + ", last-heartbeat: " + (lastBeat == 0 ? "never" : (unchecked (now - lastBeat) / 1000 + "s ago")) + (bridge.IsBeating ? " (mid-beat)" : "") + ", last-mbeat: " + multiplexer.LastHeartbeatSecondsAgo + "s ago, global: " + ConnectionMultiplexer.LastGlobalHeartbeatSecondsAgo + "s ago"; var ex = innerException == null ? new RedisConnectionException(failureType, message) : new RedisConnectionException(failureType, message, innerException); bridge.OnConnectionFailed(this, failureType, ex); } // cleanup lock (outstanding) { bridge.Trace(outstanding.Count != 0, "Failing outstanding messages: " + outstanding.Count); while (outstanding.Count != 0) { var next = outstanding.Dequeue(); bridge.Trace("Failing: " + next); next.Fail(failureType, innerException); bridge.CompleteSyncOrAsync(next); } } // burn the socket var socketManager = multiplexer.SocketManager; if (socketManager != null) { socketManager.Shutdown(socketToken); } }
public void RecordConnectionFailed(ConnectionFailureType failureType, ref SocketManager.ManagerState managerState, Exception innerException = null, [CallerMemberName] string origin = null) { IdentifyFailureType(innerException, ref failureType); managerState = SocketManager.ManagerState.RecordConnectionFailed_OnInternalError; if (failureType == ConnectionFailureType.InternalFailure) { OnInternalError(innerException, origin); } // stop anything new coming in... bridge.Trace("Failed: " + failureType); bool isCurrent; PhysicalBridge.State oldState; int @in = -1, ar = -1; managerState = SocketManager.ManagerState.RecordConnectionFailed_OnDisconnected; bridge.OnDisconnected(failureType, this, out isCurrent, out oldState); if (oldState == PhysicalBridge.State.ConnectedEstablished) { try { @in = GetAvailableInboundBytes(out ar); } catch { /* best effort only */ } } if (isCurrent && Interlocked.CompareExchange(ref failureReported, 1, 0) == 0) { managerState = SocketManager.ManagerState.RecordConnectionFailed_ReportFailure; int now = Environment.TickCount, lastRead = Thread.VolatileRead(ref lastReadTickCount), lastWrite = Thread.VolatileRead(ref lastWriteTickCount), lastBeat = Thread.VolatileRead(ref lastBeatTickCount); int unansweredRead = Thread.VolatileRead(ref firstUnansweredWriteTickCount); var exMessage = new StringBuilder(failureType + " on " + Format.ToString(bridge.ServerEndPoint.EndPoint) + "/" + connectionType); var data = new List <Tuple <string, string> > { Tuple.Create("FailureType", failureType.ToString()), Tuple.Create("EndPoint", Format.ToString(bridge.ServerEndPoint.EndPoint)) }; Action <string, string, string> add = (lk, sk, v) => { data.Add(Tuple.Create(lk, v)); exMessage.Append(", " + sk + ": " + v); }; add("Origin", "origin", origin); add("Input-Buffer", "input-buffer", ioBufferBytes.ToString()); add("Outstanding-Responses", "outstanding", GetSentAwaitingResponseCount().ToString()); add("Last-Read", "last-read", unchecked (now - lastRead) / 1000 + "s ago"); add("Last-Write", "last-write", unchecked (now - lastWrite) / 1000 + "s ago"); add("Unanswered-Write", "unanswered-write", unchecked (now - unansweredRead) / 1000 + "s ago"); add("Keep-Alive", "keep-alive", bridge.ServerEndPoint.WriteEverySeconds + "s"); add("Pending", "pending", bridge.GetPendingCount().ToString()); add("Previous-Physical-State", "state", oldState.ToString()); if (@in >= 0) { add("Inbound-Bytes", "in", @in.ToString()); add("Active-Readers", "ar", ar.ToString()); } add("Last-Heartbeat", "last-heartbeat", (lastBeat == 0 ? "never" : (unchecked (now - lastBeat) / 1000 + "s ago")) + (bridge.IsBeating ? " (mid-beat)" : "")); add("Last-Multiplexer-Heartbeat", "last-mbeat", multiplexer.LastHeartbeatSecondsAgo + "s ago"); add("Last-Global-Heartbeat", "global", ConnectionMultiplexer.LastGlobalHeartbeatSecondsAgo + "s ago"); #if !__MonoCS__ var mgr = bridge.Multiplexer.SocketManager; add("SocketManager-State", "mgr", mgr.State.ToString()); add("Last-Error", "err", mgr.LastErrorTimeRelative()); #endif var ex = innerException == null ? new RedisConnectionException(failureType, exMessage.ToString()) : new RedisConnectionException(failureType, exMessage.ToString(), innerException); foreach (var kv in data) { ex.Data["Redis-" + kv.Item1] = kv.Item2; } managerState = SocketManager.ManagerState.RecordConnectionFailed_OnConnectionFailed; bridge.OnConnectionFailed(this, failureType, ex); } // cleanup managerState = SocketManager.ManagerState.RecordConnectionFailed_FailOutstanding; lock (outstanding) { bridge.Trace(outstanding.Count != 0, "Failing outstanding messages: " + outstanding.Count); while (outstanding.Count != 0) { var next = outstanding.Dequeue(); bridge.Trace("Failing: " + next); next.Fail(failureType, innerException); bridge.CompleteSyncOrAsync(next); } } // burn the socket managerState = SocketManager.ManagerState.RecordConnectionFailed_ShutdownSocket; var socketManager = multiplexer.SocketManager; if (socketManager != null) { socketManager.Shutdown(socketToken); } }