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); }
internal Task <T> QueueDirectAsync <T>(Message message, ResultProcessor <T> processor, object asyncState = null, PhysicalBridge bridge = null) { var tcs = TaskSource.CreateDenyExecSync <T>(asyncState); var source = ResultBox <T> .Get(tcs); message.SetSource(processor, source); if (bridge == null) { bridge = GetBridge(message.Command); } if (!bridge.TryEnqueue(message, isSlave)) { ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, this, multiplexer.GetServerSnapshot())); } return(tcs.Task); }