Improving check command responsiveness

This commit is contained in:
Ben 2025-06-10 12:37:28 +02:00
parent 0c74acab11
commit c5ff76db69
No known key found for this signature in database
GPG Key ID: 0F16E812E736C24B
6 changed files with 74 additions and 34 deletions

View File

@ -1,16 +1,20 @@
using Newtonsoft.Json;
using Logging;
using Newtonsoft.Json;
using Utils;
namespace BiblioTech.CodexChecking
{
public class CheckRepo
{
private const string modelFilename = "model.json";
private readonly ILog log;
private readonly Configuration config;
private readonly object _lock = new object();
private CheckRepoModel? model = null;
public CheckRepo(Configuration config)
public CheckRepo(ILog log, Configuration config)
{
this.log = log;
this.config = config;
}
@ -18,20 +22,32 @@ namespace BiblioTech.CodexChecking
{
lock (_lock)
{
if (model == null) LoadModel();
var existing = model.Reports.SingleOrDefault(r => r.UserId == userId);
if (existing == null)
var sw = System.Diagnostics.Stopwatch.StartNew();
try
{
var newEntry = new CheckReport
if (model == null) LoadModel();
var existing = model.Reports.SingleOrDefault(r => r.UserId == userId);
if (existing == null)
{
UserId = userId,
};
model.Reports.Add(newEntry);
SaveChanges();
return newEntry;
var newEntry = new CheckReport
{
UserId = userId,
};
model.Reports.Add(newEntry);
SaveChanges();
return newEntry;
}
return existing;
}
finally
{
var elapsed = sw.Elapsed;
if (elapsed > TimeSpan.FromMilliseconds(500))
{
log.Log($"Warning {nameof(GetOrCreate)} took {Time.FormatDuration(elapsed)}");
}
}
return existing;
}
}

View File

@ -43,7 +43,7 @@ namespace BiblioTech.CodexChecking
repo.SaveChanges();
}
var cid = UploadData(check.UniqueData);
var cid = await UploadData(check.UniqueData);
await handler.GiveCidToUser(cid);
}
@ -87,7 +87,7 @@ namespace BiblioTech.CodexChecking
return;
}
var manifest = GetManifest(receivedCid);
var manifest = await GetManifest(receivedCid);
if (manifest == null)
{
await handler.CouldNotDownloadCid();
@ -96,7 +96,7 @@ namespace BiblioTech.CodexChecking
if (IsManifestLengthCompatible(handler, check, manifest))
{
if (IsContentCorrect(handler, check, receivedCid))
if (await IsContentCorrect(handler, check, receivedCid))
{
await CheckNowCompleted(handler, check, userId, "UploadCheck");
return;
@ -120,7 +120,7 @@ namespace BiblioTech.CodexChecking
check.CompletedUtc < expiry;
}
private string UploadData(string uniqueData)
private async Task<string> UploadData(string uniqueData)
{
var filePath = Path.Combine(config.ChecksDataPath, Guid.NewGuid().ToString());
@ -129,7 +129,7 @@ namespace BiblioTech.CodexChecking
File.WriteAllText(filePath, uniqueData);
var file = new TrackedFile(log, filePath, "checkData");
return codexWrapper.OnCodex(node =>
return await codexWrapper.OnCodex(node =>
{
return node.UploadFile(file).Id;
});
@ -145,11 +145,11 @@ namespace BiblioTech.CodexChecking
}
}
private Manifest? GetManifest(string receivedCid)
private async Task<Manifest?> GetManifest(string receivedCid)
{
try
{
return codexWrapper.OnCodex(node =>
return await codexWrapper.OnCodex(node =>
{
return node.DownloadManifestOnly(new ContentId(receivedCid)).Manifest;
});
@ -172,11 +172,11 @@ namespace BiblioTech.CodexChecking
manifestLength < (dataLength + 1);
}
private bool IsContentCorrect(ICheckResponseHandler handler, TransferCheck check, string receivedCid)
private async Task<bool> IsContentCorrect(ICheckResponseHandler handler, TransferCheck check, string receivedCid)
{
try
{
var content = codexWrapper.OnCodex(node =>
var content = await codexWrapper.OnCodex(node =>
{
var file = node.DownloadContent(new ContentId(receivedCid));
if (file == null) return string.Empty;

View File

@ -23,20 +23,26 @@ namespace BiblioTech.CodexChecking
factory = new CodexNodeFactory(log, httpFactory, dataDir: config.DataPath);
}
public void OnCodex(Action<ICodexNode> action)
public async Task OnCodex(Action<ICodexNode> action)
{
lock (codexLock)
await Task.Run(() =>
{
action(Get());
}
lock (codexLock)
{
action(Get());
}
});
}
public T OnCodex<T>(Func<ICodexNode, T> func)
public async Task<T> OnCodex<T>(Func<ICodexNode, T> func)
{
lock (codexLock)
return await Task<T>.Run(() =>
{
return func(Get());
}
lock (codexLock)
{
return func(Get());
}
});
}
private ICodexNode Get()
@ -76,10 +82,28 @@ namespace BiblioTech.CodexChecking
var tokens = config.CodexEndpointAuth.Split(':');
if (tokens.Length != 2) throw new Exception("Expected '<username>:<password>' in CodexEndpointAuth parameter.");
return new HttpFactory(log, onClientCreated: client =>
return new HttpFactory(log, new SnappyTimeSet(), onClientCreated: client =>
{
client.SetBasicAuthentication(tokens[0], tokens[1]);
});
}
public class SnappyTimeSet : IWebCallTimeSet
{
public TimeSpan HttpCallRetryDelay()
{
return TimeSpan.FromSeconds(1.0);
}
public TimeSpan HttpCallTimeout()
{
return TimeSpan.FromSeconds(3.0);
}
public TimeSpan HttpRetryTimeout()
{
return TimeSpan.FromSeconds(12.0);
}
}
}
}

View File

@ -18,7 +18,7 @@ namespace BiblioTech.Commands
}
public override string Name => "checkdownload";
public override string StartingMessage => RandomBusyMessage.Get();
public override string StartingMessage => "Connecting to the testnet... Please be patient... " + RandomBusyMessage.Get();
public override string Description => "Checks the download connectivity of your Codex node.";
public override CommandOption[] Options => [contentOption];

View File

@ -18,7 +18,7 @@ namespace BiblioTech.Commands
}
public override string Name => "checkupload";
public override string StartingMessage => RandomBusyMessage.Get();
public override string StartingMessage => "Connecting to the testnet... Please be patient... " + RandomBusyMessage.Get();
public override string Description => "Checks the upload connectivity of your Codex node.";
public override CommandOption[] Options => [cidOption];

View File

@ -88,7 +88,7 @@ namespace BiblioTech
client = new DiscordSocketClient();
client.Log += ClientLog;
var checkRepo = new CheckRepo(Config);
var checkRepo = new CheckRepo(Log, Config);
var codexWrapper = new CodexWrapper(Log, Config);
var checker = new CodexTwoWayChecker(Log, Config, checkRepo, codexWrapper);
var notifyCommand = new NotifyCommand();