private async Task TestGetAndSetSameTransaction <T>( Action <TransactionalRedisContext, string, T> set, Action <TransactionalRedisContext, string> get, int expectedResultsCount, T setValue, T expectedValue) { var ctx = GetTestConnection(); var key = GenerateRandomKey(); var transactionCtx = TransactionalRedisContext.FromRedisContext(ctx); transactionCtx.Start(); set(transactionCtx, key, setValue); get(transactionCtx, key); var results = transactionCtx.Execute(); Assert.AreEqual(expectedResultsCount, results.Length); var t = results[1] as Task <T>; Assert.IsNotNull(t); var actual = await t; Assert.AreEqual(expectedValue, actual); ctx?.CloseConnections(); }
public void SortedSetRemoveRangeByScoreTest <T>( Tuple <T, double>[] valswithScores, Dictionary <double, T[]> expectedResultsPerScore, double startScore, double stopScore, Action <TransactionalRedisContext, string, T, double> sortedSetAdd, Action <TransactionalRedisContext, string, double> getByScore) { var key = GenerateRandomKey(); var conn = GetTestConnection(); try { var txCtx = TransactionalRedisContext.FromRedisContext(conn); txCtx.Start(); foreach (var val in valswithScores) { var value = val.Item1; var score = val.Item2; sortedSetAdd(txCtx, key, value, score); } var addResults = txCtx.Execute(); Task.WaitAll(addResults); txCtx.Start(); txCtx.SortedSetRemoveRangeByScore(key, startScore, stopScore); foreach (var expected in expectedResultsPerScore) { getByScore(txCtx, key, expected.Key); } var castedResults = txCtx.ExecuteAndWaitTyped <T[]>(); Assert.AreEqual(expectedResultsPerScore.Count, castedResults.Length); var i = 0; foreach (var expected in expectedResultsPerScore) { for (var j = 0; j < castedResults[i].Length; j++) { Assert.AreEqual(expected.Value[j], castedResults[i][j]); } i++; } } finally { conn.CloseConnections(); } }
public void SortedSetAddGet <T>( T[] vals, Action <TransactionalRedisContext, string, T, double> sortedSetAdd, Action <TransactionalRedisContext, string, int> getRange) { var key = GenerateRandomKey(); var valsCount = vals.Length; var conn = GetTestConnection(); try { var txCtx = TransactionalRedisContext.FromRedisContext(conn); txCtx.Start(); var i = 0; foreach (var val in vals) { sortedSetAdd(txCtx, key, val, i); i++; } var addResults = txCtx.Execute(); Task.WaitAll(addResults); txCtx.Start(); for (var rangeIndex = 0; rangeIndex < valsCount; rangeIndex++) { getRange(txCtx, key, rangeIndex); } var results = txCtx.ExecuteAndWaitTyped <T[]>(); i = 0; while (valsCount > 0) { valsCount--; Assert.AreEqual(valsCount + 1, results[i].Length); i++; } } finally { conn.CloseConnections(); } }
public void SlidingWindowTest() { var key = GenerateRandomKey(); const int valuesCount = 15; const int waitInEachIterationSeconds = 1; const int slidingWindowSizeMS = 5000; var expectedResultsByTimePassed = new Dictionary <int, int> { [1] = 11, [2] = 23, [3] = 36, [4] = 50, [5] = 65, [6] = 70, [7] = 75, [8] = 80, [9] = 85, [10] = 90, [11] = 95, [12] = 100, [13] = 105, [14] = 110, [15] = 115, }; var baseline = DateTime.UtcNow; var conn = GetTestConnection(); try { var txCtx = TransactionalRedisContext.FromRedisContext(conn); for (var i = 1; i <= valuesCount; i++) { var sw = Stopwatch.StartNew(); txCtx.Start(); var resultsIindex = 1; var currentIterationScore = (DateTime.UtcNow - baseline).TotalSeconds * 1000; var calculatedRangeEnd = currentIterationScore - slidingWindowSizeMS; var removeRangeEnd = Math.Max(calculatedRangeEnd, 0); // remove older points if (removeRangeEnd > 0) { Console.WriteLine($"removing range. start: 0, end: {removeRangeEnd}"); txCtx.SortedSetRemoveRangeByScore(key, 0, removeRangeEnd); resultsIindex++; } // add current point to the sliding window Console.WriteLine($"adding to set. score: {currentIterationScore}"); txCtx.SortedSetAdd(key, 10 + i, currentIterationScore); // get the entire set - current window txCtx.SortedSetGetRangeByRankInt(key); // set new TTL - window size -- this is nessassary only for cleaning up after the test txCtx.SetTimeToLive(key, TimeSpan.FromMilliseconds(slidingWindowSizeMS)); var resultsTasks = txCtx.Execute(); // wait for all of it to finish Task.WaitAll(resultsTasks); // only the second\third command is interesting for us - getting all of the values in the current window var convertedTask = resultsTasks[resultsIindex] as Task <int[]>; Assert.IsNotNull(convertedTask); var windowContent = convertedTask.Result; var sum = windowContent.Sum(); Console.WriteLine( $"checking results. iteration: {i}, expected: {expectedResultsByTimePassed[i]}, actual: {sum}"); Assert.AreEqual(expectedResultsByTimePassed[i], sum); sw.Stop(); Thread.Sleep((waitInEachIterationSeconds * 1000) - (int)sw.ElapsedMilliseconds); } } finally { conn.CloseConnections(); } }