示例#1
0
        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));
        }
示例#2
0
        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));
        }
示例#3
0
        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);
                }
            }
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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);
            }
        }