From f7fa35c7badc203320e789388544452b62ada6e4 Mon Sep 17 00:00:00 2001 From: benbierens Date: Wed, 11 Sep 2024 14:00:22 +0200 Subject: [PATCH] Implements center service --- AutoClientCenter/AutoClientCenter.csproj.user | 5 +- AutoClientCenter/CidRepo.cs | 76 +++++++++++++++++++ AutoClientCenter/Model.cs | 17 ++--- AutoClientCenter/TaskService.cs | 66 +++++++++++++++- 4 files changed, 150 insertions(+), 14 deletions(-) create mode 100644 AutoClientCenter/CidRepo.cs diff --git a/AutoClientCenter/AutoClientCenter.csproj.user b/AutoClientCenter/AutoClientCenter.csproj.user index dd2d54c..db3a939 100644 --- a/AutoClientCenter/AutoClientCenter.csproj.user +++ b/AutoClientCenter/AutoClientCenter.csproj.user @@ -1,6 +1,9 @@  - Container (Dockerfile) + IIS Express + + + ProjectDebugger \ No newline at end of file diff --git a/AutoClientCenter/CidRepo.cs b/AutoClientCenter/CidRepo.cs new file mode 100644 index 0000000..542c2d4 --- /dev/null +++ b/AutoClientCenter/CidRepo.cs @@ -0,0 +1,76 @@ +namespace AutoClientCenter +{ + public class CidRepo + { + private readonly Random random = new Random(); + private readonly object _lock = new object(); + private readonly List entries = new List(); + + public void Add(string cid, long knownSize) + { + lock (_lock) + { + entries.Add(new CidEntry(cid, knownSize)); + } + } + + public void AddEncoded(string originalCid, string encodedCid) + { + lock (_lock) + { + var entry = entries.SingleOrDefault(e => e.Cid == originalCid); + if (entry == null) return; + + entry.Encoded = encodedCid; + } + } + + public void Assign(AcDownloadStep downloadStep) + { + lock (_lock) + { + while (true) + { + if (!entries.Any()) return; + + var i = random.Next(0, entries.Count); + var entry = entries[i]; + + if (entry.CreatedUtc < (DateTime.UtcNow + TimeSpan.FromHours(18))) + { + entries.RemoveAt(i); + } + else + { + downloadStep.Cid = entry.Cid; + return; + } + } + } + } + + public long? GetSizeKbsForCid(string cid) + { + lock (_lock) + { + var entry = entries.SingleOrDefault(e => e.Cid == cid); + if (entry == null) return null; + return entry.KnownSize; + } + } + } + + public class CidEntry + { + public CidEntry(string cid, long knownSize) + { + Cid = cid; + KnownSize = knownSize; + } + + public string Cid { get; } + public string Encoded { get; set; } = string.Empty; + public long KnownSize { get; } + public DateTime CreatedUtc { get; } = DateTime.UtcNow; + } +} diff --git a/AutoClientCenter/Model.cs b/AutoClientCenter/Model.cs index e37ef61..9f3a8c9 100644 --- a/AutoClientCenter/Model.cs +++ b/AutoClientCenter/Model.cs @@ -2,7 +2,7 @@ { public class AcTasks { - public TimeSpan StartTaskEvery { get; set; } = TimeSpan.FromHours(6); + public int StartTaskEverySeconds { get; set; } public AcTask[] Tasks { get; set; } = Array.Empty(); } @@ -36,28 +36,25 @@ public int Price { get; set; } public int RequiredCollateral { get; set; } public string? ResultPurchaseId { get; set; } - public string? ResultCid { get; set; } + public string? ResultOriginalCid { get; set; } + public string? ResultEncodedCid { get; set; } } public class AcDownloadStep { - public string[] Cids { get; set; } = Array.Empty(); - public long[] ResultDownloadTimeSeconds { get; set; } = Array.Empty(); + public string Cid { get; set; } = string.Empty; + public long ResultDownloadTimeMilliseconds { get; set; } } public class AcStats { - public int NumberOfAutoClients { get; set; } todo send client peerId - public DateTime ServiceStartUtc { get; set; } = DateTime.MinValue; public int TotalUploads { get; set; } public int TotalUploadsFailed { get; set; } public int TotalDownloads { get; set; } - public long[] DownloadTimesSeconds { get; set; } = Array.Empty(); + public long[] DownloadTimesMillisecondsPerKb { get; set; } = Array.Empty(); public int TotalDownloadsFailed { get; set; } public int TotalContractsStarted { get; set; } - public int TotalContractsCompleted { get; set; } - public int TotalContractsExpired { get; set; } - public int TotalContractsFailed { get; set; } + public int TotalContractStartsFailed { get; set; } } } diff --git a/AutoClientCenter/TaskService.cs b/AutoClientCenter/TaskService.cs index 59aa490..fc27a5b 100644 --- a/AutoClientCenter/TaskService.cs +++ b/AutoClientCenter/TaskService.cs @@ -10,6 +10,7 @@ public class TaskService : ITaskService { + private readonly CidRepo cidRepo = new CidRepo(); private readonly List downloadTimes = new List(); private readonly AcStats stats = new AcStats { @@ -18,23 +19,31 @@ private AcTasks tasks = new AcTasks { - StartTaskEvery = TimeSpan.FromHours(8), + StartTaskEverySeconds = Convert.ToInt32(TimeSpan.FromHours(8).TotalSeconds), Tasks = Array.Empty() }; public AcStats GetStats() { + stats.DownloadTimesMillisecondsPerKb = downloadTimes.ToArray(); return stats; } public AcTasks GetTasks() { + foreach (var task in tasks.Tasks) + { + foreach (var step in task.Steps) + { + if (step.DownloadStep != null) cidRepo.Assign(step.DownloadStep); + } + } return tasks; } public void SetConfig(AcTasks newTasks) { - if (newTasks.StartTaskEvery < TimeSpan.FromMinutes(10)) return; + if (newTasks.StartTaskEverySeconds < (10 * 60)) return; foreach (var task in newTasks.Tasks) { if (task.ChanceWeight < 1) return; @@ -50,7 +59,58 @@ public void ProcessResults(AcTaskStep[] taskSteps) { - throw new NotImplementedException(); + foreach (var step in taskSteps) ProcessResults(step); + } + + private void ProcessResults(AcTaskStep step) + { + ProcessResult(step.UploadStep); + ProcessResult(step.StoreStep); + ProcessResult(step.DownloadStep); + } + + private void ProcessResult(AcUploadStep? uploadStep) + { + if (uploadStep == null) return; + + if (string.IsNullOrWhiteSpace(uploadStep.ResultCid)) + { + stats.TotalUploadsFailed++; + } + else + { + stats.TotalUploads++; + cidRepo.Add(uploadStep.ResultCid, uploadStep.SizeInBytes); + } + } + + private void ProcessResult(AcStoreStep? storeStep) + { + if (storeStep == null) return; + + if (string.IsNullOrWhiteSpace(storeStep.ResultOriginalCid) || + string.IsNullOrWhiteSpace(storeStep.ResultEncodedCid) || + string.IsNullOrWhiteSpace(storeStep.ResultPurchaseId)) + { + stats.TotalContractStartsFailed++; + } + else + { + stats.TotalContractsStarted++; + cidRepo.AddEncoded(storeStep.ResultOriginalCid, storeStep.ResultEncodedCid); + } + } + + private void ProcessResult(AcDownloadStep? downloadStep) + { + if (downloadStep == null) return; + + var kbs = cidRepo.GetSizeKbsForCid(downloadStep.Cid); + if (kbs == null) return; + var milliseconds = downloadStep.ResultDownloadTimeMilliseconds; + + var millisecondsPerKb = milliseconds / kbs.Value; + downloadTimes.Add(millisecondsPerKb); } } }