Ejemplo n.º 1
0
            public bool TryParse(RawResult result, out T[] pairs)
            {
                switch (result.Type)
                {
                case ResultType.MultiBulk:
                    var arr = result.GetItems();
                    if (arr == null)
                    {
                        pairs = null;
                    }
                    else
                    {
                        int count = arr.Length / 2;
                        if (count == 0)
                        {
                            pairs = nix;
                        }
                        else
                        {
                            pairs = new T[count];
                            int offset = 0;
                            for (int i = 0; i < pairs.Length; i++)
                            {
                                pairs[i] = Parse(arr[offset++], arr[offset++]);
                            }
                        }
                    }
                    return(true);

                default:
                    pairs = null;
                    return(false);
                }
            }
Ejemplo n.º 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
            }
        }
Ejemplo n.º 3
0
 public bool TryParse(RawResult result, out TimeSpan?expiry)
 {
     switch (result.Type)
     {
     case ResultType.Integer:
         long time;
         if (result.TryGetInt64(out time))
         {
             if (time < 0)
             {
                 expiry = null;
             }
             else if (isMilliseconds)
             {
                 expiry = TimeSpan.FromMilliseconds(time);
             }
             else
             {
                 expiry = TimeSpan.FromSeconds(time);
             }
             return(true);
         }
         break;
     }
     expiry = null;
     return(false);
 }
Ejemplo n.º 4
0
        private RawResult ReadArray(byte[] buffer, ref int offset, ref int count)
        {
            var itemCount = ReadLineTerminatedString(ResultType.Integer, buffer, ref offset, ref count);

            if (itemCount.HasValue)
            {
                if (!itemCount.TryGetInt64(out long i64))
                {
                    throw ExceptionFactory.ConnectionFailure(Multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid array length", Bridge.ServerEndPoint);
                }
                int itemCountActual = checked ((int)i64);

                if (itemCountActual < 0)
                {
                    //for null response by command like EXEC, RESP array: *-1\r\n
                    return(new RawResult(ResultType.SimpleString, null, 0, 0));
                }
                else if (itemCountActual == 0)
                {
                    //for zero array response by command like SCAN, Resp array: *0\r\n
                    return(RawResult.EmptyArray);
                }

                var arr = new RawResult[itemCountActual];
                for (int i = 0; i < itemCountActual; i++)
                {
                    if (!(arr[i] = TryParseResult(buffer, ref offset, ref count)).HasValue)
                    {
                        return(RawResult.Nil);
                    }
                }
                return(new RawResult(arr));
            }
            return(RawResult.Nil);
        }
Ejemplo n.º 5
0
        private RawResult ReadArray(byte[] buffer, ref int offset, ref int count)
        {
            var itemCount = ReadLineTerminatedString(ResultType.Integer, buffer, ref offset, ref count);

            if (itemCount.HasValue)
            {
                long i64;
                if (!itemCount.TryGetInt64(out i64))
                {
                    throw ExceptionFactory.ConnectionFailure(multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid array length", bridge.ServerEndPoint);
                }
                int itemCountActual = checked ((int)i64);

                if (itemCountActual <= 0)
                {
                    return(RawResult.EmptyArray);
                }

                var arr = new RawResult[itemCountActual];
                for (int i = 0; i < itemCountActual; i++)
                {
                    if (!(arr[i] = TryParseResult(buffer, ref offset, ref count)).HasValue)
                    {
                        return(RawResult.Nil);
                    }
                }
                return(new RawResult(arr));
            }
            return(RawResult.Nil);
        }
Ejemplo n.º 6
0
        private RawResult ReadBulkString(byte[] buffer, ref int offset, ref int count)
        {
            var prefix = ReadLineTerminatedString(ResultType.Integer, buffer, ref offset, ref count);

            if (prefix.HasValue)
            {
                long i64;
                if (!prefix.TryGetInt64(out i64))
                {
                    throw ExceptionFactory.ConnectionFailure(Multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid bulk string length", Bridge.ServerEndPoint);
                }
                int bodySize = checked ((int)i64);
                if (bodySize < 0)
                {
                    return(new RawResult(ResultType.BulkString, null, 0, 0));
                }
                else if (count >= bodySize + 2)
                {
                    if (buffer[offset + bodySize] != '\r' || buffer[offset + bodySize + 1] != '\n')
                    {
                        throw ExceptionFactory.ConnectionFailure(Multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid bulk string terminator", Bridge.ServerEndPoint);
                    }
                    var result = new RawResult(ResultType.BulkString, buffer, offset, bodySize);
                    offset += bodySize + 2;
                    count  -= bodySize + 2;
                    return(result);
                }
            }
            return(RawResult.Nil);
        }
Ejemplo n.º 7
0
 public RawResult(RawResult[] arr)
 {
     if (arr == null) throw new ArgumentNullException(nameof(arr));
     Type = ResultType.MultiBulk;
     offset = 0;
     count = arr.Length;
     this.arr = arr;
 }
Ejemplo n.º 8
0
 public RawResult(RawResult[] arr)
 {
     if (arr == null) throw new ArgumentNullException("arr");
     this.resultType = ResultType.MultiBulk;
     this.offset = 0;
     this.count = arr.Length;
     this.arr = arr;
 }
Ejemplo n.º 9
0
            internal override bool TryValidate(RawResult result, out bool value)
            {
                bool parsed;

                if (ResultProcessor.DemandZeroOrOneProcessor.TryGet(result, out parsed))
                {
                    value = parsed == expectedResult;
                    ConnectionMultiplexer.TraceWithoutContext("exists: " + parsed + "; expected: " + expectedResult + "; voting: " + value);
                    return(true);
                }
                value = false;
                return(false);
            }
Ejemplo n.º 10
0
 internal override bool TryValidate(RawResult result, out bool value)
 {
     switch (result.Type)
     {
     case ResultType.BulkString:
     case ResultType.SimpleString:
     case ResultType.Integer:
         var parsed = result.AsRedisValue();
         value = parsed.IsInteger && (expectedLength.CompareTo((long)parsed) == compareToResult);
         ConnectionMultiplexer.TraceWithoutContext("actual: " + (string)parsed + "; expected: " + expectedLength +
                                                   "; wanted: " + GetComparisonString() + "; voting: " + value);
         return(true);
     }
     value = false;
     return(false);
 }
Ejemplo n.º 11
0
 internal override bool TryValidate(RawResult result, out bool value)
 {
     switch (result.Type)
     {
     case ResultType.BulkString:
     case ResultType.SimpleString:
     case ResultType.Integer:
         var parsed = result.AsRedisValue();
         value = (parsed == expectedValue) == expectedEqual;
         ConnectionMultiplexer.TraceWithoutContext("actual: " + (string)parsed + "; expected: " + (string)expectedValue +
                                                   "; wanted: " + (expectedEqual ? "==" : "!=") + "; voting: " + value);
         return(true);
     }
     value = false;
     return(false);
 }
Ejemplo n.º 12
0
        private RawResult ReadLineTerminatedString(ResultType type, byte[] buffer, ref int offset, ref int count)
        {
            int max = offset + count - 2;

            for (int i = offset; i < max; i++)
            {
                if (buffer[i + 1] == '\r' && buffer[i + 2] == '\n')
                {
                    int len    = i - offset + 1;
                    var result = new RawResult(type, buffer, offset, len);
                    count  -= (len + 2);
                    offset += (len + 2);
                    return(result);
                }
            }
            return(RawResult.Nil);
        }
Ejemplo n.º 13
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(), result.Type));

                case ResultType.MultiBulk:
                    if (result.IsNull)
                    {
                        return(NullArray);
                    }
                    var items = result.GetItems();
                    if (items.Length == 0)
                    {
                        return(EmptyArray);
                    }
                    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
            }
        }
Ejemplo n.º 14
0
 public static bool TryGet(RawResult result, out bool value)
 {
     switch (result.Type)
     {
     case ResultType.Integer:
     case ResultType.SimpleString:
     case ResultType.BulkString:
         if (result.IsEqual(one))
         {
             value = true; return(true);
         }
         else if (result.IsEqual(zero))
         {
             value = false; return(true);
         }
         break;
     }
     value = false;
     return(false);
 }
Ejemplo n.º 15
0
 // returns an array of RawResults
 internal                         RawResult[] GetArrayOfRawResults()
 {
     if (arr == null)
     {
         return(null);
     }
     else if (arr.Length == 0)
     {
         return(new RawResult[0]);
     }
     else
     {
         var rawResultArray = new RawResult[arr.Length];
         for (int i = 0; i < arr.Length; i++)
         {
             var rawResult = (RawResult)arr.GetValue(i);
             rawResultArray.SetValue(rawResult, i);
         }
         return(rawResultArray);
     }
 }
Ejemplo n.º 16
0
            internal override bool TryValidate(RawResult result, out bool value)
            {
                switch (type)
                {
                case RedisType.SortedSet:
                    var parsedValue = result.AsRedisValue();
                    value = (parsedValue.IsNull != expectedResult);
                    ConnectionMultiplexer.TraceWithoutContext("exists: " + parsedValue + "; expected: " + expectedResult + "; voting: " + value);
                    return(true);

                default:
                    bool parsed;
                    if (ResultProcessor.DemandZeroOrOneProcessor.TryGet(result, out parsed))
                    {
                        value = parsed == expectedResult;
                        ConnectionMultiplexer.TraceWithoutContext("exists: " + parsed + "; expected: " + expectedResult + "; voting: " + value);
                        return(true);
                    }
                    value = false;
                    return(false);
                }
            }
Ejemplo n.º 17
0
 protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
 {
     switch (result.Type)
     {
     case ResultType.MultiBulk:
         var arr = result.GetItemsAsKeys();
         SetResult(message, arr);
         return(true);
     }
     return(false);
 }
Ejemplo n.º 18
0
            protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
            {
                var  msg       = message as ConditionMessage;
                var  condition = msg == null ? null : msg.Condition;
                bool final;

                if (condition != null && condition.TryValidate(result, out final))
                {
                    SetResult(message, final);
                    return(true);
                }
                return(false);
            }
Ejemplo n.º 19
0
 internal abstract bool TryValidate(RawResult result, out bool value);
Ejemplo n.º 20
0
 protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
 {
     switch (result.Type)
     {
     case ResultType.Integer:
     case ResultType.SimpleString:
     case ResultType.BulkString:
         SetResult(message, result.AsRedisKey());
         return(true);
     }
     return(false);
 }
Ejemplo n.º 21
0
 protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
 {
     switch (result.Type)
     {
     case ResultType.SimpleString:
     case ResultType.BulkString:
         string    s = result.GetString();
         RedisType value;
         if (string.Equals(s, "zset", StringComparison.OrdinalIgnoreCase))
         {
             value = Redis.RedisType.SortedSet;
         }
         else if (!Enum.TryParse <RedisType>(s, true, out value))
         {
             value = global::StackExchange.Redis.RedisType.Unknown;
         }
         SetResult(message, value);
         return(true);
     }
     return(false);
 }
Ejemplo n.º 22
0
 // returns an array of RawResults
 internal RawResult[] GetArrayOfRawResults()
 {
     if (arr == null)
     {
         return null;
     }
     else if (arr.Length == 0)
     {
         return new RawResult[0];
     }
     else
     {
         var rawResultArray = new RawResult[arr.Length];
         for (int i = 0; i < arr.Length; i++)
         {
             var rawResult = (RawResult)arr.GetValue(i);
             rawResultArray.SetValue(rawResult, i);
         }
         return rawResultArray;
     }
 }
 private RawResult ReadLineTerminatedString(ResultType type, byte[] buffer, ref int offset, ref int count)
 {
     int max = offset + count - 2;
     for (int i = offset; i < max; i++)
     {
         if (buffer[i + 1] == '\r' && buffer[i + 2] == '\n')
         {
             int len = i - offset + 1;
             var result = new RawResult(type, buffer, offset, len);
             count -= (len + 2);
             offset += (len + 2);
             return result;
         }
     }
     return RawResult.Nil;
 }
 private RawResult ReadBulkString(byte[] buffer, ref int offset, ref int count)
 {
     var prefix = ReadLineTerminatedString(ResultType.Integer, buffer, ref offset, ref count);
     if (prefix.HasValue)
     {
         long i64;
         if (!prefix.TryGetInt64(out i64)) throw ExceptionFactory.ConnectionFailure(multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid bulk string length", bridge.ServerEndPoint);
         int bodySize = checked((int)i64);
         if (bodySize < 0)
         {
             return new RawResult(ResultType.BulkString, null, 0, 0);
         }
         else if (count >= bodySize + 2)
         {
             if (buffer[offset + bodySize] != '\r' || buffer[offset + bodySize + 1] != '\n')
             {
                 throw ExceptionFactory.ConnectionFailure(multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid bulk string terminator", bridge.ServerEndPoint);
             }
             var result = new RawResult(ResultType.BulkString, buffer, offset, bodySize);
             offset += bodySize + 2;
             count -= bodySize + 2;
             return result;
         }
     }
     return RawResult.Nil;
 }
Ejemplo n.º 25
0
 protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
 {
     switch (result.Type)
     {
     case ResultType.Integer:
     case ResultType.SimpleString:
     case ResultType.BulkString:
         if (result.IsNull)
         {
             SetResult(message, null);
             return(true);
         }
         long i64;
         if (result.TryGetInt64(out i64))
         {
             SetResult(message, i64);
             return(true);
         }
         break;
     }
     return(false);
 }
Ejemplo n.º 26
0
 // true if ready to be completed (i.e. false if re-issued to another server)
 internal bool ComputeResult(PhysicalConnection connection, RawResult result)
 {
     return(resultProcessor == null || resultProcessor.SetResult(connection, this, result));
 }
        private RawResult ReadArray(byte[] buffer, ref int offset, ref int count)
        {
            var itemCount = ReadLineTerminatedString(ResultType.Integer, buffer, ref offset, ref count);
            if (itemCount.HasValue)
            {
                long i64;
                if (!itemCount.TryGetInt64(out i64)) throw ExceptionFactory.ConnectionFailure(multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid array length", bridge.ServerEndPoint);
                int itemCountActual = checked((int)i64);

                if (itemCountActual < 0)
                {
                    //for null response by command like EXEC, RESP array: *-1\r\n
                    return new RawResult(ResultType.SimpleString, null, 0, 0); 
                }
                else if (itemCountActual == 0)
                {
                    //for zero array response by command like SCAN, Resp array: *0\r\n 
                    return RawResult.EmptyArray; 
                }

                var arr = new RawResult[itemCountActual];
                for (int i = 0; i < itemCountActual; i++)
                {
                    if (!(arr[i] = TryParseResult(buffer, ref offset, ref count)).HasValue)
                        return RawResult.Nil;
                }
                return new RawResult(arr);
            }
            return RawResult.Nil;
        }
Ejemplo n.º 28
0
            protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
            {
                connection?.BridgeCouldBeNull?.Multiplexer?.OnTransactionLog($"condition '{message.CommandAndKey}' got '{result.ToString()}'");
                var msg       = message as ConditionMessage;
                var condition = msg?.Condition;

                if (condition != null && condition.TryValidate(result, out bool final))
                {
                    SetResult(message, final);
                    return(true);
                }
                return(false);
            }
Ejemplo n.º 29
0
 protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
 {
     switch (result.Type)
     {
     case ResultType.MultiBulk:
         var            arr = result.GetItems();
         RedisChannel[] final;
         if (arr.Length == 0)
         {
             final = RedisChannel.EmptyArray;
         }
         else
         {
             final = new RedisChannel[arr.Length];
             byte[] channelPrefix = connection.ChannelPrefix;
             for (int i = 0; i < final.Length; i++)
             {
                 final[i] = result.AsRedisChannel(channelPrefix);
             }
         }
         SetResult(message, final);
         return(true);
     }
     return(false);
 }
 protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
 {
     if (result.Type == ResultType.SimpleString && result.IsEqual(QUEUED))
     {
         var q = message as QueuedMessage;
         if (q != null)
         {
             q.WasQueued = true;
         }
         return(true);
     }
     return(false);
 }
Ejemplo n.º 31
0
 protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
 {
     switch (result.Type)
     {
     case ResultType.MultiBulk:
         var            parts = result.GetItems();
         CommandTrace[] arr   = new CommandTrace[parts.Length];
         for (int i = 0; i < parts.Length; i++)
         {
             var  subParts = parts[i].GetItems();
             long uniqueid, time, duration;
             if (!subParts[0].TryGetInt64(out uniqueid) || !subParts[1].TryGetInt64(out time) || !subParts[2].TryGetInt64(out duration))
             {
                 return(false);
             }
             arr[i] = new CommandTrace(uniqueid, time, duration, subParts[3].GetItemsAsValues());
         }
         SetResult(message, arr);
         return(true);
     }
     return(false);
 }
Ejemplo n.º 32
0
        void MatchResult(RawResult result)
        {
            // check to see if it could be an out-of-band pubsub message
            if (connectionType == ConnectionType.Subscription && result.Type == ResultType.MultiBulk)
            {   // out of band message does not match to a queued message
                var items = result.GetItems();
                if (items.Length >= 3 && items[0].IsEqual(message))
                {
                    // special-case the configuration change broadcasts (we don't keep that in the usual pub/sub registry)
                    var configChanged = Multiplexer.ConfigurationChangedChannel;
                    if (configChanged != null && items[1].IsEqual(configChanged))
                    {
                        EndPoint blame = null;
                        try
                        {
                            if (!items[2].IsEqual(RedisLiterals.ByteWildcard))
                            {
                                blame = Format.TryParseEndPoint(items[2].GetString());
                            }
                        }
                        catch { /* no biggie */ }
                        Multiplexer.Trace("Configuration changed: " + Format.ToString(blame), physicalName);
                        Multiplexer.ReconfigureIfNeeded(blame, true, "broadcast");
                    }

                    // invoke the handlers
                    var channel = items[1].AsRedisChannel(ChannelPrefix, RedisChannel.PatternMode.Literal);
                    Multiplexer.Trace("MESSAGE: " + channel, physicalName);
                    if (!channel.IsNull)
                    {
                        Multiplexer.OnMessage(channel, channel, items[2].AsRedisValue());
                    }
                    return; // AND STOP PROCESSING!
                }
                else if (items.Length >= 4 && items[0].IsEqual(pmessage))
                {
                    var channel = items[2].AsRedisChannel(ChannelPrefix, RedisChannel.PatternMode.Literal);
                    Multiplexer.Trace("PMESSAGE: " + channel, physicalName);
                    if (!channel.IsNull)
                    {
                        var sub = items[1].AsRedisChannel(ChannelPrefix, RedisChannel.PatternMode.Pattern);
                        Multiplexer.OnMessage(sub, channel, items[3].AsRedisValue());
                    }
                    return; // AND STOP PROCESSING!
                }

                // if it didn't look like "[p]message", then we still need to process the pending queue
            }
            Multiplexer.Trace("Matching result...", physicalName);
            Message msg;

            lock (outstanding)
            {
                Multiplexer.Trace(outstanding.Count == 0, "Nothing to respond to!", physicalName);
                msg = outstanding.Dequeue();
            }

            Multiplexer.Trace("Response to: " + msg.ToString(), physicalName);
            if (msg.ComputeResult(this, result))
            {
                Bridge.CompleteSyncOrAsync(msg);
            }
        }
            protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
            {
                var tran = message as TransactionMessage;

                if (tran != null)
                {
                    var bridge  = connection.Bridge;
                    var wrapped = tran.InnerOperations;
                    switch (result.Type)
                    {
                    case ResultType.SimpleString:
                        if (tran.IsAborted && result.IsEqual(RedisLiterals.BytesOK))
                        {
                            connection.Multiplexer.Trace("Acknowledging UNWATCH (aborted electively)");
                            SetResult(message, false);
                            return(true);
                        }
                        break;

                    case ResultType.MultiBulk:
                        if (!tran.IsAborted)
                        {
                            var arr = result.GetItems();
                            if (arr == null)
                            {
                                connection.Multiplexer.Trace("Server aborted due to failed WATCH");
                                foreach (var op in wrapped)
                                {
                                    op.Wrapped.Cancel();
                                    bridge.CompleteSyncOrAsync(op.Wrapped);
                                }
                                SetResult(message, false);
                                return(true);
                            }
                            else if (wrapped.Length == arr.Length)
                            {
                                connection.Multiplexer.Trace("Server committed; processing nested replies");
                                for (int i = 0; i < arr.Length; i++)
                                {
                                    if (wrapped[i].Wrapped.ComputeResult(connection, arr[i]))
                                    {
                                        bridge.CompleteSyncOrAsync(wrapped[i].Wrapped);
                                    }
                                }
                                SetResult(message, true);
                                return(true);
                            }
                        }
                        break;
                    }
                    // even if we didn't fully understand the result, we still need to do something with
                    // the pending tasks
                    foreach (var op in wrapped)
                    {
                        op.Wrapped.Fail(ConnectionFailureType.ProtocolFailure, null);
                        bridge.CompleteSyncOrAsync(op.Wrapped);
                    }
                }
                return(false);
            }
Ejemplo n.º 34
0
            protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
            {
                switch (result.Type)
                {
                case ResultType.BulkString:

                    var raw     = result.GetString();
                    var clients = Parse(raw);
                    SetResult(message, clients);
                    return(true);
                }
                return(false);
            }
Ejemplo n.º 35
0
 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);
 }
 public override bool SetResult(PhysicalConnection connection, Message message, RawResult result)
 {
     if (result.IsError)
     {
         var tran = message as TransactionMessage;
         if (tran != null)
         {
             string error  = result.GetString();
             var    bridge = connection.Bridge;
             foreach (var op in tran.InnerOperations)
             {
                 ServerFail(op.Wrapped, error);
                 bridge.CompleteSyncOrAsync(op.Wrapped);
             }
         }
     }
     return(base.SetResult(connection, message, result));
 }
        void MatchResult(RawResult result)
        {
            // check to see if it could be an out-of-band pubsub message
            if (connectionType == ConnectionType.Subscription && result.Type == ResultType.MultiBulk)
            {   // out of band message does not match to a queued message
                var items = result.GetItems();
                if (items.Length >= 3 && items[0].IsEqual(message))
                {
                    // special-case the configuration change broadcasts (we don't keep that in the usual pub/sub registry)
                    var configChanged = multiplexer.ConfigurationChangedChannel;
                    if (configChanged != null && items[1].IsEqual(configChanged))
                    {
                        EndPoint blame = null;
                        try
                        {
                            if (!items[2].IsEqual(RedisLiterals.ByteWildcard))
                            {
                                blame = Format.TryParseEndPoint(items[2].GetString());
                            }
                        }
                        catch { /* no biggie */ }
                        multiplexer.Trace("Configuration changed: " + Format.ToString(blame), physicalName);
                        multiplexer.ReconfigureIfNeeded(blame, true, "broadcast");
                    }

                    // invoke the handlers
                    var channel = items[1].AsRedisChannel(ChannelPrefix, RedisChannel.PatternMode.Literal);
                    multiplexer.Trace("MESSAGE: " + channel, physicalName);
                    if (!channel.IsNull)
                    {
                        multiplexer.OnMessage(channel, channel, items[2].AsRedisValue());
                    }
                    return; // AND STOP PROCESSING!
                }
                else if (items.Length >= 4 && items[0].IsEqual(pmessage))
                {
                    var channel = items[2].AsRedisChannel(ChannelPrefix, RedisChannel.PatternMode.Literal);
                    multiplexer.Trace("PMESSAGE: " + channel, physicalName);
                    if (!channel.IsNull)
                    {
                        var sub = items[1].AsRedisChannel(ChannelPrefix, RedisChannel.PatternMode.Pattern);
                        multiplexer.OnMessage(sub, channel, items[3].AsRedisValue());
                    }
                    return; // AND STOP PROCESSING!
                }

                // if it didn't look like "[p]message", then we still need to process the pending queue
            }
            multiplexer.Trace("Matching result...", physicalName);
            Message msg;
            lock (outstanding)
            {
                multiplexer.Trace(outstanding.Count == 0, "Nothing to respond to!", physicalName);
                msg = outstanding.Dequeue();
            }

            multiplexer.Trace("Response to: " + msg.ToString(), physicalName);
            if (msg.ComputeResult(this, result))
            {
                bridge.CompleteSyncOrAsync(msg);
            }
        }
Ejemplo n.º 38
0
 protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
 {
     switch (result.Type)
     {
     case ResultType.MultiBulk:
         var  arr = result.GetItems();
         long i64;
         if (arr.Length == 2 && arr[1].Type == ResultType.MultiBulk && arr[0].TryGetInt64(out i64))
         {
             var keysResult = new ScanResult(i64, arr[1].GetItemsAsKeys());
             SetResult(message, keysResult);
             return(true);
         }
         break;
     }
     return(false);
 }
        private RawResult ReadArray(byte[] buffer, ref int offset, ref int count)
        {
            var itemCount = ReadLineTerminatedString(ResultType.Integer, buffer, ref offset, ref count);
            if (itemCount.HasValue)
            {
                long i64;
                if (!itemCount.TryGetInt64(out i64)) throw ExceptionFactory.ConnectionFailure(multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid array length", bridge.ServerEndPoint);
                int itemCountActual = checked((int)i64);

                if (itemCountActual <= 0) return RawResult.EmptyArray;

                var arr = new RawResult[itemCountActual];
                for (int i = 0; i < itemCountActual; i++)
                {
                    if (!(arr[i] = TryParseResult(buffer, ref offset, ref count)).HasValue)
                        return RawResult.Nil;
                }
                return new RawResult(arr);
            }
            return RawResult.Nil;
        }