public IEnumerable <RedisKey> Keys(int database = 0, RedisValue pattern = default(RedisValue), int pageSize = CursorUtils.DefaultPageSize, long cursor = CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None) { if (pageSize <= 0) { throw new ArgumentOutOfRangeException("pageSize"); } if (CursorUtils.IsNil(pattern)) { pattern = RedisLiterals.Wildcard; } if (multiplexer.CommandMap.IsAvailable(RedisCommand.SCAN)) { var features = server.GetFeatures(); if (features.Scan) { return(new KeysScanEnumerable(this, database, pattern, pageSize, cursor, pageOffset, flags)); } } if (cursor != 0 || pageOffset != 0) { throw ExceptionFactory.NoCursor(RedisCommand.KEYS); } Message msg = Message.Create(database, flags, RedisCommand.KEYS, pattern); return(ExecuteSync(msg, ResultProcessor.RedisKeyArray)); }
public IEnumerable <RedisKey> Keys(int database = 0, RedisValue pattern = default(RedisValue), int pageSize = KeysScanIterator.DefaultPageSize, CommandFlags flags = CommandFlags.None) { if (pageSize <= 0) { throw new ArgumentOutOfRangeException("pageSize"); } if (KeysScanIterator.IsNil(pattern)) { pattern = RedisLiterals.Wildcard; } if (multiplexer.CommandMap.IsAvailable(RedisCommand.SCAN)) { var features = server.GetFeatures(); if (features.Scan) { return(new KeysScanIterator(this, database, pattern, pageSize, flags).Read()); } } Message msg = Message.Create(database, flags, RedisCommand.KEYS, pattern); return(ExecuteSync(msg, ResultProcessor.RedisKeyArray)); }
internal void KeepAlive() { if (!(physical?.IsIdle() ?? false)) { return; // don't pile on if already doing something } var commandMap = Multiplexer.CommandMap; Message msg = null; var features = ServerEndPoint.GetFeatures(); switch (ConnectionType) { case ConnectionType.Interactive: msg = ServerEndPoint.GetTracerMessage(false); msg.SetSource(ResultProcessor.Tracer, null); break; case ConnectionType.Subscription: if (commandMap.IsAvailable(RedisCommand.PING) && features.PingOnSubscriber) { msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.PING); msg.SetSource(ResultProcessor.Tracer, null); } else if (commandMap.IsAvailable(RedisCommand.UNSUBSCRIBE)) { msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.UNSUBSCRIBE, (RedisChannel)Multiplexer.UniqueId); msg.SetSource(ResultProcessor.TrackSubscriptions, null); } break; } if (msg != null) { msg.SetInternalCall(); Multiplexer.Trace("Enqueue: " + msg); Multiplexer.OnInfoMessage($"heartbeat ({physical?.LastWriteSecondsAgo}s >= {ServerEndPoint?.WriteEverySeconds}s, {physical?.GetSentAwaitingResponseCount()} waiting) '{msg.CommandAndKey}' on '{PhysicalName}' (v{features.Version})"); physical?.UpdateLastWriteTime(); // pre-emptively #pragma warning disable CS0618 var result = TryWriteSync(msg, ServerEndPoint.IsSlave); #pragma warning restore CS0618 if (result != WriteResult.Success) { var ex = Multiplexer.GetException(result, msg, ServerEndPoint); OnInternalError(ex); } } }
private WriteResult WriteMessageToServerInsideWriteLock(PhysicalConnection connection, Message message) { if (message == null) { return(WriteResult.Success); // for some definition of success } bool isQueued = false; try { var cmd = message.Command; LastCommand = cmd; bool isMasterOnly = message.IsMasterOnly(); if (isMasterOnly && ServerEndPoint.IsSlave && (ServerEndPoint.SlaveReadOnly || !ServerEndPoint.AllowSlaveWrites)) { throw ExceptionFactory.MasterOnly(Multiplexer.IncludeDetailInExceptions, message.Command, message, ServerEndPoint); } switch (cmd) { case RedisCommand.QUIT: connection.RecordQuit(); break; case RedisCommand.EXEC: Multiplexer.OnPreTransactionExec(message); // testing purposes, to force certain errors break; } SelectDatabaseInsideWriteLock(connection, message); if (!connection.TransactionActive) { var readmode = connection.GetReadModeCommand(isMasterOnly); if (readmode != null) { connection.EnqueueInsideWriteLock(readmode); readmode.WriteTo(connection); readmode.SetRequestSent(); IncrementOpCount(); } if (message.IsAsking) { var asking = ReusableAskingCommand; connection.EnqueueInsideWriteLock(asking); asking.WriteTo(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.EnqueueInsideWriteLock(message); isQueued = true; message.WriteTo(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.UNKNOWN: case RedisCommand.DISCARD: case RedisCommand.EXEC: connection.SetUnknownDatabase(); break; } return(WriteResult.Success); } catch (RedisCommandException ex) when(!isQueued) { Trace("Write failed: " + ex.Message); message.Fail(ConnectionFailureType.InternalFailure, ex, null); this.CompleteSyncOrAsync(message); // this failed without actually writing; we're OK with that... unless there's a transaction if (connection?.TransactionActive == true) { // we left it in a broken state; need to kill the connection connection.RecordConnectionFailed(ConnectionFailureType.ProtocolFailure, ex); return(WriteResult.WriteFailure); } return(WriteResult.Success); } catch (Exception ex) { Trace("Write failed: " + ex.Message); message.Fail(ConnectionFailureType.InternalFailure, ex, null); this.CompleteSyncOrAsync(message); // we're not sure *what* happened here; probably an IOException; kill the connection connection?.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); return(WriteResult.WriteFailure); } }
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 if (connection != null) { connection.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); } return(false); } }