in src/Config/FileSystemRuntimeConfigLoader.cs [190:289]
public bool TryLoadConfig(
string path,
[NotNullWhen(true)] out RuntimeConfig? outConfig,
bool replaceEnvVar = false,
ILogger? logger = null,
bool? isDevMode = null)
{
if (_fileSystem.File.Exists(path))
{
Console.WriteLine($"Loading config file from {_fileSystem.Path.GetFullPath(path)}.");
// Use File.ReadAllText because DAB doesn't need write access to the file
// and ensures the file handle is released immediately after reading.
// Previous usage of File.Open may cause file locking issues when
// actively using hot-reload and modifying the config file in a text editor.
// Includes an exponential back-off retry mechanism to accommodate
// circumstances where the file may be in use by another process.
int runCount = 1;
string json = string.Empty;
while (runCount <= FileUtilities.RunLimit)
{
try
{
json = _fileSystem.File.ReadAllText(path);
break;
}
catch (IOException ex)
{
Console.WriteLine($"IO Exception, retrying due to {ex.Message}");
if (runCount == FileUtilities.RunLimit)
{
throw;
}
Thread.Sleep(TimeSpan.FromSeconds(Math.Pow(FileUtilities.ExponentialRetryBase, runCount)));
runCount++;
}
}
if (!string.IsNullOrEmpty(json) && TryParseConfig(json, out RuntimeConfig, connectionString: _connectionString, replaceEnvVar: replaceEnvVar))
{
if (TrySetupConfigFileWatcher())
{
Console.WriteLine("Monitoring config: {0} for hot-reloading.", ConfigFilePath);
logger?.LogInformation("Monitoring config: {ConfigFilePath} for hot-reloading.", ConfigFilePath);
}
// When isDevMode is not null it means we are in a hot-reload scenario, and need to save the previous
// mode in the new RuntimeConfig since we do not support hot-reload of the mode.
if (isDevMode is not null && RuntimeConfig.Runtime is not null && RuntimeConfig.Runtime.Host is not null)
{
// Log error when the mode is changed during hot-reload.
if (isDevMode != this.RuntimeConfig.IsDevelopmentMode())
{
if (logger is null)
{
Console.WriteLine("Hot-reload doesn't support switching mode. Please restart the service to switch the mode.");
}
else
{
logger.LogError("Hot-reload doesn't support switching mode. Please restart the service to switch the mode.");
}
}
RuntimeConfig.Runtime.Host.Mode = (bool)isDevMode ? HostMode.Development : HostMode.Production;
}
outConfig = RuntimeConfig;
if (LastValidRuntimeConfig is null)
{
LastValidRuntimeConfig = RuntimeConfig;
}
return true;
}
if (LastValidRuntimeConfig is not null)
{
RuntimeConfig = LastValidRuntimeConfig;
}
outConfig = null;
return false;
}
if (logger is null)
{
string errorMessage = $"Unable to find config file: {path} does not exist.";
Console.Error.WriteLine(errorMessage);
}
else
{
string errorMessage = "Unable to find config file: {path} does not exist.";
logger.LogError(message: errorMessage, path);
}
outConfig = null;
return false;
}