feat: integrate config file loading and SIGHUP hot reload
Wire up the config parsing infrastructure into the server: - NatsServer: add ReloadConfig() with digest-based change detection, diff/validate, CLI override preservation, and side-effect triggers - Program.cs: two-pass CLI parsing — load config file first, then apply CLI args on top with InCmdLine tracking for reload precedence - SIGHUP handler upgraded from stub warning to actual reload - Remove config file "not yet supported" warning from StartAsync - Add integration tests for config loading, CLI overrides, and reload validation
This commit is contained in:
@@ -1,85 +1,124 @@
|
||||
using NATS.Server;
|
||||
using NATS.Server.Configuration;
|
||||
using Serilog;
|
||||
using Serilog.Sinks.SystemConsole.Themes;
|
||||
|
||||
var options = new NatsOptions();
|
||||
// First pass: scan args for -c flag to get config file path
|
||||
string? configFile = null;
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
if (args[i] == "-c" && i + 1 < args.Length)
|
||||
{
|
||||
configFile = args[++i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse ALL CLI flags into NatsOptions first
|
||||
// If config file specified, load it as the base options
|
||||
var options = configFile != null
|
||||
? ConfigProcessor.ProcessConfigFile(configFile)
|
||||
: new NatsOptions();
|
||||
|
||||
// Second pass: apply CLI args on top of config-loaded options, tracking InCmdLine
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
switch (args[i])
|
||||
{
|
||||
case "-p" or "--port" when i + 1 < args.Length:
|
||||
options.Port = int.Parse(args[++i]);
|
||||
options.InCmdLine.Add("Port");
|
||||
break;
|
||||
case "-a" or "--addr" when i + 1 < args.Length:
|
||||
options.Host = args[++i];
|
||||
options.InCmdLine.Add("Host");
|
||||
break;
|
||||
case "-n" or "--name" when i + 1 < args.Length:
|
||||
options.ServerName = args[++i];
|
||||
options.InCmdLine.Add("ServerName");
|
||||
break;
|
||||
case "-m" or "--http_port" when i + 1 < args.Length:
|
||||
options.MonitorPort = int.Parse(args[++i]);
|
||||
options.InCmdLine.Add("MonitorPort");
|
||||
break;
|
||||
case "--http_base_path" when i + 1 < args.Length:
|
||||
options.MonitorBasePath = args[++i];
|
||||
options.InCmdLine.Add("MonitorBasePath");
|
||||
break;
|
||||
case "--https_port" when i + 1 < args.Length:
|
||||
options.MonitorHttpsPort = int.Parse(args[++i]);
|
||||
options.InCmdLine.Add("MonitorHttpsPort");
|
||||
break;
|
||||
case "-c" when i + 1 < args.Length:
|
||||
options.ConfigFile = args[++i];
|
||||
// Already handled in first pass; skip the value
|
||||
i++;
|
||||
break;
|
||||
case "--pid" when i + 1 < args.Length:
|
||||
options.PidFile = args[++i];
|
||||
options.InCmdLine.Add("PidFile");
|
||||
break;
|
||||
case "--ports_file_dir" when i + 1 < args.Length:
|
||||
options.PortsFileDir = args[++i];
|
||||
options.InCmdLine.Add("PortsFileDir");
|
||||
break;
|
||||
case "--tls":
|
||||
break;
|
||||
case "--tlscert" when i + 1 < args.Length:
|
||||
options.TlsCert = args[++i];
|
||||
options.InCmdLine.Add("TlsCert");
|
||||
break;
|
||||
case "--tlskey" when i + 1 < args.Length:
|
||||
options.TlsKey = args[++i];
|
||||
options.InCmdLine.Add("TlsKey");
|
||||
break;
|
||||
case "--tlscacert" when i + 1 < args.Length:
|
||||
options.TlsCaCert = args[++i];
|
||||
options.InCmdLine.Add("TlsCaCert");
|
||||
break;
|
||||
case "--tlsverify":
|
||||
options.TlsVerify = true;
|
||||
options.InCmdLine.Add("TlsVerify");
|
||||
break;
|
||||
case "-D" or "--debug":
|
||||
options.Debug = true;
|
||||
options.InCmdLine.Add("Debug");
|
||||
break;
|
||||
case "-V" or "-T" or "--trace":
|
||||
options.Trace = true;
|
||||
options.InCmdLine.Add("Trace");
|
||||
break;
|
||||
case "-DV":
|
||||
options.Debug = true;
|
||||
options.Trace = true;
|
||||
options.InCmdLine.Add("Debug");
|
||||
options.InCmdLine.Add("Trace");
|
||||
break;
|
||||
case "-l" or "--log" or "--log_file" when i + 1 < args.Length:
|
||||
options.LogFile = args[++i];
|
||||
options.InCmdLine.Add("LogFile");
|
||||
break;
|
||||
case "--log_size_limit" when i + 1 < args.Length:
|
||||
options.LogSizeLimit = long.Parse(args[++i]);
|
||||
options.InCmdLine.Add("LogSizeLimit");
|
||||
break;
|
||||
case "--log_max_files" when i + 1 < args.Length:
|
||||
options.LogMaxFiles = int.Parse(args[++i]);
|
||||
options.InCmdLine.Add("LogMaxFiles");
|
||||
break;
|
||||
case "--logtime" when i + 1 < args.Length:
|
||||
options.Logtime = bool.Parse(args[++i]);
|
||||
options.InCmdLine.Add("Logtime");
|
||||
break;
|
||||
case "--logtime_utc":
|
||||
options.LogtimeUTC = true;
|
||||
options.InCmdLine.Add("LogtimeUTC");
|
||||
break;
|
||||
case "--syslog":
|
||||
options.Syslog = true;
|
||||
options.InCmdLine.Add("Syslog");
|
||||
break;
|
||||
case "--remote_syslog" when i + 1 < args.Length:
|
||||
options.RemoteSyslog = args[++i];
|
||||
options.InCmdLine.Add("RemoteSyslog");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -136,6 +175,14 @@ Log.Logger = logConfig.CreateLogger();
|
||||
using var loggerFactory = new Serilog.Extensions.Logging.SerilogLoggerFactory(Log.Logger);
|
||||
using var server = new NatsServer(options, loggerFactory);
|
||||
|
||||
// Store CLI snapshot for reload precedence (CLI flags always win over config file)
|
||||
if (configFile != null && options.InCmdLine.Count > 0)
|
||||
{
|
||||
var cliSnapshot = new NatsOptions();
|
||||
ConfigReloader.MergeCliOverrides(cliSnapshot, options, options.InCmdLine);
|
||||
server.SetCliSnapshot(cliSnapshot, options.InCmdLine);
|
||||
}
|
||||
|
||||
// Register signal handlers
|
||||
server.HandleSignals();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user