Commit 95271bbb authored by Nick Craver's avatar Nick Craver

Multiplexer: normalize line endings

parent a86a5e5f
......@@ -63,12 +63,12 @@ private static string GetDefaultClientName()
?? "StackExchange.Redis");
}
/// <summary>
/// <summary>
/// Tries to get the Roleinstance Id if Microsoft.WindowsAzure.ServiceRuntime is loaded.
/// In case of any failure, swallows the exception and returns null
/// In case of any failure, swallows the exception and returns null
/// </summary>
internal static string TryGetAzureRoleInstanceIdNoThrow()
{
{
#if NETSTANDARD1_5
return null;
#else
......@@ -132,7 +132,7 @@ internal void OnConnectionFailed(EndPoint endpoint, ConnectionType connectionTyp
ReconfigureIfNeeded(endpoint, false, "connection failed");
}
}
internal void OnInternalError(Exception exception, EndPoint endpoint = null, ConnectionType connectionType = ConnectionType.None, [CallerMemberName] string origin = null)
{
try
......@@ -175,8 +175,8 @@ private void OnEndpointChanged(EndPoint endpoint, EventHandler<EndPointEventArgs
);
}
}
internal void OnConfigurationChanged(EndPoint endpoint) => OnEndpointChanged(endpoint, ConfigurationChanged);
internal void OnConfigurationChanged(EndPoint endpoint) => OnEndpointChanged(endpoint, ConfigurationChanged);
internal void OnConfigurationChangedBroadcast(EndPoint endpoint) => OnEndpointChanged(endpoint, ConfigurationChangedBroadcast);
/// <summary>
......@@ -223,11 +223,11 @@ private static void Write<T>(ZipArchive zip, string name, Task task, Action<T, S
break;
}
}
}
}
/// <summary>
/// Write the configuration of all servers to an output stream
/// </summary>
/// <param name="destination">The destination stream to write the export to.</param>
/// </summary>
/// <param name="destination">The destination stream to write the export to.</param>
/// <param name="options">The options to use for this export.</param>
public void ExportConfiguration(Stream destination, ExportOptions options = ExportOptions.All)
{
......@@ -323,7 +323,7 @@ internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options
try
{
srv.Ping(flags); // if it isn't happy, we're not happy
}
}
catch (Exception ex)
{
LogLocked(log, "Operation failed on {0}, aborting: {1}", Format.ToString(srv.EndPoint), ex.Message);
......@@ -354,7 +354,7 @@ internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options
try
{
srv.SlaveOf(null, flags);
}
}
catch (Exception ex)
{
LogLocked(log, "Operation failed on {0}, aborting: {1}", Format.ToString(srv.EndPoint), ex.Message);
......@@ -406,30 +406,30 @@ internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options
/// <summary>
/// Used internally to synchronize loggine without depending on locking the log instance
/// </summary>
private object LogSyncLock => UniqueId;
// we know this has strong identity: readonly and unique to us
private object LogSyncLock => UniqueId;
// we know this has strong identity: readonly and unique to us
internal void LogLocked(TextWriter log, string line)
{
if (log != null) lock (LogSyncLock) { log.WriteLine(line); }
}
internal void LogLocked(TextWriter log, string line, object arg)
{
if (log != null) lock (LogSyncLock) { log.WriteLine(line, arg); }
}
internal void LogLocked(TextWriter log, string line, object arg0, object arg1)
{
if (log != null) lock (LogSyncLock) { log.WriteLine(line, arg0, arg1); }
}
internal void LogLocked(TextWriter log, string line, object arg0, object arg1, object arg2)
{
if (log != null) lock (LogSyncLock) { log.WriteLine(line, arg0, arg1, arg2); }
}
internal void LogLocked(TextWriter log, string line, params object[] args)
{
if (log != null) lock (LogSyncLock) { log.WriteLine(line, args); }
......@@ -481,11 +481,11 @@ private static void WriteNormalizingLineEndings(string source, StreamWriter writ
/// <summary>
/// Gets the timeout associated with the connections
/// </summary>
public int TimeoutMilliseconds => timeoutMilliseconds;
public int TimeoutMilliseconds => timeoutMilliseconds;
/// <summary>
/// Gets all endpoints defined on the server
/// </summary>
/// </summary>
/// <param name="configuredOnly">Whether to get only the endpoints specified explicitly in the config.</param>
public EndPoint[] GetEndPoints(bool configuredOnly = false)
{
......@@ -501,33 +501,33 @@ public EndPoint[] GetEndPoints(bool configuredOnly = false)
internal bool TryResend(int hashSlot, Message message, EndPoint endpoint, bool isMoved)
{
return serverSelectionStrategy.TryResend(hashSlot, message, endpoint, isMoved);
}
}
/// <summary>
/// Wait for a given asynchronous operation to complete (or timeout)
/// </summary>
/// </summary>
/// <param name="task">The task to wait on.</param>
public void Wait(Task task)
{
if (task == null) throw new ArgumentNullException(nameof(task));
if (!task.Wait(timeoutMilliseconds)) throw new TimeoutException();
}
}
/// <summary>
/// Wait for a given asynchronous operation to complete (or timeout)
/// </summary>
/// <typeparam name="T">The type contains in the task to wait on.</typeparam>
/// <param name="task">The task to wait on.</param>
/// </summary>
/// <typeparam name="T">The type contains in the task to wait on.</typeparam>
/// <param name="task">The task to wait on.</param>
public T Wait<T>(Task<T> task)
{
if (task == null) throw new ArgumentNullException(nameof(task));
if (!task.Wait(timeoutMilliseconds)) throw new TimeoutException();
return task.Result;
}
}
/// <summary>
/// Wait for the given asynchronous operations to complete (or timeout)
/// </summary>
/// </summary>
/// <param name="tasks">The tasks to wait on.</param>
public void WaitAll(params Task[] tasks)
{
......@@ -537,7 +537,7 @@ public void WaitAll(params Task[] tasks)
}
private bool WaitAllIgnoreErrors(Task[] tasks) => WaitAllIgnoreErrors(tasks, timeoutMilliseconds);
private static bool WaitAllIgnoreErrors(Task[] tasks, int timeout)
{
if (tasks == null) throw new ArgumentNullException(nameof(tasks));
......@@ -569,7 +569,7 @@ private static bool WaitAllIgnoreErrors(Task[] tasks, int timeout)
}
return false;
}
#if FEATURE_THREADPOOL
private void LogLockedWithThreadPoolStats(TextWriter log, string message, out int busyWorkerCount)
{
......@@ -595,7 +595,7 @@ private static bool AllComplete(Task[] tasks)
}
return true;
}
private async Task<bool> WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilliseconds, TextWriter log)
{
if (tasks == null) throw new ArgumentNullException(nameof(tasks));
......@@ -681,11 +681,11 @@ internal void OnHashSlotMoved(int hashSlot, EndPoint old, EndPoint @new)
new HashSlotMovedEventArgs(handler, this, hashSlot, old, @new)
);
}
}
}
/// <summary>
/// Compute the hash-slot of a specified key
/// </summary>
/// </summary>
/// <param name="key">The key to get a hash slot ID for.</param>
public int HashSlot(RedisKey key) => serverSelectionStrategy.HashSlot(key);
......@@ -710,7 +710,7 @@ internal ServerEndPoint AnyConnected(ServerType serverType, uint startOffset, Re
fallback = server;
break;
}
}
}
else
{
switch (flags)
......@@ -729,12 +729,12 @@ internal ServerEndPoint AnyConnected(ServerType serverType, uint startOffset, Re
}
private volatile bool isDisposed;
internal bool IsDisposed => isDisposed;
internal bool IsDisposed => isDisposed;
/// <summary>
/// Create a new ConnectionMultiplexer instance
/// </summary>
/// <param name="configuration">The string configuration to use for this multiplexer.</param>
/// </summary>
/// <param name="configuration">The string configuration to use for this multiplexer.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static async Task<ConnectionMultiplexer> ConnectAsync(string configuration, TextWriter log = null)
{
......@@ -750,7 +750,7 @@ public static async Task<ConnectionMultiplexer> ConnectAsync(string configuratio
}
killMe = null;
return muxer;
}
}
finally
{
if (killMe != null) try { killMe.Dispose(); } catch { }
......@@ -759,8 +759,8 @@ public static async Task<ConnectionMultiplexer> ConnectAsync(string configuratio
/// <summary>
/// Create a new ConnectionMultiplexer instance
/// </summary>
/// <param name="configuration">The configuration options to use for this multiplexer.</param>
/// </summary>
/// <param name="configuration">The configuration options to use for this multiplexer.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static async Task<ConnectionMultiplexer> ConnectAsync(ConfigurationOptions configuration, TextWriter log = null)
{
......@@ -776,7 +776,7 @@ public static async Task<ConnectionMultiplexer> ConnectAsync(ConfigurationOption
}
killMe = null;
return muxer;
}
}
finally
{
if (killMe != null) try { killMe.Dispose(); } catch { }
......@@ -790,11 +790,11 @@ private static ConnectionMultiplexer CreateMultiplexer(object configuration)
if (configuration is string)
{
config = ConfigurationOptions.Parse((string)configuration);
}
}
else if (configuration is ConfigurationOptions)
{
config = ((ConfigurationOptions)configuration).Clone();
}
}
else
{
throw new ArgumentException("configuration");
......@@ -806,8 +806,8 @@ private static ConnectionMultiplexer CreateMultiplexer(object configuration)
/// <summary>
/// Create a new ConnectionMultiplexer instance
/// </summary>
/// <param name="configuration">The string configuration to use for this multiplexer.</param>
/// </summary>
/// <param name="configuration">The string configuration to use for this multiplexer.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static ConnectionMultiplexer Connect(string configuration, TextWriter log = null)
{
......@@ -816,8 +816,8 @@ public static ConnectionMultiplexer Connect(string configuration, TextWriter log
/// <summary>
/// Create a new ConnectionMultiplexer instance
/// </summary>
/// <param name="configuration">The configurtion options to use for this multiplexer.</param>
/// </summary>
/// <param name="configuration">The configurtion options to use for this multiplexer.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static ConnectionMultiplexer Connect(ConfigurationOptions configuration, TextWriter log = null)
{
......@@ -962,9 +962,9 @@ private void OnHeartbeat()
private int lastHeartbeatTicks;
private static int lastGlobalHeartbeatTicks = Environment.TickCount;
internal long LastHeartbeatSecondsAgo
internal long LastHeartbeatSecondsAgo
{
get
get
{
if (pulse == null) return -1;
return unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastHeartbeatTicks)) / 1000;
......@@ -975,22 +975,22 @@ internal long LastHeartbeatSecondsAgo
internal static long LastGlobalHeartbeatSecondsAgo => unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastGlobalHeartbeatTicks)) / 1000;
internal CompletionManager UnprocessableCompletionManager => unprocessableCompletionManager;
internal CompletionManager UnprocessableCompletionManager => unprocessableCompletionManager;
/// <summary>
/// Obtain a pub/sub subscriber connection to the specified server
/// </summary>
/// </summary>
/// <param name="asyncState">The async state object to pass to the created <see cref="RedisSubscriber"/>.</param>
public ISubscriber GetSubscriber(object asyncState = null)
{
if (RawConfig.Proxy == Proxy.Twemproxy) throw new NotSupportedException("The pub/sub API is not available via twemproxy");
return new RedisSubscriber(this, asyncState);
}
}
/// <summary>
/// Obtain an interactive connection to a database inside redis
/// </summary>
/// <param name="db">The ID to get a database for.</param>
/// </summary>
/// <param name="db">The ID to get a database for.</param>
/// <param name="asyncState">The async state to pass into the resulting <see cref="RedisDatabase"/>.</param>
public IDatabase GetDatabase(int db = -1, object asyncState = null)
{
......@@ -1025,30 +1025,30 @@ public IDatabase GetDatabase(int db = -1, object asyncState = null)
/// <summary>
/// Obtain a configuration API for an individual server
/// </summary>
/// <param name="host">The host to get a server for.</param>
/// <param name="port">The port for <paramref name="host"/> to get a server for.</param>
/// </summary>
/// <param name="host">The host to get a server for.</param>
/// <param name="port">The port for <paramref name="host"/> to get a server for.</param>
/// <param name="asyncState">The async state to pass into the resulting <see cref="RedisServer"/>.</param>
public IServer GetServer(string host, int port, object asyncState = null) => GetServer(Format.ParseEndPoint(host, port), asyncState);
/// <summary>
/// Obtain a configuration API for an individual server
/// </summary>
/// <param name="hostAndPort">The "host:port" string to get a server for.</param>
/// </summary>
/// <param name="hostAndPort">The "host:port" string to get a server for.</param>
/// <param name="asyncState">The async state to pass into the resulting <see cref="RedisServer"/>.</param>
public IServer GetServer(string hostAndPort, object asyncState = null) => GetServer(Format.TryParseEndPoint(hostAndPort), asyncState);
public IServer GetServer(string hostAndPort, object asyncState = null) => GetServer(Format.TryParseEndPoint(hostAndPort), asyncState);
/// <summary>
/// Obtain a configuration API for an individual server
/// </summary>
/// <param name="host">The host to get a server for.</param>
/// </summary>
/// <param name="host">The host to get a server for.</param>
/// <param name="port">The port for <paramref name="host"/> to get a server for.</param>
public IServer GetServer(IPAddress host, int port) => GetServer(new IPEndPoint(host, port));
public IServer GetServer(IPAddress host, int port) => GetServer(new IPEndPoint(host, port));
/// <summary>
/// Obtain a configuration API for an individual server
/// </summary>
/// <param name="endpoint">The endpoint to get a server for.</param>
/// </summary>
/// <param name="endpoint">The endpoint to get a server for.</param>
/// <param name="asyncState">The async state to pass into the resulting <see cref="RedisServer"/>.</param>
public IServer GetServer(EndPoint endpoint, object asyncState = null)
{
......@@ -1064,7 +1064,7 @@ internal void Trace(string message, [CallerMemberName] string category = null)
{
OnTrace(message, category);
}
[Conditional("VERBOSE")]
internal void Trace(bool condition, string message, [CallerMemberName] string category = null)
{
......@@ -1079,7 +1079,7 @@ internal static void TraceWithoutContext(string message, [CallerMemberName] stri
{
OnTraceWithoutContext(message, category);
}
[Conditional("VERBOSE")]
internal static void TraceWithoutContext(bool condition, string message, [CallerMemberName] string category = null)
{
......@@ -1091,7 +1091,7 @@ internal static void TraceWithoutContext(bool condition, string message, [Caller
/// <summary>
/// The number of operations that have been performed on all connections
/// </summary>
public long OperationCount
public long OperationCount
{
get
{
......@@ -1117,17 +1117,17 @@ internal bool ReconfigureIfNeeded(EndPoint blame, bool fromBroadcast, string cau
Trace("Configuration change detected; checking nodes", "Configuration");
ReconfigureAsync(false, reconfigureAll, null, blame, cause, publishReconfigure, flags).ObserveErrors();
return true;
}
}
else
{
Trace("Configuration change skipped; already in progress via " + activeCause, "Configuration");
return false;
}
}
}
/// <summary>
/// Reconfigure the current connections based on the existing configuration
/// </summary>
/// </summary>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public Task<bool> ConfigureAsync(TextWriter log = null)
{
......@@ -1136,7 +1136,7 @@ public Task<bool> ConfigureAsync(TextWriter log = null)
/// <summary>
/// Reconfigure the current connections based on the existing configuration
/// </summary>
/// </summary>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public bool Configure(TextWriter log = null)
{
......@@ -1186,7 +1186,7 @@ public string GetStatus()
/// <summary>
/// Provides a text overview of the status of all connections
/// </summary>
/// </summary>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public void GetStatus(TextWriter log)
{
......@@ -1202,7 +1202,7 @@ public void GetStatus(TextWriter log)
LogLocked(log, "Sync timeouts: {0}; fire and forget: {1}; last heartbeat: {2}s ago",
Interlocked.Read(ref syncTimeouts), Interlocked.Read(ref fireAndForgets), LastHeartbeatSecondsAgo);
}
internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, TextWriter log, EndPoint blame, string cause, bool publishReconfigure = false, CommandFlags publishReconfigureFlags = CommandFlags.None)
{
if (isDisposed) throw new ObjectDisposedException(ToString());
......@@ -1526,7 +1526,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
{ }
}
return true;
}
}
catch (Exception ex)
{
Trace(ex.Message);
......@@ -1749,7 +1749,7 @@ internal ServerEndPoint SelectServer(int db, RedisCommand command, CommandFlags
{
return serverSelectionStrategy.Select(db, command, key, flags);
}
private bool TryPushMessageToBridge<T>(Message message, ResultProcessor<T> processor, ResultBox<T> resultBox, ref ServerEndPoint server)
{
message.SetSource(processor, resultBox);
......@@ -1768,8 +1768,8 @@ private bool TryPushMessageToBridge<T>(Message message, ResultProcessor<T> proce
switch (server.ServerType)
{
case ServerType.Cluster:
case ServerType.Twemproxy: // strictly speaking twemproxy uses a different hashing algo, but the hash-tag behavior is
// the same, so this does a pretty good job of spotting illegal commands before sending them
case ServerType.Twemproxy: // strictly speaking twemproxy uses a different hashing algo, but the hash-tag behavior is
// the same, so this does a pretty good job of spotting illegal commands before sending them
if (message.GetHashSlot(ServerSelectionStrategy) == ServerSelectionStrategy.MultipleSlots)
{
throw ExceptionFactory.MultiSlot(IncludeDetailInExceptions, message);
......@@ -1787,17 +1787,17 @@ private bool TryPushMessageToBridge<T>(Message message, ResultProcessor<T> proce
{
var profCtx = profiler?.GetContext();
if (profCtx != null && profiledCommands.TryGetValue(profCtx, out ConcurrentProfileStorageCollection inFlightForCtx))
{
{
message.SetProfileStorage(ProfileStorage.NewWithContext(inFlightForCtx, server));
}
if (message.Db >= 0)
{
int availableDatabases = server.Databases;
if (availableDatabases > 0 && message.Db >= availableDatabases)
{
throw ExceptionFactory.DatabaseOutfRange(IncludeDetailInExceptions, message.Db, message, server);
}
if (availableDatabases > 0 && message.Db >= availableDatabases)
{
throw ExceptionFactory.DatabaseOutfRange(IncludeDetailInExceptions, message.Db, message, server);
}
}
Trace("Queueing on server: " + message);
......@@ -1855,11 +1855,11 @@ public bool IsConnecting
internal ConfigurationOptions RawConfig => configuration;
internal ServerSelectionStrategy ServerSelectionStrategy => serverSelectionStrategy;
internal ServerSelectionStrategy ServerSelectionStrategy => serverSelectionStrategy;
/// <summary>
/// Close all connections and release all resources associated with this object
/// </summary>
/// </summary>
/// <param name="allowCommandsToComplete">Whether to allow all in-queue commands to complete first.</param>
public void Close(bool allowCommandsToComplete = true)
{
......@@ -1877,7 +1877,7 @@ public void Close(bool allowCommandsToComplete = true)
DisposeAndClearServers();
OnCloseReaderWriter();
}
partial void OnCloseReaderWriter();
private void DisposeAndClearServers()
......@@ -1912,7 +1912,7 @@ private Task[] QuitAllServers()
/// <summary>
/// Close all connections and release all resources associated with this object
/// </summary>
/// </summary>
/// <param name="allowCommandsToComplete">Whether to allow all in-queue commands to complete first.</param>
public async Task CloseAsync(bool allowCommandsToComplete = true)
{
......@@ -1970,7 +1970,7 @@ internal static void ThrowFailed<T>(TaskCompletionSource<T> source, Exception un
try
{
throw unthrownException;
}
}
catch (Exception ex)
{
source.TrySetException(ex);
......@@ -1978,7 +1978,7 @@ internal static void ThrowFailed<T>(TaskCompletionSource<T> source, Exception un
GC.SuppressFinalize(source.Task);
}
}
internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, ServerEndPoint server)
{
if (isDisposed) throw new ObjectDisposedException(ToString());
......@@ -2027,7 +2027,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
#endif
var sb = new StringBuilder("Timeout performing ").Append(message.CommandAndKey);
data = new List<Tuple<string, string>> { Tuple.Create("Message", message.CommandAndKey) };
void add(string lk, string sk, string v)
void add(string lk, string sk, string v)
{
data.Add(Tuple.Create(lk, v));
sb.Append(", ").Append(sk).Append(": ").Append(v);
......@@ -2063,9 +2063,9 @@ void add(string lk, string sk, string v)
data.Add(Tuple.Create("Busy-Workers", busyWorkerCount.ToString()));
#endif
#if FEATURE_PERFCOUNTER
if (IncludePerformanceCountersInExceptions)
{
add("Local-CPU", "Local-CPU", GetSystemCpuPercent());
if (IncludePerformanceCountersInExceptions)
{
add("Local-CPU", "Local-CPU", GetSystemCpuPercent());
}
#endif
sb.Append(" (Please take a look at this article for some common client-side issues that can cause timeouts: ");
......@@ -2099,24 +2099,24 @@ void add(string lk, string sk, string v)
Trace(message + " received " + val);
return val;
}
}
}
#if FEATURE_PERFCOUNTER
internal static string GetThreadPoolAndCPUSummary(bool includePerformanceCounters)
{
GetThreadPoolStats(out string iocp, out string worker);
var cpu = includePerformanceCounters ? GetSystemCpuPercent() : "n/a";
return $"IOCP: {iocp}, WORKER: {worker}, Local-CPU: {cpu}";
}
private static string GetSystemCpuPercent()
{
return (PerfCounterHelper.TryGetSystemCPU(out float systemCPU))
? Math.Round(systemCPU, 2) + "%"
: "unavailable";
}
internal static string GetThreadPoolAndCPUSummary(bool includePerformanceCounters)
{
GetThreadPoolStats(out string iocp, out string worker);
var cpu = includePerformanceCounters ? GetSystemCpuPercent() : "n/a";
return $"IOCP: {iocp}, WORKER: {worker}, Local-CPU: {cpu}";
}
private static string GetSystemCpuPercent()
{
return (PerfCounterHelper.TryGetSystemCPU(out float systemCPU))
? Math.Round(systemCPU, 2) + "%"
: "unavailable";
}
#endif
#if FEATURE_THREADPOOL
#if FEATURE_THREADPOOL
private static int GetThreadPoolStats(out string iocp, out string worker)
{
ThreadPool.GetMaxThreads(out int maxWorkerThreads, out int maxIoThreads);
......@@ -2148,8 +2148,8 @@ private static int GetThreadPoolStats(out string iocp, out string worker)
/// Limit at which to start recording unusual busy patterns (only one log will be retained at a time;
/// set to a negative value to disable this feature)
/// </summary>
public int StormLogThreshold { get; set; } = 15;
public int StormLogThreshold { get; set; } = 15;
/// <summary>
/// Obtains the log of unusual busy patterns
/// </summary>
......@@ -2166,12 +2166,12 @@ public void ResetStormLog()
Interlocked.Exchange(ref stormLogSnapshot, null);
Interlocked.Exchange(ref haveStormLog, 0);
}
private long syncTimeouts, fireAndForgets;
/// <summary>
/// Request all compatible clients to reconfigure or reconnect
/// </summary>
/// </summary>
/// <param name="flags">The command flags to use.</param>2
/// <returns>The number of instances known to have received the message (however, the actual number can be higher; returns -1 if the operation is pending)</returns>
public long PublishReconfigure(CommandFlags flags = CommandFlags.None)
......@@ -2187,17 +2187,17 @@ public long PublishReconfigure(CommandFlags flags = CommandFlags.None)
return PublishReconfigureImpl(flags);
}
}
private long PublishReconfigureImpl(CommandFlags flags)
{
byte[] channel = ConfigurationChangedChannel;
if (channel == null) return 0;
return GetSubscriber().Publish(channel, RedisLiterals.Wildcard, flags);
}
}
/// <summary>
/// Request all compatible clients to reconfigure or reconnect
/// </summary>
/// </summary>
/// <param name="flags">The command flags to use.</param>
/// <returns>The number of instances known to have received the message (however, the actual number can be higher)</returns>
public Task<long> PublishReconfigureAsync(CommandFlags flags = CommandFlags.None)
......@@ -2208,4 +2208,4 @@ public Task<long> PublishReconfigureAsync(CommandFlags flags = CommandFlags.None
return GetSubscriber().PublishAsync(channel, RedisLiterals.Wildcard, flags);
}
}
}
\ No newline at end of file
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment