improve threading synchronization for BaseConfigurationHandlers

This commit is contained in:
RaidMax 2023-04-04 21:42:17 -05:00
parent fab3cf95d6
commit c14042a109
2 changed files with 20 additions and 6 deletions

View File

@ -17,6 +17,7 @@ public class BaseConfigurationHandlerV2<TConfigurationType> : IConfigurationHand
{ {
private readonly ILogger<BaseConfigurationHandlerV2<TConfigurationType>> _logger; private readonly ILogger<BaseConfigurationHandlerV2<TConfigurationType>> _logger;
private readonly ConfigurationWatcher _watcher; private readonly ConfigurationWatcher _watcher;
private readonly JsonSerializerOptions _serializerOptions = new() private readonly JsonSerializerOptions _serializerOptions = new()
{ {
WriteIndented = true, WriteIndented = true,
@ -32,7 +33,8 @@ public class BaseConfigurationHandlerV2<TConfigurationType> : IConfigurationHand
private string _path = string.Empty; private string _path = string.Empty;
private event Action<string> FileUpdated; private event Action<string> FileUpdated;
public BaseConfigurationHandlerV2(ILogger<BaseConfigurationHandlerV2<TConfigurationType>> logger, ConfigurationWatcher watcher) public BaseConfigurationHandlerV2(ILogger<BaseConfigurationHandlerV2<TConfigurationType>> logger,
ConfigurationWatcher watcher)
{ {
_logger = logger; _logger = logger;
_watcher = watcher; _watcher = watcher;
@ -69,7 +71,7 @@ public class BaseConfigurationHandlerV2<TConfigurationType> : IConfigurationHand
await using var fileStream = File.OpenRead(_path); await using var fileStream = File.OpenRead(_path);
readConfiguration = readConfiguration =
await JsonSerializer.DeserializeAsync<TConfigurationType>(fileStream, _serializerOptions); await JsonSerializer.DeserializeAsync<TConfigurationType>(fileStream, _serializerOptions);
fileStream.Close(); await fileStream.DisposeAsync();
_watcher.Register(_path, FileUpdated); _watcher.Register(_path, FileUpdated);
if (readConfiguration is null) if (readConfiguration is null)
@ -115,7 +117,7 @@ public class BaseConfigurationHandlerV2<TConfigurationType> : IConfigurationHand
await InternalSet(_configurationInstance, true); await InternalSet(_configurationInstance, true);
} }
} }
private async Task InternalSet(TConfigurationType configuration, bool awaitSemaphore) private async Task InternalSet(TConfigurationType configuration, bool awaitSemaphore)
{ {
try try
@ -124,9 +126,10 @@ public class BaseConfigurationHandlerV2<TConfigurationType> : IConfigurationHand
{ {
await _onIo.WaitAsync(); await _onIo.WaitAsync();
} }
await using var fileStream = File.OpenWrite(_path); await using var fileStream = File.OpenWrite(_path);
await JsonSerializer.SerializeAsync(fileStream, configuration, _serializerOptions); await JsonSerializer.SerializeAsync(fileStream, configuration, _serializerOptions);
fileStream.Close(); await fileStream.DisposeAsync();
_configurationInstance = configuration; _configurationInstance = configuration;
} }
catch (Exception ex) catch (Exception ex)
@ -150,7 +153,7 @@ public class BaseConfigurationHandlerV2<TConfigurationType> : IConfigurationHand
await using var fileStream = File.OpenRead(_path); await using var fileStream = File.OpenRead(_path);
var readConfiguration = var readConfiguration =
await JsonSerializer.DeserializeAsync<TConfigurationType>(fileStream, _serializerOptions); await JsonSerializer.DeserializeAsync<TConfigurationType>(fileStream, _serializerOptions);
fileStream.Close(); await fileStream.DisposeAsync();
if (readConfiguration is null) if (readConfiguration is null)
{ {
@ -184,7 +187,8 @@ public class BaseConfigurationHandlerV2<TConfigurationType> : IConfigurationHand
return; return;
} }
_logger.LogDebug("Updating existing config with new values {Type} at {Path}", typeof(TConfigurationType).Name, _path); _logger.LogDebug("Updating existing config with new values {Type} at {Path}", typeof(TConfigurationType).Name,
_path);
if (_configurationInstance is IDictionary configDict && newConfiguration is IDictionary newConfigDict) if (_configurationInstance is IDictionary configDict && newConfiguration is IDictionary newConfigDict)
{ {

View File

@ -49,8 +49,10 @@ namespace IW4MAdmin.Application.Misc
{ {
try try
{ {
await _onSaving.WaitAsync();
await using var fileStream = File.OpenRead(FileName); await using var fileStream = File.OpenRead(FileName);
_configuration = await JsonSerializer.DeserializeAsync<T>(fileStream, _serializerOptions); _configuration = await JsonSerializer.DeserializeAsync<T>(fileStream, _serializerOptions);
await fileStream.DisposeAsync();
} }
catch (FileNotFoundException) catch (FileNotFoundException)
@ -66,6 +68,13 @@ namespace IW4MAdmin.Application.Misc
ConfigurationFileName = FileName ConfigurationFileName = FileName
}; };
} }
finally
{
if (_onSaving.CurrentCount == 0)
{
_onSaving.Release(1);
}
}
} }
public async Task Save() public async Task Save()
@ -76,6 +85,7 @@ namespace IW4MAdmin.Application.Misc
await using var fileStream = File.Create(FileName); await using var fileStream = File.Create(FileName);
await JsonSerializer.SerializeAsync(fileStream, _configuration, _serializerOptions); await JsonSerializer.SerializeAsync(fileStream, _configuration, _serializerOptions);
await fileStream.DisposeAsync();
} }
finally finally