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); }
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); }
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); }
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))); }
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(); }
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))); }
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); }