public override IRedisSocket GetRedisSocket(CommandPacket cmd) { TryMulti(); return(new DefaultRedisSocket.TempRedisSocket(_redisSocket, null)); }
Task <T[]> HReadArrayAsync <T>(CommandPacket cb) => CallAsync(cb.FlagReadbytes(true), rt => rt .ThrowOrValue((a, _) => a.Select(b => DeserializeRedisValue <T>(b.ConvertTo <byte[]>(), rt.Encoding)).ToArray()));
protected TValue Call <TReadTextOrStream, TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse) => Adapter.AdapaterCall <TReadTextOrStream, TValue>(cmd, parse);
public override TValue AdapterCall <TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse) { return(TopOwner.LogCall(cmd, () => { RedisResult rt = null; RedisClientPool pool = null; using (var rds = GetRedisSocket(cmd)) { pool = (rds as DefaultRedisSocket.TempProxyRedisSocket)._pool; try { if (cmd._clusterMovedAsking) { cmd._clusterMovedAsking = false; rds.Write("ASKING"); rds.Read(false); } rds.Write(cmd); rt = rds.Read(cmd._flagReadbytes); } catch (Exception ex) { if (pool?.SetUnavailable(ex) == true) { } throw ex; } } if (rt.IsError && pool != null) { var moved = ClusterMoved.ParseSimpleError(rt.SimpleError); if (moved != null && cmd._clusterMovedTryCount < 3) { cmd._clusterMovedTryCount++; if (moved.endpoint.StartsWith("127.0.0.1")) { moved.endpoint = $"{DefaultRedisSocket.SplitHost(pool._policy._connectionStringBuilder.Host).Key}:{moved.endpoint.Substring(10)}"; } else if (moved.endpoint.StartsWith("localhost", StringComparison.CurrentCultureIgnoreCase)) { moved.endpoint = $"{DefaultRedisSocket.SplitHost(pool._policy._connectionStringBuilder.Host).Key}:{moved.endpoint.Substring(10)}"; } ConnectionStringBuilder connectionString = pool._policy._connectionStringBuilder.ToString(); connectionString.Host = moved.endpoint; RegisterClusterNode(connectionString); if (moved.ismoved) { _slotCache.AddOrUpdate(moved.slot, connectionString.Host, (k1, v1) => connectionString.Host); } if (moved.isask) { cmd._clusterMovedAsking = true; } TopOwner.OnNotice(new NoticeEventArgs(NoticeType.Info, null, $"{(cmd.WriteHost ?? "Not connected")} > {cmd}\r\n{rt.SimpleError} ", null)); return AdapterCall(cmd, parse); } } rt.IsErrorThrow = TopOwner._isThrowRedisSimpleError; return parse(rt); })); }
public override IRedisSocket GetRedisSocket(CommandPacket cmd) { return(DefaultRedisSocket.CreateTempProxy(_redisSocket, null)); }
internal T LogCall <T>(CommandPacket cmd, Func <T> func) { cmd.Prefix(Prefix); var isnotice = this.Notice != null; var isaop = this.Interceptors.Any(); if (isnotice == false && isaop == false) { return(func()); } Exception exception = null; Stopwatch sw = default; if (isnotice) { sw = new Stopwatch(); sw.Start(); } T ret = default(T); var isaopval = false; IInterceptor[] aops = null; Stopwatch[] aopsws = null; if (isaop) { aops = new IInterceptor[this.Interceptors.Count]; aopsws = new Stopwatch[aops.Length]; for (var idx = 0; idx < aops.Length; idx++) { aopsws[idx] = new Stopwatch(); aopsws[idx].Start(); aops[idx] = this.Interceptors[idx]?.Invoke(); var args = new InterceptorBeforeEventArgs(this, cmd); aops[idx].Before(args); if (args.ValueIsChanged && args.Value is T argsValue) { isaopval = true; ret = argsValue; } } } try { if (isaopval == false) { ret = func(); } return(ret); } catch (Exception ex) { exception = ex; throw ex; } finally { if (isaop) { for (var idx = 0; idx < aops.Length; idx++) { aopsws[idx].Stop(); var args = new InterceptorAfterEventArgs(this, cmd, ret, exception, aopsws[idx].ElapsedMilliseconds); aops[idx].After(args); } } if (isnotice) { sw.Stop(); LogCallFinally(cmd, ret, sw, exception); } } }
protected Task <TValue> CallAsync <TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse) => Adapter.AdapterCallAsync(cmd, parse);
public object Call(CommandPacket cmd) => Adapter.AdapterCall(cmd, rt => rt.ThrowOrValue());
public abstract Task <TValue> AdapterCallAsync <TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse);
public Task <object> CallAsync(CommandPacket cmd) => Adapter.AdapterCallAsync(cmd, rt => rt.ThrowOrValue());
public abstract IRedisSocket GetRedisSocket(CommandPacket cmd);
T[] SReadArray <T>(CommandPacket cb) => Call(cb.FlagReadbytes(true), rt => rt .ThrowOrValue((a, _) => a == null || a.Length == 0 ? new T[0] : a.Select(b => DeserializeRedisValue <T>(b.ConvertTo <byte[]>(), rt.Encoding)).ToArray()));
public override IRedisSocket GetRedisSocket(CommandPacket cmd) { throw new Exception($"RedisClient: Method cannot be used in {UseType} mode."); }
public override TValue AdapterCall <TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse) { if (cmd._keyIndexes.Count > 1) //Multiple key slot values not equal { cmd.Prefix(TopOwner.Prefix); switch (cmd._command) { case "DEL": case "UNLINK": return(cmd._keyIndexes.Select((_, idx) => AdapterCall(cmd._command.InputKey(cmd.GetKey(idx)), parse)).Sum(a => a.ConvertTo <long>()).ConvertTo <TValue>()); case "MSET": cmd._keyIndexes.ForEach(idx => AdapterCall(cmd._command.InputKey(cmd._input[idx].ToInvariantCultureToString()).InputRaw(cmd._input[idx + 1]), parse)); return(default); case "MGET": return(cmd._keyIndexes.Select((_, idx) => { var rt = AdapterCall(cmd._command.InputKey(cmd.GetKey(idx)), parse); return rt.ConvertTo <object[]>().FirstOrDefault(); }).ToArray().ConvertTo <TValue>()); case "PFCOUNT": return(cmd._keyIndexes.Select((_, idx) => AdapterCall(cmd._command.InputKey(cmd.GetKey(idx)), parse)).Sum(a => a.ConvertTo <long>()).ConvertTo <TValue>()); } } return(TopOwner.LogCall(cmd, () => { RedisResult rt = null; RedisClientPool pool = null; var protocolRetry = false; using (var rds = GetRedisSocket(cmd)) { pool = (rds as DefaultRedisSocket.TempProxyRedisSocket)._pool; try { if (cmd._clusterMovedAsking) { cmd._clusterMovedAsking = false; var askingCmd = "ASKING".SubCommand(null).FlagReadbytes(false); rds.Write(askingCmd); rds.Read(askingCmd); } rds.Write(cmd); rt = rds.Read(cmd); } catch (ProtocolViolationException) { rds.ReleaseSocket(); cmd._protocolErrorTryCount++; if (cmd._protocolErrorTryCount <= pool._policy._connectionStringBuilder.Retry) { protocolRetry = true; } else { if (cmd.IsReadOnlyCommand() == false || cmd._protocolErrorTryCount > 1) { throw; } protocolRetry = true; } } catch (Exception ex) { if (pool?.SetUnavailable(ex) == true) { } throw; } } if (protocolRetry) { return AdapterCall(cmd, parse); } if (rt.IsError && pool != null) { var moved = ClusterMoved.ParseSimpleError(rt.SimpleError); if (moved != null && cmd._clusterMovedTryCount < 3) { cmd._clusterMovedTryCount++; if (moved.endpoint.StartsWith("127.0.0.1")) { moved.endpoint = $"{DefaultRedisSocket.SplitHost(pool._policy._connectionStringBuilder.Host).Key}:{moved.endpoint.Substring(10)}"; } else if (moved.endpoint.StartsWith("localhost", StringComparison.CurrentCultureIgnoreCase)) { moved.endpoint = $"{DefaultRedisSocket.SplitHost(pool._policy._connectionStringBuilder.Host).Key}:{moved.endpoint.Substring(10)}"; } ConnectionStringBuilder connectionString = pool._policy._connectionStringBuilder.ToString(); connectionString.Host = moved.endpoint; RegisterClusterNode(connectionString); if (moved.ismoved) { _slotCache.AddOrUpdate(moved.slot, connectionString.Host, (k1, v1) => connectionString.Host); } if (moved.isask) { cmd._clusterMovedAsking = true; } TopOwner.OnNotice(null, new NoticeEventArgs(NoticeType.Info, null, $"{(cmd.WriteTarget ?? "Not connected").PadRight(21)} > {cmd}\r\n{rt.SimpleError} ", null)); return AdapterCall(cmd, parse); } } return parse(rt); })); }
public object Call(CommandPacket cmd) => _adapter.AdapaterCall <object, object>(cmd, rt => rt.ThrowOrValue());
T[] SReadArray <T>(CommandPacket cb) => Call <object, T[]>(cb, rt => rt .NewValue(a => a.ConvertTo <byte[][]>().Select(b => DeserializeRedisValue <T>(b, rt.Encoding)).ToArray()) .ThrowOrValue());
protected T2 Call <T1, T2>(CommandPacket cmd, Func <RedisResult <T1>, T2> parse) => _adapter.AdapaterCall(cmd, parse);
protected TValue Call <TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse) => Adapter.AdapterCall(cmd, parse);
public InterceptorBeforeEventArgs(RedisClient cli, CommandPacket cmd, Type valueType) { this.Client = cli; this.Command = cmd; this.ValueType = valueType; }
public override Task <TValue> AdapterCallAsync <TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse) { //Single socket not support Async Multiplexing return(Task.FromResult(AdapterCall <TValue>(cmd, parse))); }
public override Task <TValue> AdapterCallAsync <TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse) { return(Task.FromResult(AdapterCall(cmd, parse))); //todo.. }