コード例 #1
0
        private StackRedis.RedisResult Eval(ScriptType scriptType, StackRedis.RedisKey redisKey, StackRedis.RedisValue[] values = null, StackRedis.CommandFlags flags = StackRedis.CommandFlags.None)
        {
            if (!this.scriptsLoaded)
            {
                lock (this.loadScriptLock)
                {
                    if (!this.scriptsLoaded)
                    {
                        this.LoadScripts();
                        this.scriptsLoaded = true;
                    }
                }
            }

            StackRedis.LoadedLuaScript script;
            if (!this.shaScripts.TryGetValue(scriptType, out script))
            {
                throw new InvalidOperationException("Something went wrong during loading scripts to the server.");
            }

            try
            {
                return(this.Database.ScriptEvaluate(script.Hash, new[] { redisKey }, values, flags));
            }
            catch (StackRedis.RedisServerException ex) when(ex.Message.StartsWith("NOSCRIPT", StringComparison.OrdinalIgnoreCase))
            {
                this.LoadScripts();

                // retry
                throw;
            }
        }
コード例 #2
0
        private StackRedis.RedisResult Eval(ScriptType scriptType, StackRedis.RedisKey redisKey, StackRedis.RedisValue[] values = null, StackRedis.CommandFlags flags = StackRedis.CommandFlags.None)
        {
            if (!this.scriptsLoaded)
            {
                lock (this.lockObject)
                {
                    if (!this.scriptsLoaded)
                    {
                        this.LoadScripts();
                        this.scriptsLoaded = true;
                    }
                }
            }

            StackRedis.LoadedLuaScript script;
            if (!this.shaScripts.TryGetValue(scriptType, out script))
            {
                this.Logger.LogCritical("Something is wrong with the Lua scripts. Seem to be not loaded.");
                this.scriptsLoaded = false;
                throw new InvalidOperationException("Something is wrong with the Lua scripts. Seem to be not loaded.");
            }

            try
            {
                return(this.connection.Database.ScriptEvaluate(script.Hash, new[] { redisKey }, values, flags));
            }
            catch (StackRedis.RedisServerException ex) when(ex.Message.StartsWith("NOSCRIPT", StringComparison.OrdinalIgnoreCase))
            {
                this.Logger.LogInfo("Received NOSCRIPT from server. Reloading scripts...");
                this.LoadScripts();

                // retry
                throw;
            }
        }
コード例 #3
0
 public CommandKeyValueValueValueMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value0, RedisValue value1, RedisValue value2) : base(db, flags, command, key)
 {
     value0.AssertNotNull();
     value1.AssertNotNull();
     value2.AssertNotNull();
     this.value0 = value0;
     this.value1 = value1;
     this.value2 = value2;
 }
コード例 #4
0
 public CommandKeyValuesMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue[] values) : base(db, flags, command, key)
 {
     for (int i = 0; i < values.Length; i++)
     {
         values[i].AssertNotNull();
     }
     this.values = values;
 }
コード例 #5
0
 public CommandKeyValueMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value) : base(db, flags, command, key)
 {
     value.AssertNotNull();
     this.value = value;
 }
コード例 #6
0
 public CommandKeyMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key) : base(db, flags, command, key)
 {
 }
コード例 #7
0
 public CommandKeyKeysMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisKey[] keys) : base(db, flags, command, key)
 {
     for (int i = 0; i < keys.Length; i++)
     {
         keys[i].AssertNotNull();
     }
     this.keys = keys;
 }
コード例 #8
0
 /// <summary>
 /// Create a key associated with a value that is obtained by deserializing the provided serialized value (obtained via DUMP).
 /// If ttl is 0 the key is created without any expire, otherwise the specified expire time(in milliseconds) is set.
 /// </summary>
 /// <param name="key">The key to restore.</param>
 /// <param name="value">The value of the key.</param>
 /// <remarks>https://redis.io/commands/restore</remarks>
 public Task RestoreAsync(StackExchange.Redis.RedisKey key, byte[] value)
 {
     return(RedisDb.KeyRestoreAsync(KeyName, value));
 }
コード例 #9
0
 internal static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisValue[] values, RedisKey key1)
 {
     if (values == null)
     {
         throw new ArgumentNullException("values");
     }
     return(new CommandKeyValuesKeyMessage(db, flags, command, key0, values, key1));
 }
コード例 #10
0
        internal static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue[] values)
        {
            if (values == null)
            {
                throw new ArgumentNullException("values");
            }
            switch (values.Length)
            {
            case 0: return(new CommandKeyMessage(db, flags, command, key));

            case 1: return(new CommandKeyValueMessage(db, flags, command, key, values[0]));

            case 2: return(new CommandKeyValueValueMessage(db, flags, command, key, values[0], values[1]));

            case 3: return(new CommandKeyValueValueValueMessage(db, flags, command, key, values[0], values[1], values[2]));

            case 4: return(new CommandKeyValueValueValueValueMessage(db, flags, command, key, values[0], values[1], values[2], values[3]));

            default: return(new CommandKeyValuesMessage(db, flags, command, key, values));
            }
        }
コード例 #11
0
        internal static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisKey[] keys)
        {
            switch (keys.Length)
            {
            case 0: return(new CommandKeyMessage(db, flags, command, key));

            case 1: return(new CommandKeyKeyMessage(db, flags, command, key, keys[0]));

            case 2: return(new CommandKeyKeyKeyMessage(db, flags, command, key, keys[0], keys[1]));

            default: return(new CommandKeyKeysMessage(db, flags, command, key, keys));
            }
        }
コード例 #12
0
 public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisValue value, RedisKey key)
 {
     return(new CommandValueKeyMessage(db, flags, command, value, key));
 }
コード例 #13
0
 public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value0, RedisValue value1, RedisValue value2, RedisValue value3)
 {
     return(new CommandKeyValueValueValueValueMessage(db, flags, command, key, value0, value1, value2, value3));
 }
コード例 #14
0
 public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisKey key1, RedisKey key2)
 {
     return(new CommandKeyKeyKeyMessage(db, flags, command, key0, key1, key2));
 }
コード例 #15
0
 /// <summary>
 /// Serialize the value stored at key in a Redis-specific format and return it to the user. The returned value can be synthesized back into a Redis key using the RESTORE command.
 /// </summary>
 /// <param name="key">The key to dump.</param>
 /// <returns>the serialized value.</returns>
 /// <remarks>https://redis.io/commands/dump</remarks>
 public Task <byte[]> DumpAsync(StackExchange.Redis.RedisKey key)
 {
     return(RedisDb.KeyDumpAsync(KeyName));
 }
コード例 #16
0
        internal void AutoConfigure(PhysicalConnection connection)
        {
            if (serverType == ServerType.Twemproxy)
            {
                // don't try to detect configuration; all the config commands are disabled, and
                // the fallback master/slave detection won't help
                return;
            }

            var commandMap = Multiplexer.CommandMap;

#pragma warning disable CS0618
            const CommandFlags flags = CommandFlags.FireAndForget | CommandFlags.HighPriority | CommandFlags.NoRedirect;
#pragma warning restore CS0618
            var     features = GetFeatures();
            Message msg;

#pragma warning disable CS0618
            if (commandMap.IsAvailable(RedisCommand.CONFIG))
            {
                if (Multiplexer.RawConfig.KeepAlive <= 0)
                {
                    msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.timeout);
                    msg.SetInternalCall();
                    WriteDirectOrQueueFireAndForgetSync(connection, msg, ResultProcessor.AutoConfigure);
                }
                msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.slave_read_only);
                msg.SetInternalCall();
                WriteDirectOrQueueFireAndForgetSync(connection, msg, ResultProcessor.AutoConfigure);
                msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.databases);
                msg.SetInternalCall();
                WriteDirectOrQueueFireAndForgetSync(connection, msg, ResultProcessor.AutoConfigure);
            }
            if (commandMap.IsAvailable(RedisCommand.INFO))
            {
                lastInfoReplicationCheckTicks = Environment.TickCount;
                if (features.InfoSections)
                {
                    msg = Message.Create(-1, flags, RedisCommand.INFO, RedisLiterals.replication);
                    msg.SetInternalCall();
                    WriteDirectOrQueueFireAndForgetSync(connection, msg, ResultProcessor.AutoConfigure);

                    msg = Message.Create(-1, flags, RedisCommand.INFO, RedisLiterals.server);
                    msg.SetInternalCall();
                    WriteDirectOrQueueFireAndForgetSync(connection, msg, ResultProcessor.AutoConfigure);
                }
                else
                {
                    msg = Message.Create(-1, flags, RedisCommand.INFO);
                    msg.SetInternalCall();
                    WriteDirectOrQueueFireAndForgetSync(connection, msg, ResultProcessor.AutoConfigure);
                }
            }
            else if (commandMap.IsAvailable(RedisCommand.SET))
            {
                // this is a nasty way to find if we are a slave, and it will only work on up-level servers, but...
                RedisKey key = Multiplexer.UniqueId;
                msg = Message.Create(0, flags, RedisCommand.SET, key, RedisLiterals.slave_read_only, RedisLiterals.PX, 1, RedisLiterals.NX);
                msg.SetInternalCall();
                WriteDirectOrQueueFireAndForgetSync(connection, msg, ResultProcessor.AutoConfigure);
            }
            if (commandMap.IsAvailable(RedisCommand.CLUSTER))
            {
                msg = Message.Create(-1, flags, RedisCommand.CLUSTER, RedisLiterals.NODES);
                msg.SetInternalCall();
                WriteDirectOrQueueFireAndForgetSync(connection, msg, ResultProcessor.ClusterNodes);
            }
#pragma warning restore CS0618
        }
コード例 #17
0
        /// <summary>
        /// 锁住可用的资源,此方法是发布订阅模式,性能较好,推荐使用
        /// </summary>
        /// <param name="connectionMultiplexer">连接转换器,此处的连接器必须是可写的DB</param>
        /// <param name="key">键</param>
        /// <param name="action">动作</param>
        /// <param name="dbIndex">数据库索引</param>
        /// <param name="timeoutMilliSecond">超时毫秒,默认为5秒</param>
        /// <param name="flags">命令标记</param>
        public static void LockTake(this IConnectionMultiplexer connectionMultiplexer, RedisKey key, Action action, int dbIndex = -1, int timeoutMilliSecond = 5000, CommandFlags flags = CommandFlags.None)
        {
            var channel    = StringUtil.NewShortGuid();
            var subscriber = connectionMultiplexer.GetSubscriber();
            var db         = connectionMultiplexer.GetDatabase(dbIndex);

            // 将进入的都加入到队列里,将频道唯一值作为队列值
            var count = db.ListLeftPush(key, channel, flags: flags);

            // 如果大于1,说明已经被其他地方锁定资源,需要监听等待触发释放锁
            if (count > 1)
            {
                // 线程互斥对象
                var auto = new AutoResetEvent(false);

                // 是否已执行业务
                var isExecuted = false;
                subscriber.SubscribeAsync(channel, (myChannel, channelValue) =>
                {
                    if (isExecuted)
                    {
                        subscriber.UnsubscribeAsync(channel, flags: flags);
                        return;
                    }

                    isExecuted = true;
                    subscriber.UnsubscribeAsync(channel, flags: flags);

                    auto.Set();
                    ExecLockAction(subscriber, db, key, action, flags);
                }, flags: flags);

                // 等待超时,如果超时后还未执行,则手动执行,预防死锁
                auto.WaitOne(timeoutMilliSecond);
                if (isExecuted)
                {
                    return;
                }
                else
                {
                    isExecuted = true;
                    // 移除队列的元素
                    db.ListRemoveAsync(key, channel, flags: flags);
                    subscriber.UnsubscribeAsync(channel, flags: flags);
                    ExecLockAction(subscriber, db, key, action, flags);
                }
            }
            else
            {
                // 排除第1个队列值
                db.ListRightPop(key, flags: flags);
                ExecLockAction(subscriber, db, key, action, flags);
            }
        }
コード例 #18
0
 public CommandKeyBase(int db, CommandFlags flags, RedisCommand command, RedisKey key) : base(db, flags, command)
 {
     key.AssertNotNull();
     this.Key = key;
 }
コード例 #19
0
 public CommandKeyKeyMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisKey key1) : base(db, flags, command, key0)
 {
     key1.AssertNotNull();
     this.key1 = key1;
 }
コード例 #20
0
        public ServerEndPoint Select(int db, RedisCommand command, RedisKey key, CommandFlags flags)
        {
            int slot = serverType == ServerType.Cluster ? HashSlot(key) : NoSlot;

            return(Select(slot, command, flags));
        }