cs-codex-dist-tests/Tools/AutoClient/AutomaticPurchaser.cs

165 lines
4.8 KiB
C#
Raw Normal View History

using CodexOpenApi;
2024-04-01 20:40:03 +02:00
using CodexPlugin;
using Logging;
using Newtonsoft.Json;
2024-04-01 20:40:03 +02:00
using Utils;
namespace AutoClient
{
public class AutomaticPurchaser
2024-04-01 20:40:03 +02:00
{
private readonly ILog log;
2024-10-30 11:09:13 +01:00
private readonly ICodexInstance instance;
private readonly CodexNode codex;
2024-09-12 14:38:15 +02:00
private Task workerTask = Task.CompletedTask;
2024-10-30 11:09:13 +01:00
private App app => instance.App;
2024-04-01 20:40:03 +02:00
2024-10-30 11:09:13 +01:00
public AutomaticPurchaser(ILog log, ICodexInstance instance, CodexNode codex)
2024-04-01 20:40:03 +02:00
{
this.log = log;
2024-10-30 11:09:13 +01:00
this.instance = instance;
2024-04-01 20:40:03 +02:00
this.codex = codex;
}
2024-06-28 08:47:09 +02:00
public void Start()
{
2024-09-12 14:38:15 +02:00
workerTask = Task.Run(Worker);
}
public void Stop()
{
workerTask.Wait();
2024-06-28 08:47:09 +02:00
}
private async Task Worker()
2024-04-01 20:40:03 +02:00
{
2024-09-12 14:38:15 +02:00
log.Log("Worker started.");
while (!app.Cts.Token.IsCancellationRequested)
2024-04-01 20:40:03 +02:00
{
2024-09-12 14:38:15 +02:00
try
{
var pid = await StartNewPurchase();
await WaitTillFinished(pid);
await DownloadForeignCid();
}
catch (Exception ex)
{
log.Error("Worker failed with: " + ex);
await Task.Delay(TimeSpan.FromHours(6));
}
}
}
private async Task DownloadForeignCid()
{
2024-10-30 11:09:13 +01:00
var cid = app.CidRepo.GetForeignCid(instance.NodeId);
2024-09-12 14:38:15 +02:00
if (cid == null) return;
2024-10-30 11:09:13 +01:00
2024-09-12 14:38:15 +02:00
var size = app.CidRepo.GetSizeForCid(cid);
if (size == null) return;
2024-09-12 14:38:15 +02:00
2024-10-30 11:09:13 +01:00
var filename = Guid.NewGuid().ToString().ToLowerInvariant();
await codex.DownloadCid(filename, cid, size);
DeleteFile(filename);
2024-04-01 20:40:03 +02:00
}
2024-06-28 08:47:09 +02:00
private async Task<string> StartNewPurchase()
2024-04-01 20:40:03 +02:00
{
var file = await CreateFile();
2024-10-21 11:10:39 +02:00
try
{
2024-10-30 11:09:13 +01:00
var cid = await codex.UploadFile(file);
return await codex.RequestStorage(cid);
2024-10-21 11:10:39 +02:00
}
finally
{
DeleteFile(file);
}
2024-04-01 20:40:03 +02:00
}
private async Task<string> CreateFile()
2024-04-01 20:40:03 +02:00
{
2024-09-12 14:38:15 +02:00
return await app.Generator.Generate();
2024-04-01 20:40:03 +02:00
}
2024-10-21 11:10:39 +02:00
private void DeleteFile(string file)
{
try
{
File.Delete(file);
}
catch (Exception exc)
{
app.Log.Error($"Failed to delete file '{file}': {exc}");
}
}
2024-06-28 08:47:09 +02:00
private async Task WaitTillFinished(string pid)
2024-04-01 20:40:03 +02:00
{
try
{
var emptyResponseTolerance = 10;
2024-09-12 14:38:15 +02:00
while (!app.Cts.Token.IsCancellationRequested)
2024-04-01 20:40:03 +02:00
{
2024-10-30 11:09:13 +01:00
var purchase = await codex.GetStoragePurchase(pid);
2024-09-12 14:38:15 +02:00
if (purchase == null)
2024-04-01 20:40:03 +02:00
{
2024-09-12 14:38:15 +02:00
await FixedShortDelay();
emptyResponseTolerance--;
if (emptyResponseTolerance == 0)
{
2024-06-28 08:47:09 +02:00
log.Log("Received 10 empty responses. Stop tracking this purchase.");
await ExpiryTimeDelay();
return;
}
2024-09-12 14:38:15 +02:00
continue;
}
2024-10-30 11:09:13 +01:00
if (purchase.IsCancelled)
{
2024-09-12 14:38:15 +02:00
app.Performance.StorageContractCancelled();
return;
}
2024-10-30 11:09:13 +01:00
if (purchase.IsError)
2024-09-12 14:38:15 +02:00
{
app.Performance.StorageContractErrored(purchase.Error);
return;
}
2024-10-30 11:09:13 +01:00
if (purchase.IsFinished)
2024-09-12 14:38:15 +02:00
{
app.Performance.StorageContractFinished();
return;
}
2024-10-30 11:09:13 +01:00
if (purchase.IsStarted)
2024-09-12 14:38:15 +02:00
{
app.Performance.StorageContractStarted();
await FixedDurationDelay();
2024-04-01 20:40:03 +02:00
}
2024-06-28 08:47:09 +02:00
await FixedShortDelay();
2024-04-01 20:40:03 +02:00
}
}
catch (Exception ex)
{
log.Log($"Wait failed with exception: {ex}. Assume contract will expire: Wait expiry time.");
await ExpiryTimeDelay();
2024-04-01 20:40:03 +02:00
}
}
private async Task FixedDurationDelay()
{
2024-09-12 14:38:15 +02:00
await Task.Delay(app.Config.ContractDurationMinutes * 60 * 1000, app.Cts.Token);
}
private async Task ExpiryTimeDelay()
2024-04-01 20:40:03 +02:00
{
2024-09-12 14:38:15 +02:00
await Task.Delay(app.Config.ContractExpiryMinutes * 60 * 1000, app.Cts.Token);
2024-04-01 20:40:03 +02:00
}
private async Task FixedShortDelay()
2024-04-01 20:40:03 +02:00
{
2024-09-12 14:38:15 +02:00
await Task.Delay(15 * 1000, app.Cts.Token);
2024-04-01 20:40:03 +02:00
}
}
}