/// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider#WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var timer = Stopwatch.StartNew();
            var key   = GetKey(grainReference);

            RedisResult response = null;
            var         newEtag  = Guid.NewGuid().ToString();

            if (_options.UseJson)
            {
                var payload = JsonConvert.SerializeObject(grainState.State, JsonSettings);
                var args    = new { key, etag = grainState.ETag ?? "null", newEtag, data = payload };
                response = await _db.ScriptEvaluateAsync(_preparedWriteScript, args);
            }
            else
            {
                var payload = _serializationManager.SerializeToByteArray(grainState.State);
                var args    = new { key, etag = grainState.ETag ?? "null", newEtag, data = payload };
                response = await _db.ScriptEvaluateAsync(_preparedWriteScript, args);
            }

            if (response.IsNull)
            {
                timer.Stop();
                _logger.LogError("Writing: GrainType={0} PrimaryKey={1} Grainid={2} ETag={3} to Database={4}, finished in {5} ms - Error: ETag mismatch!",
                                 grainType, key, grainReference, grainState.ETag, _db.Database, timer.Elapsed.TotalMilliseconds.ToString("0.00"));
                throw new InconsistentStateException($"ETag mismatch - tried with ETag: {grainState.ETag}");
            }

            grainState.ETag = newEtag;

            timer.Stop();
            _logger.LogInformation("Writing: GrainType={0} PrimaryKey={1} Grainid={2} ETag={3} to Database={4}, finished in {5} ms",
                                   grainType, key, grainReference, grainState.ETag, _db.Database, timer.Elapsed.TotalMilliseconds.ToString("0.00"));
        }
Example #2
0
 public override TValue AdapterCall <TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse)
 {
     return(TopOwner.LogCall(cmd, () =>
     {
         RedisResult rt = null;
         RedisClientPool pool = null;
         Exception ioex = null;
         using (var rds = GetRedisSocket(cmd))
         {
             pool = (rds as DefaultRedisSocket.TempProxyRedisSocket)._pool;
             try
             {
                 rds.Write(cmd);
                 rt = rds.Read(cmd);
             }
             catch (Exception ex)
             {
                 ioex = ex;
             }
         }
         if (ioex != null)
         {
             if (pool?.SetUnavailable(ioex) == true)
             {
             }
             throw ioex;
         }
         return parse(rt);
     }));
 }
        /// <summary>
        /// This method is used to retrieve a hash member set of values from the cache.
        /// </summary>
        /// <param name="cache">Contains the redis Cache database to retrieve the cache value from.</param>
        /// <param name="key">Contains the key to find.</param>
        /// <param name="members">Contains the members to retrieve from the hash.</param>
        /// <returns>Returns the array of Redis values found.</returns>
        internal static async Task <RedisValue[]> HashMemberGetAsync(this IDatabase cache, string key, params string[] members)
        {
            RedisResult result = await cache.ScriptEvaluateAsync(HmGetScript, new RedisKey[] { key }, GetRedisMembers(members));

            // TODO: Error checking?
            return((RedisValue[])result);
        }
Example #4
0
        public void ToDictionaryFailsWithDuplicateKeys()
        {
            var redisArrayResult = RedisResult.Create(
                new RedisValue[] { "banana", 1, "BANANA", 2, "orange", 3, "apple", 4 });

            Assert.Throws <ArgumentException>(() => redisArrayResult.ToDictionary(/* Use default comparer, causes collision of banana */));
        }
Example #5
0
        public ISessionStateItemCollection GetSessionData(object rowDataFromRedis)
        {
            RedisResult rowDataAsRedisResult = (RedisResult)rowDataFromRedis;

            RedisResult[] lockScriptReturnValueArray = (RedisResult[])rowDataAsRedisResult;
            Debug.Assert(lockScriptReturnValueArray != null);

            ChangeTrackingSessionStateItemCollection sessionData = null;

            if (lockScriptReturnValueArray.Length > 1 && lockScriptReturnValueArray[1] != null)
            {
                RedisResult[] data = (RedisResult[])lockScriptReturnValueArray[1];

                // LUA script returns data as object array so keys and values are store one after another
                // This list has to be even because it contains pair of <key, value> as {key, value, key, value}
                if (data != null && data.Length != 0 && data.Length % 2 == 0)
                {
                    sessionData = new ChangeTrackingSessionStateItemCollection(_redisUtility);
                    // In every cycle of loop we are getting one pair of key value and putting it into session items
                    // thats why increment is by 2 because we want to move to next pair
                    for (int i = 0; (i + 1) < data.Length; i += 2)
                    {
                        string key = (string)data[i];
                        if (key != null)
                        {
                            sessionData.SetData(key, (byte[])data[i + 1]);
                        }
                    }
                }
            }
            return(sessionData);
        }
Example #6
0
 /// <summary>
 /// Redis 自定义异步接口  使用场景多线程,消息队列
 /// </summary>
 /// <param name="cmd"></param>
 /// <param name="values"></param>
 /// <returns></returns>
 public string CommandOutValueAsync(RedisCommand cmd, List <string> values)
 {
     Count = 0;
     try
     {
         using (var client = ConnectionMultiplexer.Connect(Profile.redisIp + ",abortConnect=false"))
         {
             var cv    = client.GetDatabase();
             var batch = cv.CreateBatch();
             var task  = batch.ExecuteAsync(cmd.ToString(), values.ToArray());
             batch.Execute();
             task.Wait();
             RedisResult result = task.Result;
             var         val    = ((RedisResult[])result)[1].ToString();
             Sucess = !string.IsNullOrWhiteSpace(val);
             return(val);
         }
     }
     catch (Exception ex)
     {
         Logger.Error(ex);
         Message = ex.Message;
         Code    = ErrorCode.ReadRedisErrorCode;
         Sucess  = false;
     }
     return(string.Empty);
 }
Example #7
0
 public static StreamsEntryResult[] ThrowOrValueToXRead(this RedisResult rt) =>
 rt.ThrowOrValue((a, _) =>
 {
     if (a == null)
     {
         return(new StreamsEntryResult[0]);
     }
     var ret = new StreamsEntryResult[a.Length];
     for (var z = 0; z < a.Length; z++)
     {
         var objs1   = a[z] as object[];
         var objs2   = objs1[1] as object[];
         var entries = new StreamsEntry[objs2.Length];
         ret[z]      = new StreamsEntryResult {
             key = objs1[0].ConvertTo <string>(), entries = entries
         };
         for (var y = 0; y < objs2.Length; y++)
         {
             var objs3  = objs2[y] as object[];
             entries[y] = new StreamsEntry {
                 id = objs3[0].ConvertTo <string>(), fieldValues = objs3[1] as object[]
             };
         }
     }
     return(ret);
 });
Example #8
0
 public override TValue AdapterCall <TValue>(CommandPacket cmd, Func <RedisResult, TValue> parse)
 {
     return(TopOwner.LogCall(cmd, () =>
     {
         RedisResult rt = null;
         using (var rds = GetRedisSocket(cmd))
         {
             try
             {
                 rds.Write(cmd);
                 rt = rds.Read(cmd._flagReadbytes);
             }
             catch (Exception ex)
             {
                 var pool = (rds as DefaultRedisSocket.TempProxyRedisSocket)._pool;
                 if (pool?.SetUnavailable(ex) == true)
                 {
                     Interlocked.Exchange(ref _masterHost, null);
                     RecoverySentinel();
                 }
                 throw ex;
             }
         }
         rt.IsErrorThrow = TopOwner._isThrowRedisSimpleError;
         return parse(rt);
     }));
 }
        public async Task StressTest_On_SearchKeysMethod()
        {
            //Note: https://github.com/imperugo/StackExchange.Redis.Extensions/issues/115
            var filter          = "prefix_";
            var totalItemsToAdd = 10000;

            await PopulateDbAsync(filter, totalItemsToAdd);

            List <string> schemas = new List <string>();

            var sw = new Stopwatch();

            #region With SCAN and MATCH
            sw.Start();
            int nextCursor = 0;
            do
            {
                RedisResult redisResult = sut.Database.Execute("SCAN", nextCursor.ToString(), "MATCH", $"{filter}*", "COUNT", "5000");
                var         innerResult = (RedisResult[])redisResult;
                nextCursor = int.Parse((string)innerResult[0]);
                List <string> resultLines = ((string[])innerResult[1]).ToList();
                schemas.AddRange(resultLines);
            }while (nextCursor != 0);
            output.WriteLine($"SCAN and MATCH: Got {schemas.Count} elements of {filter} in {sw.ElapsedMilliseconds}msec.", schemas.Count, sw.ElapsedMilliseconds);
            #endregion With SCAN and MATCH
            #region With method SearchKeys
            sw.Restart();
            IEnumerable <string> schemas1 = sut.SearchKeys($"{filter}*");
            output.WriteLine($"SearchKeys: Got {schemas1.Count()} elements of {filter} in {sw.ElapsedMilliseconds}msec.");
            #endregion With method SearchKeys

            Assert.Equal(schemas.Count, totalItemsToAdd);
            Assert.Equal(schemas1.Count(), totalItemsToAdd);
        }
Example #10
0
        public void ToDictionaryFailsOnMishapenResults()
        {
            var redisArrayResult = RedisResult.Create(
                new RedisValue[] { "one", 1, "two", 2, "three", 3, "four" /* missing 4 */ });

            Assert.Throws <IndexOutOfRangeException>(() => redisArrayResult.ToDictionary(StringComparer.Ordinal));
        }
Example #11
0
        public ResultSet(RedisResult result, GraphCache graphCache)
        {
            if (result.Type == ResultType.MultiBulk)
            {
                var resultArray = (RedisResult[])result;
                _graphCache = graphCache;

                if (resultArray.Length == 3)
                {
                    Header     = new Header(resultArray[0]);
                    Statistics = new Statistics(resultArray[2]);

                    _rawResults = (RedisResult[])resultArray[1];

                    Count = _rawResults.Length;
                }
                else
                {
                    Statistics = new Statistics(resultArray[resultArray.Length - 1]);
                    Count      = 0;
                }
            }
            else
            {
                Statistics = new Statistics(result);
                Count      = 0;
            }
        }
Example #12
0
        private RedisResult GetRedisKeys(string pattern)
        {
            string      lua         = @"local res = redis.call('keys',@pattern) 
return res ";
            RedisResult redisResult = DB.ScriptEvaluate(LuaScript.Prepare(lua), new { pattern });

            return(redisResult);
        }
Example #13
0
        internal static string GetLockIdStatic(object rowDataFromRedis)
        {
            RedisResult rowDataAsRedisResult = (RedisResult)rowDataFromRedis;

            RedisResult[] lockScriptReturnValueArray = (RedisResult[])rowDataAsRedisResult;
            Debug.Assert(lockScriptReturnValueArray != null);
            return((string)lockScriptReturnValueArray[0]);
        }
 private static TimeStamp ParseTimeStamp(RedisResult result)
 {
     if (result.Type == ResultType.None)
     {
         return(null);
     }
     return(new TimeStamp((long)result));
 }
        public GraphResultScalar(RedisResult result)
        {
            var cell       = (RedisResult[])result;
            var startIndex = cell.Length > 2 ? 1 : 0;

            Type  = (PropertyType)((int)cell[startIndex]);
            Value = cell[startIndex + 1];
        }
Example #16
0
        /// <summary>
        /// SetAsync
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="utcTicks"></param>
        /// <param name="options"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        /// <exception cref="CacheException"></exception>
        public async Task <bool> SetAsync(string key, byte[] value, UtcNowTicks utcTicks, DistributedCacheEntryOptions options, CancellationToken token = default)
        {
            token.ThrowIfCancellationRequested();

            IDatabase database = await GetDefaultDatabaseAsync().ConfigureAwait(false);

            if (options.AbsoluteExpirationRelativeToNow.HasValue)
            {
                options.AbsoluteExpiration = TimeUtil.UtcNow + options.AbsoluteExpirationRelativeToNow;
            }

            long?absoluteExpireUnixSeconds = options.AbsoluteExpiration?.ToUnixTimeSeconds();
            long?slideSeconds = (long?)(options.SlidingExpiration?.TotalSeconds);

            try
            {
                RedisResult redisResult = await database.ScriptEvaluateAsync(GetDefaultLoadLuas().LoadedSetWithTimestampLua, new RedisKey[] { GetRealKey("", key) },
                                                                             new RedisValue[]
                {
                    absoluteExpireUnixSeconds ?? -1,
                    slideSeconds ?? -1,
                    GetInitialExpireSeconds(absoluteExpireUnixSeconds, slideSeconds) ?? -1,
                    value,
                    utcTicks.Ticks
                }).ConfigureAwait(false);

                int rt = (int)redisResult;

                if (rt == 1)
                {
                    return(true);
                }
                else if (rt == 8)
                {
                    _logger.LogWarning("检测到,Cache Invalidation Concurrency冲突,已被阻止. {key}, {Timestamp}", key, utcTicks);
                }
                else if (rt == 9)
                {
                    _logger.LogWarning("检测到,Cache Update Concurrency冲突,已被阻止. {key}, {Timestamp}", key, utcTicks);
                }

                return(false);
            }
            catch (RedisServerException ex) when(ex.Message.StartsWith("NOSCRIPT", StringComparison.InvariantCulture))
            {
                _logger.LogError(ex, "NOSCRIPT, will try again.");

                InitLoadedLuas();

                return(await SetAsync(key, value, utcTicks, options, token).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "分析这个");

                throw Exceptions.Unkown(key, null, ex);
            }
        }
 private static TimeSeriesTuple ParseTimeSeriesTuple(RedisResult result)
 {
     RedisResult[] redisResults = (RedisResult[])result;
     if (redisResults.Length == 0)
     {
         return(null);
     }
     return(new TimeSeriesTuple(ParseTimeStamp(redisResults[0]), (double)redisResults[1]));
 }
        private static TimeSeriesRule ParseRule(RedisResult result)
        {
            RedisResult[] redisResults = (RedisResult[])result;
            string        destKey      = (string)redisResults[0];
            long          bucketTime   = (long)redisResults[1];
            var           aggregation  = AggregationExtensions.AsAggregation((string)redisResults[2]);

            return(new TimeSeriesRule(destKey, bucketTime, aggregation));
        }
Example #19
0
        public bool IsLocked(object rowDataFromRedis)
        {
            RedisResult rowDataAsRedisResult = (RedisResult)rowDataFromRedis;

            RedisResult[] lockScriptReturnValueArray = (RedisResult[])rowDataAsRedisResult;
            Debug.Assert(lockScriptReturnValueArray != null);
            Debug.Assert(lockScriptReturnValueArray[3] != null);
            return((bool)lockScriptReturnValueArray[3]);
        }
Example #20
0
        public void PrepareLuaScript(dynamic parameters)
        {
            RedisResult result = this.cache.ScriptEvaluate(ruleLuaScript, parameters);

            if (!result.IsNull)
            {
                var type = result.Type;
            }
            var test = result.IsNull;
        }
Example #21
0
        internal ThrottleResult(RedisResult result)
        {
            var arr = (int[])result;

            Permitted         = arr[0] == 0;
            TotalLimit        = arr[1];
            RemainingLimit    = arr[2];
            RetryAfterSeconds = arr[3];
            ResetAfterSeconds = arr[4];
        }
        public IEnumerable <MiddlewareParameter> Execute(IEnumerable <MiddlewareParameter> parameters, Session session, ParameterTypeEnum returnTypeWanted)
        {
            IDatabase db = REDISConnector.REDISConnector.GetRedis().GetDatabase(datastore);
            // loaded.Evaluate(db, convertParamNames(parameters),convertParamValues(parameters));
            RedisResult res = db.ScriptEvaluate(loaded.Hash, convertParamNames(parameters), convertParameterValues(parameters));

            return(new List <MiddlewareParameter> {
                new MiddlewareParameter <string>("RedisResult", res.ToString(), MiddlewareParameterDirection.Out)
            });
        }
Example #23
0
        /// <summary>
        /// Return a dictionary with RedisResult key-value
        /// </summary>
        /// <param name="redisResult"></param>
        /// <returns></returns>
        private static Dictionary <string, string> ToCustomDictionary(this RedisResult redisResult)
        {
            var info       = redisResult.ToString();
            var dictionary = info?.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
                             .Where(part => part.Contains(':'))
                             .Select(part => part.Split(':'))
                             .ToDictionary(split => split[0], split => split[1]);

            return(dictionary);
        }
 /// <summary>
 /// Marshall's a JSON result from Redis into a POCO
 /// </summary>
 /// <typeparam name="TResult"></typeparam>
 /// <param name="serializedValue"></param>
 /// <returns></returns>
 public TResult Deserialize <TResult>(RedisResult serializedValue)
 {
     try
     {
         return(JsonConvert.DeserializeObject <TResult>(serializedValue.ToString()));
     }
     catch (ArgumentNullException)
     {
         throw new RedisKeyNotFoundException("Key not present in database");
     }
 }
Example #25
0
        public async Task <long> Increment(string key, long value = 1, TimeSpan?expire = null)
        {
            if (expire == null)
            {
                return(await _db.StringIncrementAsync(key, value).ConfigureAwait(false));
            }

            RedisResult result = await _db.ScriptEvaluateAsync(_preparedScript, new { Key = new RedisKey(key), Value = value, Expire = expire.Value.TotalSeconds }).ConfigureAwait(false);

            return((long)result);
        }
Example #26
0
        public void ToDictionaryWorksWithCustomComparator()
        {
            var redisArrayResult = RedisResult.Create(
                new RedisValue[] { "banana", 1, "BANANA", 2, "orange", 3, "apple", 4 });

            var dict = redisArrayResult.ToDictionary(StringComparer.Ordinal);

            Assert.Equal(4, dict.Count);
            Assert.Equal(1, (RedisValue)dict["banana"]);
            Assert.Equal(2, (RedisValue)dict["BANANA"]);
        }
Example #27
0
 internal void OnDataTrigger(RedisResult rt)
 {
     if (_ondata == null)
     {
         return;
     }
     while (_ondata.Any())
     {
         _ondata.Dequeue()(rt);
     }
 }
        private static TsDuplicatePolicy?ParsePolicy(RedisResult result)
        {
            var policyStatus = (string)result;

            if (String.IsNullOrEmpty(policyStatus) || policyStatus == "(nil)")
            {
                return(null);
            }

            return(DuplicatePolicyExtensions.AsPolicy(policyStatus.ToUpper()));
        }
Example #29
0
        public bool Acquire(int expire)
        {
            RedisValue strExpire = expire.ToString();
            var        script    = "local locked = redis.call('SETNX', KEYS[1], ARGV[1]);" +
                                   "if locked == 1 then redis.call('PEXPIRE', KEYS[1], ARGV[2]) end;" +
                                   "return locked";
            IDatabase   database = connection.GetDatabase();
            RedisResult result   = database.ScriptEvaluate(script, new RedisKey[] { this.key }, new RedisValue[] { this.key, strExpire });

            return((bool)result);
        }
Example #30
0
        internal Header(RedisResult result)
        {
            SchemaTypes = new List <ResultSetColumnTypes>();
            SchemaNames = new List <string>();

            foreach (RedisResult[] tuple in (RedisResult[])result)
            {
                SchemaTypes.Add((ResultSetColumnTypes)(int)tuple[0]);
                SchemaNames.Add((string)tuple[1]);
            }
        }
        private RedisResult GetResult()
        {
            RedisResult redisResult = new RedisResult();
            redisResult.Flag = _bstream.ReadByte();

            string msg = ReadLine();

            if (redisResult.Flag == '-')
            {
                redisResult.Exeption = new Exception(msg.StartsWith("-ERR ") ? msg.Substring(5) : msg.Substring(1));
                return redisResult;
            }

            if (redisResult.Flag == ':')
            {
                int i;
                if (int.TryParse(msg, out i))
                {
                    redisResult.Result = i;
                    return redisResult;
                }
            }

            if (redisResult.Flag == '$')
            {
                if (msg == "-1")
                {
                    return redisResult;
                }
                int n;

                if (int.TryParse(msg, out n))
                {
                    byte[] retbuf = new byte[n];

                    int bytesRead = 0;
                    do
                    {
                        int read = _bstream.Read(retbuf, bytesRead, n - bytesRead);
                        if (read < 1)
                        {
                            redisResult.Exeption = new Exception("Invalid termination mid stream");
                            return redisResult;
                        }
                        bytesRead += read;
                    }
                    while (bytesRead < n);
                    if (_bstream.ReadByte() != '\r' || _bstream.ReadByte() != '\n')
                    {
                        redisResult.Exeption = new Exception("Invalid termination");
                        return redisResult;
                    }
                    redisResult.Result = retbuf;
                    return redisResult;
                }

                redisResult.Exeption = new Exception("Invalid length");
                return redisResult;
            }

            if (redisResult.Flag == '*')
            {
                int count;
                if (int.TryParse(msg, out count))
                {
                    byte[][] result = new byte[count][];

                    for (int i = 0; i < count; i++)
                    {
                        var tmp = GetResult();
                        if (tmp.Exeption == null)
                        {
                            result[i] = (tmp.Result is byte[]) ? tmp.Result : new[] { (byte)tmp.Result };
                        }
                        else
                        {
                            redisResult.Exeption = tmp.Exeption;
                            return redisResult;
                        }
                    }

                    redisResult.Result = result;
                    return redisResult;
                }
            }

            if (redisResult.Flag == '+')
            {
                redisResult.Result = msg;
                return redisResult;
            }
            redisResult.Exeption = new Exception($"Unexpected reply: {redisResult.Flag} {msg}");
            return redisResult;
        }