From 430bd09ec42ae8294fa7b2210eb6f61c47e58cfa Mon Sep 17 00:00:00 2001 From: Jetsparrow Date: Thu, 2 May 2024 15:57:57 +0300 Subject: [PATCH] Show ratelimit utilization on dashboard --- JetHerald/Contracts/IDb.cs | 2 +- .../Controllers/Ui/DashboardController.cs | 32 +++++++++++++------ JetHerald/Services/LeakyBucket.cs | 8 +++++ JetHerald/Views/Dashboard/Index.cshtml | 18 +++++++---- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/JetHerald/Contracts/IDb.cs b/JetHerald/Contracts/IDb.cs index cff5966..77b0e5e 100644 --- a/JetHerald/Contracts/IDb.cs +++ b/JetHerald/Contracts/IDb.cs @@ -54,7 +54,7 @@ public class User public string Allow { get; set; } public int? MaxTopics { get; set; } - public int? TimeoutMultiplier { get; set; } + public double? TimeoutMultiplier { get; set; } public DateTime CreateTs { get; set; } } diff --git a/JetHerald/Controllers/Ui/DashboardController.cs b/JetHerald/Controllers/Ui/DashboardController.cs index 74fe93f..00a17d6 100644 --- a/JetHerald/Controllers/Ui/DashboardController.cs +++ b/JetHerald/Controllers/Ui/DashboardController.cs @@ -1,5 +1,4 @@ - -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using JetHerald.Services; using JetHerald.Utils; @@ -12,9 +11,11 @@ namespace JetHerald.Controllers.Ui; public class DashboardController : Controller { Db Db { get; } - public DashboardController(Db db) + LeakyBucket LeakyBucket { get; } + public DashboardController(Db db, LeakyBucket leakyBucket) { Db = db; + LeakyBucket = leakyBucket; } [HttpGet, Route("ui/dashboard/")] @@ -25,11 +26,17 @@ public class DashboardController : Controller var user = await ctx.GetUser(login); var topics = await ctx.GetTopicsForUser(user.UserId); var hearts = await ctx.GetHeartsForUser(user.UserId); - var vm = new DashboardViewModel + var vm = new DashboardViewModel(); + foreach (var t in topics.OrderBy(x => x.TopicId)) { - Topics = topics.ToArray(), - Hearts = hearts.Where(h => h.ExpiryTs + TimeSpan.FromDays(90) >= DateTime.UtcNow ).ToLookup(h => h.TopicId) - }; + vm.Topics.Add(new TopicInfo() + { + Topic = t, + Hearts = hearts.Where(h => h.TopicId == t.TopicId).ToList(), + Utilization = (int)Math.Round(LeakyBucket.GetUtilization(t.TopicId) * 100) + }); + } + vm.User = user; return View(vm); } } @@ -58,8 +65,13 @@ public static class DateTimeExt public class DashboardViewModel { - public Topic[] Topics { get; set; } - public ILookup Hearts { get; set; } - + public User User { get; set; } + public List Topics { get; set; } = new(); +} +public class TopicInfo +{ + public Topic Topic { get; set; } + public ICollection Hearts { get; set; } + public int Utilization { get; set; } } \ No newline at end of file diff --git a/JetHerald/Services/LeakyBucket.cs b/JetHerald/Services/LeakyBucket.cs index 99d6fec..7e3199a 100644 --- a/JetHerald/Services/LeakyBucket.cs +++ b/JetHerald/Services/LeakyBucket.cs @@ -12,6 +12,14 @@ public class LeakyBucket this.log = log; } + public double GetUtilization(uint key) + { + var now = DateTime.UtcNow; + var cur = expiryDates.GetValueOrDefault(key, now); + var util = (cur - now).TotalSeconds / config.DebtLimitSeconds; + return Math.Clamp(util, 0, 1); + } + public bool IsTimedOut(uint key) { var now = DateTime.UtcNow; diff --git a/JetHerald/Views/Dashboard/Index.cshtml b/JetHerald/Views/Dashboard/Index.cshtml index e99da28..58171cd 100644 --- a/JetHerald/Views/Dashboard/Index.cshtml +++ b/JetHerald/Views/Dashboard/Index.cshtml @@ -6,16 +6,20 @@
@DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") @TimeZoneInfo.Local.StandardName
- @foreach (var topic in @Model.Topics) + @foreach (var ti in @Model.Topics) {
-

@topic.Name

+

@ti.Topic.Name

- Read: @topic.ReadToken - Write: @topic.WriteToken + Read: @ti.Topic.ReadToken + Write: @ti.Topic.WriteToken
- - @if (@Model.Hearts.Contains(topic.TopicId)) + @if (Model.User.TimeoutMultiplier > 0) + { +
+ @ti.Utilization% +
+ }@if (ti.Hearts.Any()) { @@ -24,7 +28,7 @@ - @foreach (var heart in @Model.Hearts[topic.TopicId]) + @foreach (var heart in @ti.Hearts) {
Last beat Expires on
@heart.Name