Ejemplo n.º 1
0
            public override IRedisSocket GetRedisSocket(CommandPacket cmd)
            {
                var slots    = cmd._flagKey.Select(a => GetClusterSlot(a)).Distinct().ToArray();
                var poolkeys = slots.Select(a => _slotCache.TryGetValue(a, out var trykey) ? trykey : null).Distinct().Where(a => a != null).ToArray();

                if (poolkeys.Length > 1)
                {
                    throw new RedisClientException($"Multiple key slot values not equal: {cmd}");
                }
                var poolkey = poolkeys.FirstOrDefault() ?? _ib.GetKeyFirst();

                var pool = _ib.Get(poolkey);

                if (pool.IsAvailable == false)
                {
                    poolkey = _ib.GetKeys(a => a != null && a.IsAvailable).FirstOrDefault();
                    if (string.IsNullOrEmpty(poolkey))
                    {
                        throw new RedisClientException($"All nodes of the cluster failed to connect");
                    }
                    pool = _ib.Get(poolkey);
                }
                var cli      = pool.Get();
                var rds      = cli.Value.Adapter.GetRedisSocket(null);
                var rdsproxy = DefaultRedisSocket.CreateTempProxy(rds, () => pool.Return(cli));

                rdsproxy._pool = pool;
                return(rdsproxy);
            }
Ejemplo n.º 2
0
            string GetIdleBusKey(CommandPacket cmd)
            {
                if (cmd != null && (_rw_splitting || !_is_single))
                {
                    var cmdset = CommandSets.Get(cmd._command);
                    if (cmdset != null)
                    {
                        if (!_is_single && (cmdset.Status & CommandSets.LocalStatus.check_single) == CommandSets.LocalStatus.check_single)
                        {
                            throw new RedisClientException($"Method cannot be used in {UseType} mode. You can set \"max pool size=1\", but it is not singleton mode.");
                        }

                        if (_rw_splitting &&
                            ((cmdset.Tag & CommandSets.ServerTag.read) == CommandSets.ServerTag.read ||
                             (cmdset.Flag & CommandSets.ServerFlag.@readonly) == CommandSets.ServerFlag.@readonly))
                        {
                            var rndkeys = _ib.GetKeys(v => v == null || v.IsAvailable && v._policy._connectionStringBuilder.Host != _masterHost);
                            if (rndkeys.Any())
                            {
                                var rndkey = rndkeys[_rnd.Value.Next(0, rndkeys.Length)];
                                return(rndkey);
                            }
                        }
                    }
                }
                return(_masterHost);
            }
Ejemplo n.º 3
0
            public override IRedisSocket GetRedisSocket(CommandPacket cmd)
            {
                var slots    = cmd?._keyIndexes.Select(a => GetClusterSlot(cmd._input[a].ToInvariantCultureToString())).Distinct().ToArray();
                var poolkeys = slots?.Select(a => _slotCache.TryGetValue(a, out var trykey) ? trykey : null).Distinct().Where(a => a != null).ToArray();
                //if (poolkeys.Length > 1) throw new RedisClientException($"CROSSSLOT Keys in request don't hash to the same slot: {cmd}");
                var poolkey = poolkeys?.FirstOrDefault();

goto_getrndkey:
                if (string.IsNullOrEmpty(poolkey))
                {
                    var rndkeys = _ib.GetKeys(v => v == null || v.IsAvailable);
                    if (rndkeys.Any() == false)
                    {
                        throw new RedisClientException($"All nodes of the cluster failed to connect");
                    }
                    poolkey = rndkeys[_rnd.Value.Next(0, rndkeys.Length)];
                }
                var pool = _ib.Get(poolkey);

                if (pool.IsAvailable == false)
                {
                    poolkey = null;
                    goto goto_getrndkey;
                }
                var cli      = pool.Get();
                var rds      = cli.Value.Adapter.GetRedisSocket(null);
                var rdsproxy = DefaultRedisSocket.CreateTempProxy(rds, () => pool.Return(cli));

                rdsproxy._poolkey = poolkey;
                rdsproxy._pool    = pool;
                return(rdsproxy);
            }
Ejemplo n.º 4
0
            public override IRedisSocket GetRedisSocket(CommandPacket cmd)
            {
                if (_rw_splitting && cmd != null)
                {
                    var cmdcfg = CommandConfig.Get(cmd._command);
                    if (cmdcfg != null)
                    {
                        if (
                            (cmdcfg.Tag & CommandTag.read) == CommandTag.read &&
                            (cmdcfg.Flag & CommandFlag.@readonly) == CommandFlag.@readonly)
                        {
                            var rndkeys = _ib.GetKeys(v => v == null || v.IsAvailable && v._policy._connectionStringBuilder.Host != _masterHost);
                            if (rndkeys.Any())
                            {
                                var rndkey  = rndkeys[_rnd.Value.Next(0, rndkeys.Length)];
                                var rndpool = _ib.Get(rndkey);
                                var rndcli  = rndpool.Get();
                                var rndrds  = rndcli.Value._adapter.GetRedisSocket(null);
                                return(new DefaultRedisSocket.TempRedisSocket(rndrds, () => rndpool.Return(rndcli)));
                            }
                        }
                    }
                }
                var poolkey = _masterHost;

                if (string.IsNullOrWhiteSpace(poolkey))
                {
                    throw new Exception("RedisClient.GetRedisSocket() Redis Sentinel Master is switching");
                }
                var pool = _ib.Get(poolkey);
                var cli  = pool.Get();
                var rds  = cli.Value._adapter.GetRedisSocket(null);

                return(new DefaultRedisSocket.TempRedisSocket(rds, () => pool.Return(cli)));
            }
Ejemplo n.º 5
0
 public override void Dispose()
 {
     foreach (var key in _ib.GetKeys())
     {
         var pool = _ib.Get(key);
         TopOwner.Unavailable?.Invoke(TopOwner, new UnavailableEventArgs(pool.Key, pool));
     }
     isdisposed = true;
     _ib.Dispose();
 }
Ejemplo n.º 6
0
            public override IRedisSocket GetRedisSocket(CommandPacket cmd)
            {
                if (cmd != null && (_rw_splitting || !_is_single))
                {
                    var cmdset = CommandSets.Get(cmd._command);
                    if (cmdset != null)
                    {
                        if (!_is_single && (cmdset.Status & CommandSets.LocalStatus.check_single) == CommandSets.LocalStatus.check_single)
                        {
                            throw new RedisException($"RedisClient: Method cannot be used in {UseType} mode. You can set \"max pool size=1\", but it is not singleton mode.");
                        }

                        if (_rw_splitting &&
                            ((cmdset.Tag & CommandSets.ServerTag.read) == CommandSets.ServerTag.read ||
                             (cmdset.Flag & CommandSets.ServerFlag.@readonly) == CommandSets.ServerFlag.@readonly))
                        {
                            var rndkeys = _ib.GetKeys(v => v == null || v.IsAvailable && v._policy._connectionStringBuilder.Host != _masterHost);
                            if (rndkeys.Any())
                            {
                                var rndkey  = rndkeys[_rnd.Value.Next(0, rndkeys.Length)];
                                var rndpool = _ib.Get(rndkey);
                                var rndcli  = rndpool.Get();
                                var rndrds  = rndcli.Value.Adapter.GetRedisSocket(null);
                                return(DefaultRedisSocket.CreateTempProxy(rndrds, () => rndpool.Return(rndcli)));
                            }
                        }
                    }
                }
                var poolkey = _masterHost;
                var pool    = _ib.Get(poolkey);
                var cli     = pool.Get();
                var rds     = cli.Value.Adapter.GetRedisSocket(null);

                return(DefaultRedisSocket.CreateTempProxy(rds, () => pool.Return(cli)));
            }
Ejemplo n.º 7
0
        public FreeSqlCloud <TDBKey> Register(TDBKey dbkey, Func <IFreeSql> create)
        {
            if (_ib.TryRegister(dbkey, create))
            {
                if (_ib.GetKeys().Length == 1)
                {
                    _dbkeyMaster = dbkey;
                    if (_distributeTraceEnable)
                    {
                        _distributedTraceCall($"{dbkey} 注册成功, 并存储 TCC/SAGA 事务相关数据");
                    }
                    _scheduler = new IdleScheduler.Scheduler(new IdleScheduler.TaskHandlers.TestHandler());

                    _ormMaster.CodeFirst.ConfigEntity <TccMasterInfo>(a => a.Name($"tcc_{DistributeKey}"));
                    _ormMaster.CodeFirst.SyncStructure <TccMasterInfo>();
                    _ormMaster.CodeFirst.ConfigEntity <TccUnitInfo>(a => a.Name($"tcc_{DistributeKey}_unit"));
                    _ormMaster.CodeFirst.SyncStructure <TccUnitInfo>();

                    _ormMaster.CodeFirst.ConfigEntity <SagaMasterInfo>(a => a.Name($"saga_{DistributeKey}"));
                    _ormMaster.CodeFirst.SyncStructure <SagaMasterInfo>();
                    _ormMaster.CodeFirst.ConfigEntity <SagaUnitInfo>(a => a.Name($"saga_{DistributeKey}_unit"));
                    _ormMaster.CodeFirst.SyncStructure <SagaUnitInfo>();

                    #region 加载历史未未成 TCC 事务
                    var tccPendings = _ormMaster.Select <TccMasterInfo>()
                                      .Where(a => a.Status == TccMasterStatus.Pending && a.RetryCount < a.MaxRetryCount)
                                      .OrderBy(a => a.CreateTime)
                                      .ToList();
                    foreach (var pending in tccPendings)
                    {
                        _scheduler.AddTempTask(TimeSpan.FromSeconds(pending.RetryInterval), TccMaster <TDBKey> .GetTempTask(this, pending.Tid, pending.Title, pending.RetryInterval));
                    }
                    if (_distributeTraceEnable)
                    {
                        _distributedTraceCall($"成功加载历史未完成 TCC 事务 {tccPendings.Count} 个");
                    }
                    #endregion

                    #region 加载历史未未成 SAGA 事务
                    var sagaPendings = _ormMaster.Select <SagaMasterInfo>()
                                       .Where(a => a.Status == SagaMasterStatus.Pending && a.RetryCount < a.MaxRetryCount)
                                       .OrderBy(a => a.CreateTime)
                                       .ToList();
                    foreach (var pending in sagaPendings)
                    {
                        _scheduler.AddTempTask(TimeSpan.FromSeconds(pending.RetryInterval), SagaMaster <TDBKey> .GetTempTask(this, pending.Tid, pending.Title, pending.RetryInterval));
                    }
                    if (_distributeTraceEnable)
                    {
                        _distributedTraceCall($"成功加载历史未完成 SAGA 事务 {sagaPendings.Count} 个");
                    }
                    #endregion
                }
            }
            return(this);
        }