Пример #1
0
        internal void KeepAlive()
        {
            var     commandMap = Multiplexer.CommandMap;
            Message msg        = null;

            switch (ConnectionType)
            {
            case ConnectionType.Interactive:
                msg = ServerEndPoint.GetTracerMessage(false);
                msg.SetSource(ResultProcessor.Tracer, null);
                break;

            case ConnectionType.Subscription:
                if (commandMap.IsAvailable(RedisCommand.UNSUBSCRIBE))
                {
                    msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.UNSUBSCRIBE,
                                         (RedisChannel)Guid.NewGuid().ToByteArray());
                    msg.SetSource(ResultProcessor.TrackSubscriptions, null);
                }
                break;
            }
            if (msg != null)
            {
                msg.SetInternalCall();
                Multiplexer.Trace("Enqueue: " + msg);
                if (!TryEnqueue(msg, ServerEndPoint.IsSlave))
                {
                    OnInternalError(ExceptionFactory.NoConnectionAvailable(Multiplexer.IncludeDetailInExceptions, Multiplexer.IncludePerformanceCountersInExceptions, msg.Command, msg, ServerEndPoint, Multiplexer.GetServerSnapshot()));
                }
            }
        }
Пример #2
0
        internal void KeepAlive()
        {
            if (!(physical?.IsIdle() ?? false))
            {
                return;                                 // don't pile on if already doing something
            }
            var     commandMap = Multiplexer.CommandMap;
            Message msg        = null;
            var     features   = ServerEndPoint.GetFeatures();

            switch (ConnectionType)
            {
            case ConnectionType.Interactive:
                msg = ServerEndPoint.GetTracerMessage(false);
                msg.SetSource(ResultProcessor.Tracer, null);
                break;

            case ConnectionType.Subscription:
                if (commandMap.IsAvailable(RedisCommand.PING) && features.PingOnSubscriber)
                {
                    msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.PING);
                    msg.SetSource(ResultProcessor.Tracer, null);
                }
                else if (commandMap.IsAvailable(RedisCommand.UNSUBSCRIBE))
                {
                    msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.UNSUBSCRIBE,
                                         (RedisChannel)Multiplexer.UniqueId);
                    msg.SetSource(ResultProcessor.TrackSubscriptions, null);
                }
                break;
            }

            if (msg != null)
            {
                msg.SetInternalCall();
                Multiplexer.Trace("Enqueue: " + msg);
                Multiplexer.OnInfoMessage($"heartbeat ({physical?.LastWriteSecondsAgo}s >= {ServerEndPoint?.WriteEverySeconds}s, {physical?.GetSentAwaitingResponseCount()} waiting) '{msg.CommandAndKey}' on '{PhysicalName}' (v{features.Version})");
                physical?.UpdateLastWriteTime(); // pre-emptively
#pragma warning disable CS0618
                var result = TryWriteSync(msg, ServerEndPoint.IsSlave);
#pragma warning restore CS0618

                if (result != WriteResult.Success)
                {
                    var ex = Multiplexer.GetException(result, msg, ServerEndPoint);
                    OnInternalError(ex);
                }
            }
        }
        public bool TryResend(int hashSlot, Message message, EndPoint endpoint, bool isMoved)
        {
            try
            {
                if (ServerType == ServerType.Standalone || hashSlot < 0 || hashSlot >= RedisClusterSlotCount)
                {
                    return(false);
                }

                ServerEndPoint server = multiplexer.GetServerEndPoint(endpoint);
                if (server != null)
                {
                    bool retry = false;
                    if ((message.Flags & CommandFlags.NoRedirect) == 0)
                    {
                        message.SetAsking(!isMoved);
                        message.SetNoRedirect(); // once is enough
                        if (isMoved)
                        {
                            message.SetInternalCall();
                        }

                        // note that everything so far is talking about MASTER nodes; we might be
                        // wanting a SLAVE, so we'll check
                        ServerEndPoint resendVia = null;
                        var            command   = message.Command;
                        switch (Message.GetMasterSlaveFlags(message.Flags))
                        {
                        case CommandFlags.DemandMaster:
                            resendVia = server.IsSelectable(command, isMoved) ? server : null;
                            break;

                        case CommandFlags.PreferMaster:
                            resendVia = server.IsSelectable(command, isMoved) ? server : FindSlave(server, command);
                            break;

                        case CommandFlags.PreferSlave:
                            resendVia = FindSlave(server, command, isMoved) ?? (server.IsSelectable(command, isMoved) ? server : null);
                            break;

                        case CommandFlags.DemandSlave:
                            resendVia = FindSlave(server, command, isMoved);
                            break;
                        }
                        if (resendVia == null)
                        {
                            multiplexer.Trace("Unable to resend to " + endpoint);
                        }
                        else
                        {
                            message.PrepareToResend(resendVia, isMoved);
                            retry = resendVia.TryWrite(message) == WriteResult.Success;
                        }
                    }

                    if (isMoved) // update map; note we can still update the map even if we aren't actually goint to resend
                    {
                        var arr       = MapForMutation();
                        var oldServer = arr[hashSlot];
                        arr[hashSlot] = server;
                        if (oldServer != server)
                        {
                            multiplexer.OnHashSlotMoved(hashSlot, oldServer?.EndPoint, endpoint);
                        }
                    }

                    return(retry);
                }
                return(false);
            }
            catch
            {
                return(false);
            }
        }