private ServerEndPoint Select(int slot, RedisCommand command, CommandFlags flags) { flags = Message.GetMasterSlaveFlags(flags); // only intersted in master/slave preferences ServerEndPoint[] arr; if (slot == NoSlot || (arr = map) == null) { return(Any(command, flags)); } ServerEndPoint endpoint = arr[slot], testing; // but: ^^^ is the MASTER slots; if we want a slave, we need to do some thinking if (endpoint != null) { switch (flags) { case CommandFlags.DemandSlave: return(FindSlave(endpoint, command) ?? Any(command, flags)); case CommandFlags.PreferSlave: testing = FindSlave(endpoint, command); if (testing != null) { return(testing); } break; case CommandFlags.DemandMaster: return(FindMaster(endpoint, command) ?? Any(command, flags)); case CommandFlags.PreferMaster: testing = FindMaster(endpoint, command); if (testing != null) { return(testing); } break; } if (endpoint.IsSelectable(command)) { return(endpoint); } } return(Any(command, flags)); }
private void LogNonPreferred(CommandFlags flags, bool isSlave) { if ((flags & Message.InternalCallFlag) == 0) // don't log internal-call { if (isSlave) { if (Message.GetMasterSlaveFlags(flags) == CommandFlags.PreferMaster) { Interlocked.Increment(ref nonPreferredEndpointCount); } } else { if (Message.GetMasterSlaveFlags(flags) == CommandFlags.PreferSlave) { Interlocked.Increment(ref nonPreferredEndpointCount); } } } }
private void FixFlags(Message message, ServerEndPoint server) { // since the server is specified explicitly, we don't want defaults // to make the "non-preferred-endpoint" counters look artificially // inflated; note we only change *prefer* options switch (Message.GetMasterSlaveFlags(message.Flags)) { case CommandFlags.PreferMaster: if (server.IsSlave) { message.SetPreferSlave(); } break; case CommandFlags.PreferSlave: if (!server.IsSlave) { message.SetPreferMaster(); } break; } }
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 // 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) ? null : server; break; case CommandFlags.PreferMaster: resendVia = server.IsSelectable(command) ? FindSlave(server, command) : server; break; case CommandFlags.PreferSlave: resendVia = FindSlave(server, command) ?? (server.IsSelectable(command) ? null : server); break; case CommandFlags.DemandSlave: resendVia = FindSlave(server, command); break; } if (resendVia == null) { multiplexer.Trace("Unable to resend to " + endpoint); } else { message.PrepareToResend(resendVia, isMoved); retry = resendVia.TryEnqueue(message); } } 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 == null ? null : oldServer.EndPoint, endpoint); } } return(retry); } return(false); } catch { return(false); } }