feat: add reload semantics for cluster and jetstream options

This commit is contained in:
Joseph Doherty
2026-02-23 06:23:34 -05:00
parent 2aa7265db1
commit 6c83f12e5c
3 changed files with 120 additions and 1 deletions

View File

@@ -11,7 +11,8 @@ namespace NATS.Server.Configuration;
public static class ConfigReloader
{
// Non-reloadable options (match Go server — Host, Port, ServerName require restart)
private static readonly HashSet<string> NonReloadable = ["Host", "Port", "ServerName"];
private static readonly HashSet<string> NonReloadable =
["Host", "Port", "ServerName", "Cluster", "JetStream.StoreDir"];
// Logging-related options
private static readonly HashSet<string> LoggingOptions =
@@ -102,6 +103,13 @@ public static class ConfigReloader
CompareAndAdd(changes, "NoSystemAccount", oldOpts.NoSystemAccount, newOpts.NoSystemAccount);
CompareAndAdd(changes, "SystemAccount", oldOpts.SystemAccount, newOpts.SystemAccount);
// Cluster and JetStream (restart-required boundaries)
if (!ClusterEquivalent(oldOpts.Cluster, newOpts.Cluster))
changes.Add(new ConfigChange("Cluster", isNonReloadable: true));
if (JetStreamStoreDirChanged(oldOpts.JetStream, newOpts.JetStream))
changes.Add(new ConfigChange("JetStream.StoreDir", isNonReloadable: true));
return changes;
}
@@ -338,4 +346,35 @@ public static class ConfigReloader
isNonReloadable: NonReloadable.Contains(name)));
}
}
private static bool ClusterEquivalent(ClusterOptions? oldCluster, ClusterOptions? newCluster)
{
if (oldCluster is null && newCluster is null)
return true;
if (oldCluster is null || newCluster is null)
return false;
if (!string.Equals(oldCluster.Name, newCluster.Name, StringComparison.Ordinal))
return false;
if (!string.Equals(oldCluster.Host, newCluster.Host, StringComparison.Ordinal))
return false;
if (oldCluster.Port != newCluster.Port)
return false;
return oldCluster.Routes.SequenceEqual(newCluster.Routes, StringComparer.Ordinal);
}
private static bool JetStreamStoreDirChanged(JetStreamOptions? oldJetStream, JetStreamOptions? newJetStream)
{
if (oldJetStream is null && newJetStream is null)
return false;
if (oldJetStream is null || newJetStream is null)
return true;
return !string.Equals(oldJetStream.StoreDir, newJetStream.StoreDir, StringComparison.Ordinal);
}
}