Avoid concurrent config file writes

This commit is contained in:
kaso17
2017-01-05 18:08:10 +01:00
parent 175bea9269
commit 8e5538a11e

View File

@@ -28,6 +28,8 @@ namespace Jackett.Services
public class IndexerManagerService : IIndexerManagerService
{
private static readonly object configWriteLock = new object();
private IContainer container;
private IConfigurationService configService;
private Logger logger;
@@ -177,60 +179,63 @@ namespace Jackett.Services
public void SaveConfig(IIndexer indexer, JToken obj)
{
var uID = Guid.NewGuid().ToString("N");
var configFilePath = GetIndexerConfigFilePath(indexer);
var configFilePathBak = configFilePath + ".bak";
var configFilePathTmp = configFilePath + "." + uID + ".tmp";
var content = obj.ToString();
logger.Debug(string.Format("Saving new config file: {0}", configFilePathTmp));
if (string.IsNullOrWhiteSpace(content))
lock (configWriteLock)
{
throw new Exception(string.Format("New config content for {0} is empty, please report this bug.", indexer.ID));
}
var uID = Guid.NewGuid().ToString("N");
var configFilePath = GetIndexerConfigFilePath(indexer);
var configFilePathBak = configFilePath + ".bak";
var configFilePathTmp = configFilePath + "." + uID + ".tmp";
var content = obj.ToString();
if (content.Contains("\x00"))
{
throw new Exception(string.Format("New config content for {0} contains 0x00, please report this bug. Content: {1}", indexer.ID, content));
}
logger.Debug(string.Format("Saving new config file: {0}", configFilePathTmp));
// make sure the config directory exists
if (!Directory.Exists(configService.GetIndexerConfigDir()))
Directory.CreateDirectory(configService.GetIndexerConfigDir());
if (string.IsNullOrWhiteSpace(content))
{
throw new Exception(string.Format("New config content for {0} is empty, please report this bug.", indexer.ID));
}
// create new temporary config file
File.WriteAllText(configFilePathTmp, content);
var fileInfo = new FileInfo(configFilePathTmp);
if (fileInfo.Length == 0)
{
throw new Exception(string.Format("New config file {0} is empty, please report this bug.", configFilePathTmp));
}
if (content.Contains("\x00"))
{
throw new Exception(string.Format("New config content for {0} contains 0x00, please report this bug. Content: {1}", indexer.ID, content));
}
// create backup file
File.Delete(configFilePathBak);
if (File.Exists(configFilePath))
{
// make sure the config directory exists
if (!Directory.Exists(configService.GetIndexerConfigDir()))
Directory.CreateDirectory(configService.GetIndexerConfigDir());
// create new temporary config file
File.WriteAllText(configFilePathTmp, content);
var fileInfo = new FileInfo(configFilePathTmp);
if (fileInfo.Length == 0)
{
throw new Exception(string.Format("New config file {0} is empty, please report this bug.", configFilePathTmp));
}
// create backup file
File.Delete(configFilePathBak);
if (File.Exists(configFilePath))
{
try
{
File.Move(configFilePath, configFilePathBak);
}
catch (IOException ex)
{
logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePath, configFilePathBak, ex.ToString()));
}
}
// replace the actual config file
File.Delete(configFilePath);
try
{
File.Move(configFilePath, configFilePathBak);
File.Move(configFilePathTmp, configFilePath);
}
catch (IOException ex)
{
logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePath, configFilePathBak, ex.ToString()));
logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePathTmp, configFilePath, ex.ToString()));
}
}
// replace the actual config file
File.Delete(configFilePath);
try
{
File.Move(configFilePathTmp, configFilePath);
}
catch (IOException ex)
{
logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePathTmp, configFilePath, ex.ToString()));
}
}
public void SortIndexers()