wabbajack/Wabbajack.Server/Services/QuickSync.cs
Timothy Baldridge db3b441d19 #### Version - 2.3.6.1 - 12/31/2020
* When IPS4 (e.g. LL) sites based on CEF fail to validate, they no longer hang the app
* If a IPS4 CEF site throws a 503, or 400 error, retry
* Clean out the cookies during IPS4 CEF downloads so that they don't cause 400 errors
* Limit the number of connections to IPS4 sites to 20 per minute (one per 6 seconds)
* If a site *does* timeout, throw a log of the CEF state into `CEFStates` for easier debugging by the WJ team
* Wrote a new CLI utility to stress test the Verification routines.
* Ignore files that have `\Edit Scripts\Export\` in their path
2020-12-30 23:44:58 -07:00

72 lines
2.2 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Wabbajack.Common;
namespace Wabbajack.Server.Services
{
public class QuickSync
{
private Dictionary<Type, CancellationTokenSource> _syncs = new Dictionary<Type, CancellationTokenSource>();
private Dictionary<Type, IReportingService> _services = new Dictionary<Type, IReportingService>();
private AsyncLock _lock = new AsyncLock();
private ILogger<QuickSync> _logger;
public QuickSync(ILogger<QuickSync> logger)
{
_logger = logger;
}
public async Task<Dictionary<Type, (TimeSpan Delay, TimeSpan LastRunTime, (String, DateTime)[] ActiveWork)>> Report()
{
using var _ = await _lock.WaitAsync();
return _services.ToDictionary(s => s.Key,
s => (s.Value.Delay, DateTime.UtcNow - s.Value.LastEnd, s.Value.ActiveWorkStatus));
}
public async Task Register<T>(T service)
where T : IReportingService
{
using var _ = await _lock.WaitAsync();
_services[service.GetType()] = service;
}
public async Task<CancellationToken> GetToken<T>()
{
using var _ = await _lock.WaitAsync();
if (_syncs.TryGetValue(typeof(T), out var result))
{
return result.Token;
}
var token = new CancellationTokenSource();
_syncs[typeof(T)] = token;
return token.Token;
}
public async Task ResetToken<T>()
{
using var _ = await _lock.WaitAsync();
if (_syncs.TryGetValue(typeof(T), out var ct))
{
ct.Cancel();
}
_syncs[typeof(T)] = new CancellationTokenSource();
}
public async Task Notify<T>()
{
_logger.LogInformation($"Quicksync {typeof(T).Name}");
// Needs debugging
using var _ = await _lock.WaitAsync();
if (_syncs.TryGetValue(typeof(T), out var ct))
{
ct.Cancel();
}
}
}
}