private WriteResult HandleWriteException(Message message, Exception ex) { var inner = new RedisConnectionException(ConnectionFailureType.InternalFailure, "Failed to write", ex); message.SetExceptionAndComplete(inner, this); return(WriteResult.WriteFailure); }
internal static Exception NoConnectionAvailable(bool includeDetail, bool includePerformanceCounters, RedisCommand command, Message message, ServerEndPoint server, ReadOnlySpan <ServerEndPoint> serverSnapshot) { string commandLabel = GetLabel(includeDetail, command, message); if (server != null) { //if we already have the serverEndpoint for connection failure use that //otherwise it would output state of all the endpoints serverSnapshot = new ServerEndPoint[] { server }; } var innerException = PopulateInnerExceptions(serverSnapshot); StringBuilder exceptionmessage = new StringBuilder("No connection is available to service this operation: ").Append(commandLabel); string innermostExceptionstring = GetInnerMostExceptionMessage(innerException); if (!string.IsNullOrEmpty(innermostExceptionstring)) { exceptionmessage.Append("; ").Append(innermostExceptionstring); } if (includeDetail) { exceptionmessage.Append("; ").Append(PerfCounterHelper.GetThreadPoolAndCPUSummary(includePerformanceCounters)); } var ex = new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, exceptionmessage.ToString(), innerException, message?.Status ?? CommandStatus.Unknown); if (includeDetail) { AddDetail(ex, message, server, commandLabel); } return(ex); }
internal static Exception ConnectionFailure(bool includeDetail, ConnectionFailureType failureType, string message, ServerEndPoint server) { var ex = new RedisConnectionException(failureType, message); if (includeDetail) { AddExceptionDetail(ex, null, server, null); } return(ex); }
internal static Exception NoConnectionAvailable(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server) { string s = GetLabel(includeDetail, command, message); var ex = new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, "No connection is available to service this operation: " + s); if (includeDetail) { AddDetail(ex, message, server, s); } return(ex); }
internal static Exception NoConnectionAvailable(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server, ServerEndPoint[] serverSnapshot) { string s = GetLabel(includeDetail, command, message); if (server != null) { //if we already have the serverEndpoint for connection failure use that //otherwise it would output state of all the endpoints serverSnapshot = new ServerEndPoint[] { server }; } string exceptionmessage = "No connection is available to service this operation: " + s; var ex = new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, exceptionmessage, GetServerSnapshotInnerExceptions(serverSnapshot)); if (includeDetail) { AddDetail(ex, message, server, s); } return(ex); }
internal static Exception NoConnectionAvailable( ConnectionMultiplexer multiplexer, Message message, ServerEndPoint server, ReadOnlySpan <ServerEndPoint> serverSnapshot = default, RedisCommand command = default) { string commandLabel = GetLabel(multiplexer.IncludeDetailInExceptions, message?.Command ?? command, message); if (server != null) { //if we already have the serverEndpoint for connection failure use that //otherwise it would output state of all the endpoints serverSnapshot = new ServerEndPoint[] { server }; } var innerException = PopulateInnerExceptions(serverSnapshot == default ? multiplexer.GetServerSnapshot() : serverSnapshot); // Try to get a useful error message for the user. long attempts = multiplexer._connectAttemptCount, completions = multiplexer._connectCompletedCount; string initialMessage; // We only need to customize the connection if we're aborting on connect fail // The "never" case would have thrown, if this was true if (!multiplexer.RawConfig.AbortOnConnectFail && attempts <= multiplexer.RawConfig.ConnectRetry && completions == 0) { // Initial attempt, attempted use before an async connection completes initialMessage = $"Connection to Redis never succeeded (attempts: {attempts} - connection likely in-progress), unable to service operation: "; } else if (!multiplexer.RawConfig.AbortOnConnectFail && attempts > multiplexer.RawConfig.ConnectRetry && completions == 0) { // Attempted use after a full initial retry connect count # of failures // This can happen in Azure often, where user disables abort and has the wrong config initialMessage = $"Connection to Redis never succeeded (attempts: {attempts} - check your config), unable to service operation: "; } else { // Default if we don't have a more useful error message here based on circumstances initialMessage = "No connection is active/available to service this operation: "; } StringBuilder sb = new StringBuilder(initialMessage); sb.Append(commandLabel); string innermostExceptionstring = GetInnerMostExceptionMessage(innerException); if (!string.IsNullOrEmpty(innermostExceptionstring)) { sb.Append("; ").Append(innermostExceptionstring); } // Add counters and exception data if we have it List <Tuple <string, string> > data = null; if (multiplexer.IncludeDetailInExceptions) { data = new List <Tuple <string, string> >(); AddCommonDetail(data, sb, message, multiplexer, server); } var ex = new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, sb.ToString(), innerException, message?.Status ?? CommandStatus.Unknown); if (multiplexer.IncludeDetailInExceptions) { CopyDataToException(data, ex); sb.Append("; ").Append(PerfCounterHelper.GetThreadPoolAndCPUSummary(multiplexer.IncludePerformanceCountersInExceptions)); AddExceptionDetail(ex, message, server, commandLabel); } return(ex); }
/// <summary> /// This writes a message to the output stream /// </summary> /// <param name="physical">The phsyical connection to write to.</param> /// <param name="message">The message to be written.</param> internal WriteResult WriteMessageTakingWriteLock(PhysicalConnection physical, Message message) { Trace("Writing: " + message); message.SetEnqueued(); WriteResult result; bool haveLock = false; try { Monitor.TryEnter(SingleWriterLock, TimeoutMilliseconds, ref haveLock); if (!haveLock) { message.Cancel(); Multiplexer?.OnMessageFaulted(message, null); this.CompleteSyncOrAsync(message); return(WriteResult.TimeoutBeforeWrite); } var existingMessage = Interlocked.CompareExchange(ref _activeMesssage, message, null); if (existingMessage != null) { Multiplexer?.OnInfoMessage($"reentrant call to WriteMessageTakingWriteLock for {message.CommandAndKey}, {existingMessage.CommandAndKey} is still active"); return(WriteResult.NoConnectionAvailable); } physical.SetWriting(); var messageIsSent = false; if (message is IMultiMessage) { SelectDatabaseInsideWriteLock(physical, message); // need to switch database *before* the transaction foreach (var subCommand in ((IMultiMessage)message).GetMessages(physical)) { result = WriteMessageToServerInsideWriteLock(physical, subCommand); if (result != WriteResult.Success) { // we screwed up; abort; note that WriteMessageToServer already // killed the underlying connection Trace("Unable to write to server"); message.Fail(ConnectionFailureType.ProtocolFailure, null, "failure before write: " + result.ToString()); this.CompleteSyncOrAsync(message); return(result); } //The parent message (next) may be returned from GetMessages //and should not be marked as sent again below messageIsSent = messageIsSent || subCommand == message; } if (!messageIsSent) { message.SetRequestSent(); // well, it was attempted, at least... } result = WriteResult.Success; } else { result = WriteMessageToServerInsideWriteLock(physical, message); } if (result == WriteResult.Success) { result = physical.FlushSync(); } physical.SetIdle(); } catch (Exception ex) { var inner = new RedisConnectionException(ConnectionFailureType.InternalFailure, "Failed to write", ex); message.SetExceptionAndComplete(inner, this); result = WriteResult.WriteFailure; } finally { if (haveLock) { Interlocked.CompareExchange(ref _activeMesssage, null, message); // remove if it is us Monitor.Exit(SingleWriterLock); } } return(result); }