internal static Exception ConnectionFailure(bool includeDetail, ConnectionFailureType failureType, string message, ServerEndPoint server) { var ex = new RedisConnectionException(failureType, message); if (includeDetail) { AddDetail(ex, null, server, null); } return(ex); }
internal static Exception Timeout(bool includeDetail, string errorMessage, Message message, ServerEndPoint server) { var ex = new TimeoutException(errorMessage); if (includeDetail) { AddDetail(ex, message, server, null); } return(ex); }
internal static Exception CommandDisabled(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server) { string s = GetLabel(includeDetail, command, message); var ex = new RedisCommandException("This operation has been disabled in the command-map and cannot be used: " + 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 AdminModeNotEnabled(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server) { string s = GetLabel(includeDetail, command, message); var ex = new RedisCommandException("This operation is not available unless admin mode is enabled: " + s); if (includeDetail) { AddDetail(ex, message, server, s); } return(ex); }
public static ProfileStorage NewWithContext(ConcurrentProfileStorageCollection pushTo, ServerEndPoint server) { return(new ProfileStorage(pushTo, server, null, null)); }
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 - VolatileWrapper.Read(ref connectStartTicks)); if (connectTimeMilliseconds >= Multiplexer.RawConfig.ConnectTimeout) { LastException = ExceptionFactory.UnableToConnect("ConnectTimeout"); Trace("Aborting connect"); // abort and reconnect var snapshot = physical; bool isCurrent; State oldState; OnDisconnected(ConnectionFailureType.UnableToConnect, snapshot, out isCurrent, out oldState); using (snapshot) { } // dispose etc TryConnect(null); } if (!ifConnectedOnly) { AbortUnsent(); } break; case (int)State.ConnectedEstablishing: case (int)State.ConnectedEstablished: var tmp = physical; if (tmp != null) { if (state == (int)State.ConnectedEstablished) { tmp.Bridge.ServerEndPoint.ClearUnselectable(UnselectableFlags.DidNotRespond); } tmp.OnHeartbeat(); 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 { bool ignore; State oldState; OnDisconnected(ConnectionFailureType.SocketFailure, tmp, out ignore, out oldState); } } else if (!queue.Any() && 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: if (!ifConnectedOnly) { AbortUnsent(); Multiplexer.Trace("Resurrecting " + this.ToString()); GetConnection(null); } break; default: if (!ifConnectedOnly) { AbortUnsent(); } break; } } catch (Exception ex) { OnInternalError(ex); Trace("OnHeartbeat error: " + ex.Message); } finally { if (runThisTime) { Interlocked.Exchange(ref beating, 0); } } }
internal override Task <T> ExecuteAsync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { if (message == null) { return(CompletedTask <T> .Default(asyncState)); } multiplexer.CheckMessage(message); multiplexer.Trace("Wrapping " + message.Command, "Transaction"); // prepare the inner command as a task Task <T> task; if (message.IsFireAndForget) { task = CompletedTask <T> .Default(null); // F+F explicitly does not get async-state } else { var tcs = TaskSource.CreateDenyExecSync <T>(asyncState); var source = ResultBox <T> .Get(tcs); message.SetSource(source, processor); task = tcs.Task; } // prepare an outer-command that decorates that, but expects QUEUED var queued = new QueuedMessage(message); var wasQueued = ResultBox <bool> .Get(null); queued.SetSource(wasQueued, QueuedProcessor.Default); // store it, and return the task of the *outer* command // (there is no task for the inner command) (pending ?? (pending = new List <QueuedMessage>())).Add(queued); switch (message.Command) { case RedisCommand.EVAL: case RedisCommand.EVALSHA: // people can do very naughty things in an EVAL // including change the DB; change it back to what we // think it should be! var sel = PhysicalConnection.GetSelectDatabaseCommand(message.Db); queued = new QueuedMessage(sel); wasQueued = ResultBox <bool> .Get(null); queued.SetSource(wasQueued, QueuedProcessor.Default); pending.Add(queued); break; } return(task); }
internal virtual Task <T> ExecuteAsync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { if (message == null) { return(CompletedTask <T> .Default(asyncState)); } multiplexer.CheckMessage(message); return(multiplexer.ExecuteAsyncImpl <T>(message, processor, asyncState, server)); }
internal override RedisFeatures GetFeatures(int db, RedisKey key, CommandFlags flags, out ServerEndPoint server) { server = this.server; return(new RedisFeatures(server.Version)); }
internal override T ExecuteSync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { throw new NotSupportedException("ExecuteSync cannot be used inside a transaction"); }
internal override T ExecuteSync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { // inject our expected server automatically if (server == null) { server = this.server; } FixFlags(message, server); if (!server.IsConnected) { if (message == null || message.IsFireAndForget) { return(default(T)); } throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot()); } return(base.ExecuteSync <T>(message, processor, server)); }
internal override Task <T> ExecuteAsync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { // inject our expected server automatically if (server == null) { server = this.server; } FixFlags(message, server); if (!server.IsConnected) { if (message == null) { return(CompletedTask <T> .Default(asyncState)); } if (message.IsFireAndForget) { return(CompletedTask <T> .Default(null)); // F+F explicitly does not get async-state } // no need to deny exec-sync here; will be complete before they see if var tcs = TaskSource.Create <T>(asyncState); ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot())); return(tcs.Task); } return(base.ExecuteAsync <T>(message, processor, server)); }
private bool WriteMessageToServer(PhysicalConnection connection, Message message) { if (message == null) { return(true); } try { var cmd = message.Command; bool isMasterOnly = message.IsMasterOnly(); if (isMasterOnly && ServerEndPoint.IsSlave && (ServerEndPoint.SlaveReadOnly || !ServerEndPoint.AllowSlaveWrites)) { throw ExceptionFactory.MasterOnly(Multiplexer.IncludeDetailInExceptions, message.Command, message, ServerEndPoint); } SelectDatabase(connection, message); if (!connection.TransactionActive) { var readmode = connection.GetReadModeCommand(isMasterOnly); if (readmode != null) { connection.Enqueue(readmode); readmode.WriteTo(connection); readmode.SetRequestSent(); IncrementOpCount(); } if (message.IsAsking) { var asking = ReusableAskingCommand; connection.Enqueue(asking); asking.WriteImpl(connection); asking.SetRequestSent(); IncrementOpCount(); } } switch (cmd) { case RedisCommand.WATCH: case RedisCommand.MULTI: connection.TransactionActive = true; break; case RedisCommand.UNWATCH: case RedisCommand.EXEC: case RedisCommand.DISCARD: connection.TransactionActive = false; break; } connection.Enqueue(message); message.WriteImpl(connection); message.SetRequestSent(); IncrementOpCount(); // some commands smash our ability to trust the database; some commands // demand an immediate flush switch (cmd) { case RedisCommand.EVAL: case RedisCommand.EVALSHA: if (!ServerEndPoint.GetFeatures().ScriptingDatabaseSafe) { connection.SetUnknownDatabase(); } break; case RedisCommand.DISCARD: case RedisCommand.EXEC: connection.SetUnknownDatabase(); break; } return(true); } catch (RedisCommandException ex) { Trace("Write failed: " + ex.Message); message.Fail(ConnectionFailureType.ProtocolFailure, ex); CompleteSyncOrAsync(message); // this failed without actually writing; we're OK with that... unless there's a transaction if (connection != null && connection.TransactionActive) { // we left it in a broken state; need to kill the connection connection.RecordConnectionFailed(ConnectionFailureType.ProtocolFailure, ex); return(false); } return(true); } catch (Exception ex) { Trace("Write failed: " + ex.Message); message.Fail(ConnectionFailureType.InternalFailure, ex); CompleteSyncOrAsync(message); // we're not sure *what* happened here; probably an IOException; kill the connection connection?.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); return(false); } }
internal static Exception DatabaseOutfRange(bool includeDetail, int targetDatabase, Message message, ServerEndPoint server) { var ex = new RedisCommandException("The database does not exist on the server: " + targetDatabase); if (includeDetail) { AddDetail(ex, message, server, null); } return(ex); }
internal virtual T ExecuteSync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { if (message == null) { return(default(T)); // no-op } multiplexer.CheckMessage(message); return(multiplexer.ExecuteSyncImpl <T>(message, processor, server)); }
internal static Exception MasterOnly(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server) { string s = GetLabel(includeDetail, command, message); var ex = new RedisCommandException("Command cannot be issued to a slave: " + s); if (includeDetail) { AddDetail(ex, message, server, s); } return(ex); }
internal virtual RedisFeatures GetFeatures(int db, RedisKey key, CommandFlags flags, out ServerEndPoint server) { server = multiplexer.SelectServer(db, RedisCommand.PING, flags, key); var version = server == null ? multiplexer.RawConfig.DefaultVersion : server.Version; return(new RedisFeatures(version)); }
public static ProfileStorage NewAttachedToSameContext(ProfileStorage resentFor, ServerEndPoint server, bool isMoved) { return(new ProfileStorage(resentFor.PushToWhenFinished, server, resentFor, isMoved ? RetransmissionReasonType.Moved : RetransmissionReasonType.Ask)); }
internal override Task <T> ExecuteAsync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { if (message == null) { return(CompletedTask <T> .Default(asyncState)); } multiplexer.CheckMessage(message); // prepare the inner command as a task Task <T> task; if (message.IsFireAndForget) { task = CompletedTask <T> .Default(null); // F+F explicitly does not get async-state } else { var tcs = TaskSource.CreateDenyExecSync <T>(asyncState); var source = ResultBox <T> .Get(tcs); message.SetSource(source, processor); task = tcs.Task; } // store it (pending ?? (pending = new List <Message>())).Add(message); return(task); }