Rework resource setting storage

This commit is contained in:
Timothy Baldridge 2021-11-09 22:15:13 -07:00
parent 5fc070e5d3
commit f7d81a6f4e
3 changed files with 45 additions and 15 deletions

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
@ -10,9 +11,9 @@ namespace Wabbajack.RateLimiter;
public class Resource<T> : IResource<T>
{
private readonly Channel<PendingReport> _channel;
private readonly SemaphoreSlim _semaphore;
private readonly ConcurrentDictionary<ulong, Job<T>> _tasks;
private Channel<PendingReport> _channel;
private SemaphoreSlim _semaphore;
private ConcurrentDictionary<ulong, Job<T>> _tasks;
private ulong _nextId;
private long _totalUsed;
@ -22,14 +23,29 @@ public class Resource<T> : IResource<T>
Name = humanName ?? "<unknown>";
MaxTasks = maxTasks ?? Environment.ProcessorCount;
MaxThroughput = maxThroughput;
_semaphore = new SemaphoreSlim(MaxTasks);
_channel = Channel.CreateBounded<PendingReport>(10);
_tasks = new ConcurrentDictionary<ulong, Job<T>>();
var tsk = StartTask(CancellationToken.None);
}
public Resource(string humanName, Func<Task<(int MaxTasks, long MaxThroughput)>> settingGetter)
{
_tasks = new ConcurrentDictionary<ulong, Job<T>>();
Task.Run(async () =>
{
var (maxTasks, maxThroughput) = await settingGetter();
MaxTasks = maxTasks;
MaxThroughput = maxThroughput;
_semaphore = new SemaphoreSlim(MaxTasks);
_channel = Channel.CreateBounded<PendingReport>(10);
await StartTask(CancellationToken.None);
});
}
public int MaxTasks { get; set; }
public long MaxThroughput { get; set; }
public string Name { get; }

View File

@ -18,12 +18,15 @@ public class ResourceSettingsManager
_manager = manager;
}
private SemaphoreSlim _lock = new(1);
public async Task<ResourceSetting> GetSettings(string name)
{
Monitor.Enter(_manager);
await _lock.WaitAsync();
try
{
_settings ??= await _manager.Load<Dictionary<string, ResourceSetting>>("resource-settings");
_settings ??= await _manager.Load<Dictionary<string, ResourceSetting>>("resource_settings");
if (_settings.TryGetValue(name, out var found)) return found;
@ -35,13 +38,13 @@ public class ResourceSettingsManager
_settings.Add(name, newSetting);
await _manager.Save("resource-settings", _settings);
await _manager.Save("resource_settings", _settings);
return _settings[name];
}
finally
{
Monitor.Exit(_manager);
_lock.Release();
}
}

View File

@ -55,17 +55,28 @@ public static class ServiceExtensions
: new BinaryPatchCache(KnownFolders.EntryPoint.Combine("patchCache.sqlite")));
service.AddSingleton(new ParallelOptions {MaxDegreeOfParallelism = Environment.ProcessorCount});
Func<Task<(int MaxTasks, long MaxThroughput)>> GetSettings(IServiceProvider provider, string name)
{
return async () =>
{
var s = await provider.GetService<ResourceSettingsManager>()!.GetSettings(name);
return ((int) s.MaxTasks, s.MaxThroughput);
};
}
service.AddAllSingleton<IResource, IResource<DownloadDispatcher>>(s =>
new Resource<DownloadDispatcher>("Downloads", 12));
service.AddAllSingleton<IResource, IResource<HttpClient>>(s => new Resource<HttpClient>("Web Requests", 12));
service.AddAllSingleton<IResource, IResource<Context>>(s => new Resource<Context>("VFS", 12));
new Resource<DownloadDispatcher>("Downloads", GetSettings(s, "Downloads")));
service.AddAllSingleton<IResource, IResource<HttpClient>>(s => new Resource<HttpClient>("Web Requests", GetSettings(s, "Web Requests")));
service.AddAllSingleton<IResource, IResource<Context>>(s => new Resource<Context>("VFS", GetSettings(s, "VFS")));
service.AddAllSingleton<IResource, IResource<FileHashCache>>(s =>
new Resource<FileHashCache>("File Hashing", 12));
new Resource<FileHashCache>("File Hashing", GetSettings(s, "FileHashing")));
service.AddAllSingleton<IResource, IResource<FileExtractor.FileExtractor>>(s =>
new Resource<FileExtractor.FileExtractor>("File Extractor", 12));
new Resource<FileExtractor.FileExtractor>("File Extractor", GetSettings(s, "FileExtractor")));
service.AddAllSingleton<IResource, IResource<ACompiler>>(s =>
new Resource<ACompiler>("Compiler", 12));
new Resource<ACompiler>("Compiler", GetSettings(s, "Compiler")));
service.AddSingleton<LoggingRateLimiterReporter>();