/// <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")); }
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); }
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 */)); }
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); }
/// <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); }
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); });
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); }
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)); }
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; } }
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); }
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]; }
/// <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)); }
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]); }
public void PrepareLuaScript(dynamic parameters) { RedisResult result = this.cache.ScriptEvaluate(ruleLuaScript, parameters); if (!result.IsNull) { var type = result.Type; } var test = result.IsNull; }
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) }); }
/// <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"); } }
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); }
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"]); }
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())); }
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); }
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; }