Exemple #1
0
        /// <summary>
        /// 临时任务(程序重启会丢失)
        /// </summary>
        /// <param name="timeout"></param>
        /// <param name="handle"></param>
        /// <returns></returns>
        public string AddTempTask(TimeSpan timeout, Action handle)
        {
            var id  = Guid.NewGuid().ToString();
            var bus = new IdleTimeout(() =>
            {
                _ib.TryRemove(id);
                Interlocked.Decrement(ref _quantityTempTask);
                if (handle != null)
                {
                    _wq.Enqueue(handle);
                }
            });

            if (_ib.TryRegister(id, () => bus, timeout))
            {
                _ib.Get(id);
                Interlocked.Increment(ref _quantityTempTask);
            }
            return(id);
        }
Exemple #2
0
            internal void ResetSentinel()
            {
                if (ResetSentinelFlag != 0)
                {
                    return;
                }
                if (Interlocked.Increment(ref ResetSentinelFlag) != 1)
                {
                    Interlocked.Decrement(ref ResetSentinelFlag);
                    return;
                }
                string masterhostEnd = _masterHost;
                var    allkeys       = _ib.GetKeys().ToList();

                for (int i = 0; i < _sentinels.Count; i++)
                {
                    if (i > 0)
                    {
                        var first = _sentinels.First;
                        _sentinels.RemoveFirst();
                        _sentinels.AddLast(first.Value);
                    }

                    try
                    {
                        using (var sentinelcli = new RedisSentinelClient(_sentinels.First.Value))
                        {
                            var masterhost             = sentinelcli.GetMasterAddrByName(_connectionString.Host);
                            var masterConnectionString = localTestHost(masterhost, RoleType.Master);
                            if (masterConnectionString == null)
                            {
                                continue;
                            }
                            masterhostEnd = masterhost;

                            if (_rw_splitting)
                            {
                                foreach (var slave in sentinelcli.Salves(_connectionString.Host))
                                {
                                    ConnectionStringBuilder slaveConnectionString = localTestHost($"{slave.ip}:{slave.port}", RoleType.Slave);
                                    if (slaveConnectionString == null)
                                    {
                                        continue;
                                    }
                                }
                            }

                            foreach (var sentinel in sentinelcli.Sentinels(_connectionString.Host))
                            {
                                var remoteSentinelHost = $"{sentinel.ip}:{sentinel.port}";
                                if (_sentinels.Contains(remoteSentinelHost))
                                {
                                    continue;
                                }
                                _sentinels.AddLast(remoteSentinelHost);
                            }
                        }
                        break;
                    }
                    catch { }
                }

                foreach (var spkey in allkeys)
                {
                    _ib.TryRemove(spkey, true);
                }
                Interlocked.Exchange(ref _masterHost, masterhostEnd);
                Interlocked.Decrement(ref ResetSentinelFlag);

                ConnectionStringBuilder localTestHost(string host, RoleType role)
                {
                    ConnectionStringBuilder connectionString = _connectionString.ToString();

                    connectionString.Host        = host;
                    connectionString.MinPoolSize = 1;
                    connectionString.MaxPoolSize = 1;
                    using (var cli = new RedisClient(connectionString))
                    {
                        if (cli.Role().role != role)
                        {
                            return(null);
                        }

                        if (role == RoleType.Master)
                        {
                            //test set/get
                        }
                    }
                    connectionString.MinPoolSize = connectionString.MinPoolSize;
                    connectionString.MaxPoolSize = connectionString.MaxPoolSize;

                    _ib.TryRegister(host, () => new RedisClientPool(connectionString, null, TopOwner));
                    allkeys.Remove(host);

                    return(connectionString);
                }
            }
            void RefershClusterNodes()
            {
                foreach (var testConnection in _clusterConnectionStrings)
                {
                    RegisterClusterNode(testConnection);
                    //尝试求出其他节点,并缓存slot
                    try
                    {
                        var cnodes = AdapterCall <string>("CLUSTER".SubCommand("NODES"), rt => rt.ThrowOrValue <string>()).Split('\n');
                        foreach (var cnode in cnodes)
                        {
                            if (string.IsNullOrEmpty(cnode))
                            {
                                continue;
                            }
                            var dt = cnode.Trim().Split(' ');
                            if (dt.Length < 9)
                            {
                                continue;
                            }
                            if (!dt[2].StartsWith("master") && !dt[2].EndsWith("master"))
                            {
                                continue;
                            }
                            if (dt[7] != "connected")
                            {
                                continue;
                            }

                            var endpoint = dt[1];
                            var at40     = endpoint.IndexOf('@');
                            if (at40 != -1)
                            {
                                endpoint = endpoint.Remove(at40);
                            }

                            if (endpoint.StartsWith("127.0.0.1"))
                            {
                                endpoint = $"{DefaultRedisSocket.SplitHost(testConnection.Host).Key}:{endpoint.Substring(10)}";
                            }
                            else if (endpoint.StartsWith("localhost", StringComparison.CurrentCultureIgnoreCase))
                            {
                                endpoint = $"{DefaultRedisSocket.SplitHost(testConnection.Host).Key}:{endpoint.Substring(10)}";
                            }
                            ConnectionStringBuilder connectionString = testConnection.ToString();
                            connectionString.Host = endpoint;
                            RegisterClusterNode(connectionString);

                            for (var slotIndex = 8; slotIndex < dt.Length; slotIndex++)
                            {
                                var slots = dt[slotIndex].Split('-');
                                if (ushort.TryParse(slots[0], out var tryslotStart) &&
                                    ushort.TryParse(slots[1], out var tryslotEnd))
                                {
                                    for (var slot = tryslotStart; slot <= tryslotEnd; slot++)
                                    {
                                        _slotCache.AddOrUpdate(slot, connectionString.Host, (k1, v1) => connectionString.Host);
                                    }
                                }
                            }
                        }
                        break;
                    }
                    catch
                    {
                        _ib.TryRemove(testConnection.Host, true);
                    }
                }

                if (_ib.GetKeys().Length == 0)
                {
                    throw new RedisClientException($"All \"clusterConnectionStrings\" failed to connect");
                }
            }