internal override Task <T> ExecuteAsync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { if (message == null) { return(CompletedTask <T> .Default(asyncState)); } multiplexer.CheckMessage(message); // prepare the inner command as a task Task <T> task; if (message.IsFireAndForget) { task = CompletedTask <T> .Default(null); // F+F explicitly does not get async-state } else { var source = TaskResultBox <T> .Create(out var tcs, asyncState); task = tcs.Task; message.SetSource(source, processor); } // store it (pending ?? (pending = new List <Message>())).Add(message); return(task); }
internal Task AddSubscription(RedisChannel channel, Action <RedisChannel, RedisValue> handler, CommandFlags flags, object asyncState) { if (handler != null) { lock (subscriptions) { Subscription sub; if (subscriptions.TryGetValue(channel, out sub)) { sub.Add(handler); } else { sub = new Subscription(handler); subscriptions.Add(channel, sub); var task = sub.SubscribeToServer(this, channel, flags, asyncState, false); if (task != null) { return(task); } } } } return(CompletedTask <bool> .Default(asyncState)); }
internal Task RemoveAllSubscriptions(CommandFlags flags, object asyncState) { Task last = CompletedTask <bool> .Default(asyncState); lock (subscriptions) { foreach (var pair in subscriptions) { var msg = pair.Value.ForSyncShutdown(); if (msg != null) { UnprocessableCompletionManager.CompleteSyncOrAsync(msg); } pair.Value.Remove(true, null); pair.Value.Remove(false, null); var task = pair.Value.UnsubscribeFromServer(pair.Key, flags, asyncState, false); if (task != null) { last = task; } } subscriptions.Clear(); } return(last); }
internal Task RemoveAllSubscriptionBefore(CommandFlags flags, object asyncState) { Task last = CompletedTask <bool> .Default(asyncState); var unSubStart = DateTime.Now.Ticks; foreach (var pair in subscriptions) { var task = pair.Value.UnsubscribeFromServer(pair.Key, flags, asyncState, false); if (task != null) { task.Wait(100); } } var unSubEnd = DateTime.Now.Ticks; var ts = new TimeSpan((unSubEnd - unSubStart) * 10); Console.WriteLine("itTime:" + (unSubEnd - unSubStart)); lock (subscriptions) { Thread.Sleep(ts); //subscriptions[0] //pair.Value.Remove(null); // always wipes subscriptions.Clear(); } //Thread.Sleep(ts); return(last); }
internal virtual Task <T> ExecuteAsync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { if (message == null) { return(CompletedTask <T> .Default(asyncState)); } multiplexer.CheckMessage(message); return(multiplexer.ExecuteAsyncImpl <T>(message, processor, asyncState, server)); }
internal override Task <T> ExecuteAsync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { if (message == null) { return(CompletedTask <T> .Default(asyncState)); } multiplexer.CheckMessage(message); multiplexer.Trace("Wrapping " + message.Command, "Transaction"); // prepare the inner command as a task Task <T> task; if (message.IsFireAndForget) { task = CompletedTask <T> .Default(null); // F+F explicitly does not get async-state } else { var tcs = TaskSource.Create <T>(asyncState); var source = ResultBox <T> .Get(tcs); message.SetSource(source, processor); task = tcs.Task; } // prepare an outer-command that decorates that, but expects QUEUED var queued = new QueuedMessage(message); var wasQueued = ResultBox <bool> .Get(null); queued.SetSource(wasQueued, QueuedProcessor.Default); // store it, and return the task of the *outer* command // (there is no task for the inner command) lock (SyncLock) { (_pending ?? (_pending = new List <QueuedMessage>())).Add(queued); switch (message.Command) { case RedisCommand.UNKNOWN: case RedisCommand.EVAL: case RedisCommand.EVALSHA: // people can do very naughty things in an EVAL // including change the DB; change it back to what we // think it should be! var sel = PhysicalConnection.GetSelectDatabaseCommand(message.Db); queued = new QueuedMessage(sel); wasQueued = ResultBox <bool> .Get(null); queued.SetSource(wasQueued, QueuedProcessor.Default); _pending.Add(queued); break; } } return(task); }
internal Task Close() { var tmp = interactive; if (tmp == null || !tmp.IsConnected || !Multiplexer.CommandMap.IsAvailable(RedisCommand.QUIT)) { return(CompletedTask <bool> .Default(null)); } else { return(QueueDirectAsync(Message.Create(-1, CommandFlags.None, RedisCommand.QUIT), ResultProcessor.DemandOK, bridge: interactive)); } }
internal virtual Task <T[]> ExecuteAsync <T>(Message[] messages, ResultProcessor <T> processor, ServerEndPoint server = null) { if (messages == null) { return(CompletedTask <T[]> .Default(asyncState)); } foreach (var message in messages) { multiplexer.CheckMessage(message); } return(multiplexer.ExecuteAsyncImpl <T>(messages, processor, asyncState, server)); }
internal Task RemoveSubscription(RedisChannel channel, Action <RedisChannel, RedisValue> handler, CommandFlags flags, object asyncState) { lock (subscriptions) { if (subscriptions.TryGetValue(channel, out Subscription sub) && sub.Remove(handler)) { subscriptions.Remove(channel); var task = sub.UnsubscribeFromServer(channel, flags, asyncState, false); if (task != null) { return(task); } } } return(CompletedTask <bool> .Default(asyncState)); }
internal Task RemoveAllSubscriptions(CommandFlags flags, object asyncState) { Task last = CompletedTask <bool> .Default(asyncState); lock (subscriptions) { foreach (var pair in subscriptions) { pair.Value.Remove(null); // always wipes var task = pair.Value.UnsubscribeFromServer(pair.Key, flags, asyncState, false); if (task != null) { last = task; } } subscriptions.Clear(); } return(last); }
internal override Task <T> ExecuteAsync <T>(Message message, ResultProcessor <T> processor, ServerEndPoint server = null) { // inject our expected server automatically if (server == null) { server = this.server; } FixFlags(message, server); if (!server.IsConnected) { if (message == null) { return(CompletedTask <T> .Default(asyncState)); } if (message.IsFireAndForget) { return(CompletedTask <T> .Default(null)); // F+F explicitly does not get async-state } // no need to deny exec-sync here; will be complete before they see if var tcs = TaskSource.Create <T>(asyncState); ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server)); return(tcs.Task); } return(base.ExecuteAsync <T>(message, processor, server)); }