Task <object> IScriptingCommands.Eval(int db, string script, string[] keyArgs, object[] valueArgs, bool useCache, bool inferStrings, bool queueJump) { if (string.IsNullOrEmpty(script)) { throw new ArgumentNullException("script"); } var args = new RedisMessage.RedisParameter[2 + (keyArgs == null ? 0 : keyArgs.Length) + (valueArgs == null ? 0 : valueArgs.Length)]; args[1] = keyArgs == null ? 0 : keyArgs.Length; int idx = 2; if (keyArgs != null) { for (int i = 0; i < keyArgs.Length; i++) { args[idx++] = keyArgs[i]; } } if (valueArgs != null) { for (int i = 0; i < valueArgs.Length; i++) { args[idx++] = RedisMessage.RedisParameter.Create(valueArgs[i]); } } if (!useCache) { args[0] = script; return(ExecuteScript(RedisMessage.Create(db, RedisLiteral.EVAL, args), inferStrings, queueJump)); } // note this does a SCRIPT LOAD if it is the first time it is seen on this connection args[0] = GetScriptHash(script); return(ExecuteScript(RedisMessage.Create(db, RedisLiteral.EVALSHA, args), inferStrings, queueJump)); }
Task <long> IListCommands.AddLast(int db, string key, byte[] value, bool createIfMissing, bool queueJump) { return (ExecuteInt64( RedisMessage.Create(db, createIfMissing ? RedisLiteral.RPUSH : RedisLiteral.RPUSHX, key, value), queueJump)); }
void IMultiMessage.Execute(RedisConnectionBase conn, ref int currentDb) { var pending = messages; if (ExecutePreconditions(conn, ref currentDb)) { conn.WriteRaw(this); // MULTI List <QueuedMessage> newlyQueued = new List <QueuedMessage>(pending.Length); // estimate same length for (int i = 0; i < pending.Length; i++) { conn.WriteMessage(ref currentDb, pending[i], newlyQueued); } newlyQueued.TrimExcess(); conn.WriteMessage(ref currentDb, Execute(newlyQueued), null); } else { // preconditions failed; ABORT conn.WriteMessage(ref currentDb, RedisMessage.Create(-1, RedisLiteral.UNWATCH).ExpectOk().Critical(), null); // even though these weren't written, we still need to mark them cancelled exec.Abort(pending); // spoof a rollback; same appearance to the caller exec.Complete(RedisResult.Multi(null), false); } }
internal Task <Tuple <string, int> > QuerySentinelMaster(string serviceName) { if (string.IsNullOrEmpty(serviceName)) { throw new ArgumentNullException("serviceName"); } var taskSource = new TaskCompletionSource <Tuple <string, int> >(); ExecuteMultiString(RedisMessage.Create(-1, RedisLiteral.SENTINEL, "get-master-addr-by-name", serviceName), false, taskSource) .ContinueWith(task => { var state = (TaskCompletionSource <Tuple <string, int> >)task.AsyncState; if (Condition.ShouldSetResult(task, state)) { string[] arr = task.Result; int i; if (arr == null) { state.SetResult(null); } else if (arr.Length == 2 && int.TryParse(arr[1], out i)) { state.SetResult(Tuple.Create(arr[0], i)); } else { state.SetException( new InvalidOperationException("Invalid sentinel result: " + string.Join(",", arr))); } } }); return(taskSource.Task); }
Task <DateTime> IServerCommands.Time(bool queueJump) { var source = new TaskCompletionSource <DateTime>(); ExecuteMultiString(RedisMessage.Create(-1, RedisLiteral.TIME), queueJump, source).ContinueWith(timeCallback); return(source.Task); }
Task <long?> ISortedSetCommands.Rank(int db, string key, byte[] member, bool ascending, bool queueJump) { return (ExecuteNullableInt64( RedisMessage.Create(db, ascending ? RedisLiteral.ZRANK : RedisLiteral.ZREVRANK, key, member), queueJump)); }
Task <string> IListCommands.BlockingRemoveLastAndAddFirstString(int db, string source, string destination, int timeoutSeconds, bool queueJump) { return(ExecuteRaw(RedisMessage.Create(db, RedisLiteral.BRPOPLPUSH, source, destination, timeoutSeconds), queueJump) .ContinueWith(x => x.Result == null || x.Result is MultiRedisResult ? null : x.Result.ValueString)); }
private static RedisMessage GetRangeRequest(int db, string key, double min, double max, bool ascending, bool minInclusive, bool maxInclusive, long offset, long count) { RedisMessage msg; if (minInclusive && maxInclusive && double.IsNegativeInfinity(min) && double.IsPositiveInfinity(max) && offset >= 0 && count != 0) { // considering entire set; can be done more efficiently with ZRANGE/ZREVRANGE msg = RedisMessage.Create(db, ascending ? RedisLiteral.ZRANGE : RedisLiteral.ZREVRANGE, key, offset, (count < 0 || count == long.MaxValue) ? -1 : (offset + count - 1), RedisLiteral.WITHSCORES); } else if (offset == 0 && (count < 0 || count == long.MaxValue)) { // no need for a LIMIT msg = RedisMessage.Create(db, ascending ? RedisLiteral.ZRANGEBYSCORE : RedisLiteral.ZREVRANGEBYSCORE, key, ascending ? RedisMessage.RedisParameter.Range(min, minInclusive) : RedisMessage.RedisParameter.Range(max, maxInclusive), ascending ? RedisMessage.RedisParameter.Range(max, maxInclusive) : RedisMessage.RedisParameter.Range(min, minInclusive), RedisLiteral.WITHSCORES); } else { msg = RedisMessage.Create(db, ascending ? RedisLiteral.ZRANGEBYSCORE : RedisLiteral.ZREVRANGEBYSCORE, key, ascending ? RedisMessage.RedisParameter.Range(min, minInclusive) : RedisMessage.RedisParameter.Range(max, maxInclusive), ascending ? RedisMessage.RedisParameter.Range(max, maxInclusive) : RedisMessage.RedisParameter.Range(min, minInclusive), RedisLiteral.WITHSCORES, RedisLiteral.LIMIT, offset, (count < 0 || count == long.MaxValue) ? -1 : count); } return(msg); }
Task <byte[][]> IListCommands.Range(int db, string key, int start, int stop, bool queueJump) { return (ExecuteMultiBytes( RedisMessage.Create(db, RedisLiteral.LRANGE, key, start, (stop == int.MaxValue ? -1 : stop)), queueJump)); }
private Task <long> ExecMultiAddRemove(int db, RedisLiteral command, string key, byte[][] values, bool queueJump) { RedisFeatures features; if (values.Length > 1 && ((features = Features) == null || !features.SetVaradicAddRemove)) { RedisTransaction tran = this as RedisTransaction; bool execute = false; if (tran == null) { tran = CreateTransaction(); execute = true; } Task <bool>[] tasks = new Task <bool> [values.Length]; for (int i = 0; i < values.Length; i++) { tasks[i] = ExecuteBoolean(RedisMessage.Create(db, command, key, values[i]), queueJump); } TaskCompletionSource <long> final = new TaskCompletionSource <long>(); tasks[values.Length - 1].ContinueWith(t => { try { if (t.ShouldSetResult(final)) { long count = 0; for (int i = 0; i < tasks.Length; i++) { if (tran.Wait(tasks[i])) { count++; } } final.TrySetResult(count); } } catch (Exception ex) { final.SafeSetException(ex); } }); if (execute) { tran.Execute(queueJump); } return(final.Task); } else { var args = new RedisMessage.RedisParameter[values.Length + 1]; args[0] = key; for (int i = 0; i < values.Length; i++) { args[i + 1] = values[i]; } return(ExecuteInt64(RedisMessage.Create(db, command, args), queueJump)); } }
Task <KeyValuePair <string, double>[]> ISortedSetCommands.RangeString(int db, string key, long start, long stop, bool ascending, bool queueJump) { return (ExecuteStringDoublePairs( RedisMessage.Create(db, ascending ? RedisLiteral.ZRANGE : RedisLiteral.ZREVRANGE, key, start, (stop == long.MaxValue ? -1 : stop), RedisLiteral.WITHSCORES), queueJump)); }
Task <DateTime> IServerCommands.GetLastSaveTime() { CheckAdmin(); TaskCompletionSource <DateTime> result = new TaskCompletionSource <DateTime>(); ExecuteInt64(RedisMessage.Create(-1, RedisLiteral.LASTSAVE), false, result).ContinueWith(lastSaveCallback); return(result.Task); }
Task <ClientInfo[]> IServerCommands.ListClients() { CheckAdmin(); TaskCompletionSource <ClientInfo[]> result = new TaskCompletionSource <ClientInfo[]>(); ExecuteString(RedisMessage.Create(-1, RedisLiteral.CLIENT, RedisLiteral.LIST), false, result).ContinueWith(listClientsCallback); return(result.Task); }
public Task <bool> Move(int db, string key, int targetDb, bool queueJump = false) { if (targetDb < 0) { throw new ArgumentOutOfRangeException("targetDb"); } return(ExecuteBoolean(RedisMessage.Create(db, RedisLiteral.MOVE, key, targetDb), queueJump)); }
Task <Dictionary <string, string> > IServerCommands.GetInfo(string section, bool queueJump) { var msg = string.IsNullOrEmpty(section) ? RedisMessage.Create(-1, RedisLiteral.INFO) : RedisMessage.Create(-1, RedisLiteral.INFO, section); var source = new TaskCompletionSource <Dictionary <string, string> >(); ExecuteString(msg, queueJump, source).ContinueWith(getInfoCallback); return(source.Task); }
/// <summary> /// The INFO command returns information and statistics about the server in format that is simple to parse by computers and easy to red by humans. /// </summary> /// <remarks>http://redis.io/commands/info</remarks> public Task <string> GetInfo(string category, bool queueJump = false) { RedisMessage msg = string.IsNullOrEmpty(category) ? RedisMessage.Create(-1, RedisLiteral.INFO) : RedisMessage.Create(-1, RedisLiteral.INFO, category); return(ExecuteString(msg, queueJump)); }
public Task <long> Remove(int db, string[] keys, bool queueJump = false) { return (ExecuteInt64( (keys.Length == 1 ? RedisMessage.Create(db, RedisLiteral.DEL, keys[0]) : RedisMessage.Create(db, RedisLiteral.DEL, keys)), queueJump)); }
Task <Dictionary <string, string> > IServerCommands.GetConfig(string pattern) { if (string.IsNullOrEmpty(pattern)) { pattern = "*"; } return(ExecuteStringPairs(RedisMessage.Create(-1, RedisLiteral.CONFIG, RedisLiteral.GET, pattern), false)); }
Task <string> IStringCommands.GetString(int db, string key, int start, int end, bool queueJump) { var features = this.Features; RedisLiteral cmd = features != null && features.Version < RedisFeatures.v2_1_0 ? RedisLiteral.SUBSTR : RedisLiteral.GETRANGE; return(ExecuteString(RedisMessage.Create(db, cmd, key, start, end), queueJump)); }
Task IServerCommands.MakeMaster() { CheckAdmin(); return (ExecuteVoid( RedisMessage.Create(-1, RedisLiteral.SLAVEOF, RedisLiteral.NO, RedisLiteral.ONE) .ExpectOk() .Critical(), false)); }
Task IServerCommands.KillClient(string address) { if (string.IsNullOrEmpty(address)) { throw new ArgumentNullException("address"); } CheckAdmin(); return(ExecuteVoid(RedisMessage.Create(-1, RedisLiteral.CLIENT, RedisLiteral.KILL, address).ExpectOk(), false)); }
Task <long> ISortedSetCommands.RemoveRange(int db, string key, double min, double max, bool minInclusive, bool maxInclusive, bool queueJump) { return (ExecuteInt64( RedisMessage.Create(db, RedisLiteral.ZREMRANGEBYSCORE, key, RedisMessage.RedisParameter.Range(min, minInclusive), RedisMessage.RedisParameter.Range(max, maxInclusive)), queueJump)); }
Task <CommandTrace[]> IServerCommands.GetSlowCommands(int?count) { CheckAdmin(); TaskCompletionSource <CommandTrace[]> result = new TaskCompletionSource <CommandTrace[]>(); RedisMessage msg = count == null?RedisMessage.Create(-1, RedisLiteral.SLOWLOG, RedisLiteral.GET) : RedisMessage.Create(-1, RedisLiteral.SLOWLOG, RedisLiteral.GET, count.Value); ExecuteRaw(msg, false, result).ContinueWith(slowlogCallback); return(result.Task); }
Task <long> ISortedSetCommands.UnionAndStore(int db, string destination, string[] keys, RedisAggregate aggregate, bool queueJump) { string[] parameters = new string[keys.Length + 3]; //prepend the number of keys and append the aggregate keyword and the aggregation type parameters[0] = keys.Length.ToString(); keys.CopyTo(parameters, 1); parameters[keys.Length + 1] = "AGGREGATE"; parameters[keys.Length + 2] = aggregate.ToString(); return(ExecuteInt64(RedisMessage.Create(db, RedisLiteral.ZUNIONSTORE, destination, parameters), queueJump)); }
Task <long> IHashCommands.Remove(int db, string key, string[] fields, bool queueJump) { RedisFeatures features; if (fields.Length > 1 && ((features = Features) == null || !features.HashVaradicDelete)) { var tran = this as RedisTransaction; bool execute = false; if (tran == null) { tran = CreateTransaction(); execute = true; } var tasks = new Task <bool> [fields.Length]; IHashCommands hashes = tran.Hashes; for (int i = 0; i < fields.Length; i++) { tasks[i] = hashes.Remove(db, key, fields[i], queueJump); } var final = new TaskCompletionSource <long>(); tasks[fields.Length - 1].ContinueWith(t => { if (t.IsFaulted) { final.SetException(t.Exception); } try { long count = 0; for (int i = 0; i < tasks.Length; i++) { if (tran.Wait(tasks[i])) { count++; } } final.SetResult(count); } catch (Exception ex) { final.SetException(ex); } }); if (execute) { tran.Execute(queueJump); } return(final.Task); } else { return(ExecuteInt64(RedisMessage.Create(db, RedisLiteral.HDEL, key, fields), queueJump)); } }
private Task <long> ExecMultiAddRemove(int db, RedisLiteral command, string key, string[] values, bool queueJump) { RedisFeatures features; if (values.Length > 1 && ((features = Features) == null || !features.SetVaradicAddRemove)) { var tran = this as RedisTransaction; bool execute = false; if (tran == null) { tran = CreateTransaction(); execute = true; } var tasks = new Task <bool> [values.Length]; ISetCommands sets = tran.Sets; for (int i = 0; i < values.Length; i++) { tasks[i] = ExecuteBoolean(RedisMessage.Create(db, command, key, values[i]), queueJump); } var final = new TaskCompletionSource <long>(); tasks[values.Length - 1].ContinueWith(t => { if (t.IsFaulted) { final.SetException(t.Exception); } try { long count = 0; for (int i = 0; i < tasks.Length; i++) { if (tran.Wait(tasks[i])) { count++; } } final.SetResult(count); } catch (Exception ex) { final.SetException(ex); } }); if (execute) { tran.Execute(queueJump); } return(final.Task); } else { return(ExecuteInt64(RedisMessage.Create(db, command, key, values), queueJump)); } }
static RedisMessage GetBlockingPop(int db, RedisLiteral command, string[] keys, int timeoutSeconds) { var args = new RedisMessage.RedisParameter[keys.Length + 1]; for (int i = 0; i < keys.Length; i++) { args[i] = keys[i]; } args[keys.Length] = timeoutSeconds; return(RedisMessage.Create(db, command, args)); }
internal Task <Tuple <string, int> > QuerySentinelMaster(string serviceName) { if (string.IsNullOrEmpty(serviceName)) { throw new ArgumentNullException("serviceName"); } TaskCompletionSource <Tuple <string, int> > taskSource = new TaskCompletionSource <Tuple <string, int> >(); ExecuteMultiString(RedisMessage.Create(-1, RedisLiteral.SENTINEL, "get-master-addr-by-name", serviceName), false, taskSource) .ContinueWith(querySentinelMasterCallback); return(taskSource.Task); }
Task IHashCommands.Set(int db, string key, Dictionary <string, byte[]> values, bool queueJump) { var keyAndFields = new RedisMessage.RedisParameter[(values.Count * 2) + 1]; int index = 0; keyAndFields[index++] = key; foreach (var pair in values) { keyAndFields[index++] = pair.Key; keyAndFields[index++] = pair.Value; } return(ExecuteVoid(RedisMessage.Create(db, RedisLiteral.HMSET, keyAndFields), queueJump)); }
/// <summary> /// Attempts to open the connection to the remote server /// </summary> public async Task Open() { int foundState; if ( (foundState = Interlocked.CompareExchange(ref state, (int)ConnectionState.Opening, (int)ConnectionState.Shiny)) != (int)ConnectionState.Shiny) { throw new InvalidOperationException("Connection is " + (ConnectionState)foundState); // not shiny } try { OnOpening(); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { NoDelay = true, SendTimeout = ioTimeout }; socket.Connect(host, port); redisStream = new NetworkStream(socket); outBuffer = new BufferedStream(redisStream, 512); // buffer up operations redisStream.ReadTimeout = redisStream.WriteTimeout = ioTimeout; var thread = new Thread(Outgoing) { IsBackground = true, Name = "Redis:outgoing" }; thread.Start(); if (!string.IsNullOrEmpty(password)) { EnqueueMessage(RedisMessage.Create(-1, RedisLiteral.AUTH, password).ExpectOk().Critical(), true); } Task <string> info = GetInfo(); OnInitConnection(); ReadMoreAsync(); var result = await info; ProcessInfo(result); //return ContinueWith(info, ProcessInfo); } catch { Interlocked.CompareExchange(ref state, (int)ConnectionState.Closed, (int)ConnectionState.Opening); throw; } }