// internally, this is very similar to RawResult, except it is designed to be usable // outside of the IO-processing pipeline: the buffers are standalone, etc internal static RedisResult TryCreate(PhysicalConnection connection, RawResult result) { try { switch (result.Type) { case ResultType.Integer: case ResultType.SimpleString: case ResultType.BulkString: return new SingleRedisResult(result.AsRedisValue()); case ResultType.MultiBulk: var items = result.GetItems(); var arr = new RedisResult[items.Length]; for (int i = 0; i < arr.Length; i++) { var next = TryCreate(connection, items[i]); if (next == null) return null; // means we didn't understand arr[i] = next; } return new ArrayRedisResult(arr); case ResultType.Error: return new ErrorRedisResult(result.GetString()); default: return null; } } catch(Exception ex) { connection?.OnInternalError(ex); return null; // will be logged as a protocol fail by the processor } }
// internally, this is very similar to RawResult, except it is designed to be usable // outside of the IO-processing pipeline: the buffers are standalone, etc internal static RedisResult TryCreate(PhysicalConnection connection, RawResult result) { try { switch (result.Type) { case ResultType.Integer: case ResultType.SimpleString: case ResultType.BulkString: return(new SingleRedisResult(result.AsRedisValue())); case ResultType.MultiBulk: var items = result.GetItems(); var arr = new RedisResult[items.Length]; for (int i = 0; i < arr.Length; i++) { var next = TryCreate(connection, items[i]); if (next == null) { return(null); // means we didn't understand } arr[i] = next; } return(new ArrayRedisResult(arr)); case ResultType.Error: return(new ErrorRedisResult(result.GetString())); default: return(null); } } catch (Exception ex) { connection?.OnInternalError(ex); return(null); // will be logged as a protocol fail by the processor } }
protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) { if (result.Type == ResultType.BulkString) { string category = Normalize(null), line; var list = new List <Tuple <string, KeyValuePair <string, string> > >(); using (var reader = new StringReader(result.GetString())) { while ((line = reader.ReadLine()) != null) { if (string.IsNullOrWhiteSpace(line)) { continue; } if (line.StartsWith("# ")) { category = Normalize(line.Substring(2)); continue; } int idx = line.IndexOf(':'); if (idx < 0) { continue; } var pair = new KeyValuePair <string, string>( line.Substring(0, idx).Trim(), line.Substring(idx + 1).Trim()); list.Add(Tuple.Create(category, pair)); } } var final = list.GroupBy(x => x.Item1, x => x.Item2).ToArray(); SetResult(message, final); return(true); } return(false); }
protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) { var server = connection.Bridge.ServerEndPoint; switch (result.Type) { case ResultType.BulkString: if (message != null && message.Command == RedisCommand.INFO) { string info = result.GetString(), line; if (string.IsNullOrWhiteSpace(info)) { SetResult(message, true); return(true); } using (var reader = new StringReader(info)) { while ((line = reader.ReadLine()) != null) { if (string.IsNullOrWhiteSpace(line) || line.StartsWith("# ")) { continue; } string val; if ((val = Extract(line, "role:")) != null) { switch (val) { case "master": server.IsSlave = false; server.Multiplexer.Trace("Auto-configured role: master"); break; case "slave": server.IsSlave = true; server.Multiplexer.Trace("Auto-configured role: slave"); break; } } else if ((val = Extract(line, "redis_version:")) != null) { Version version; if (Version.TryParse(val, out version)) { server.Version = version; server.Multiplexer.Trace("Auto-configured version: " + version); } } else if ((val = Extract(line, "redis_mode:")) != null) { switch (val) { case "standalone": server.ServerType = ServerType.Standalone; server.Multiplexer.Trace("Auto-configured server-type: standalone"); break; case "cluster": server.ServerType = ServerType.Cluster; server.Multiplexer.Trace("Auto-configured server-type: cluster"); break; case "sentinel": server.ServerType = ServerType.Sentinel; server.Multiplexer.Trace("Auto-configured server-type: sentinel"); break; } } } } } SetResult(message, true); return(true); case ResultType.MultiBulk: if (message != null && message.Command == RedisCommand.CONFIG) { var arr = result.GetItems(); int count = arr.Length / 2; byte[] timeout = (byte[])RedisLiterals.timeout, databases = (byte[])RedisLiterals.databases, slave_read_only = (byte[])RedisLiterals.slave_read_only, yes = (byte[])RedisLiterals.yes, no = (byte[])RedisLiterals.no; long i64; for (int i = 0; i < count; i++) { var key = arr[i * 2]; if (key.IsEqual(timeout) && arr[(i * 2) + 1].TryGetInt64(out i64)) { // note the configuration is in seconds int timeoutSeconds = checked ((int)i64), targetSeconds; if (timeoutSeconds > 0) { if (timeoutSeconds >= 60) { targetSeconds = timeoutSeconds - 20; // time to spare... } else { targetSeconds = (timeoutSeconds * 3) / 4; } server.Multiplexer.Trace("Auto-configured timeout: " + targetSeconds + "s"); server.WriteEverySeconds = targetSeconds; } } else if (key.IsEqual(databases) && arr[(i * 2) + 1].TryGetInt64(out i64)) { int dbCount = checked ((int)i64); server.Multiplexer.Trace("Auto-configured databases: " + dbCount); server.Databases = dbCount; } else if (key.IsEqual(slave_read_only)) { var val = arr[(i * 2) + 1]; if (val.IsEqual(yes)) { server.SlaveReadOnly = true; server.Multiplexer.Trace("Auto-configured slave-read-only: true"); } else if (val.IsEqual(no)) { server.SlaveReadOnly = false; server.Multiplexer.Trace("Auto-configured slave-read-only: false"); } } } } SetResult(message, true); return(true); } return(false); }
protected override KeyValuePair <string, string> Parse(RawResult first, RawResult second) { return(new KeyValuePair <string, string>(first.GetString(), second.GetString())); }