// 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
            }
        }
Exemple #2
0
        // 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()));
 }