Show ratelimit utilization on dashboard

This commit is contained in:
Jetsparrow 2024-05-02 15:57:57 +03:00
parent 51d05b8104
commit 430bd09ec4
4 changed files with 42 additions and 18 deletions

View File

@ -54,7 +54,7 @@ public class User
public string Allow { get; set; } public string Allow { get; set; }
public int? MaxTopics { get; set; } public int? MaxTopics { get; set; }
public int? TimeoutMultiplier { get; set; } public double? TimeoutMultiplier { get; set; }
public DateTime CreateTs { get; set; } public DateTime CreateTs { get; set; }
} }

View File

@ -1,5 +1,4 @@
 using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
using JetHerald.Services; using JetHerald.Services;
using JetHerald.Utils; using JetHerald.Utils;
@ -12,9 +11,11 @@ namespace JetHerald.Controllers.Ui;
public class DashboardController : Controller public class DashboardController : Controller
{ {
Db Db { get; } Db Db { get; }
public DashboardController(Db db) LeakyBucket LeakyBucket { get; }
public DashboardController(Db db, LeakyBucket leakyBucket)
{ {
Db = db; Db = db;
LeakyBucket = leakyBucket;
} }
[HttpGet, Route("ui/dashboard/")] [HttpGet, Route("ui/dashboard/")]
@ -25,11 +26,17 @@ public class DashboardController : Controller
var user = await ctx.GetUser(login); var user = await ctx.GetUser(login);
var topics = await ctx.GetTopicsForUser(user.UserId); var topics = await ctx.GetTopicsForUser(user.UserId);
var hearts = await ctx.GetHeartsForUser(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(), vm.Topics.Add(new TopicInfo()
Hearts = hearts.Where(h => h.ExpiryTs + TimeSpan.FromDays(90) >= DateTime.UtcNow ).ToLookup(h => h.TopicId) {
}; 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); return View(vm);
} }
} }
@ -58,8 +65,13 @@ public static class DateTimeExt
public class DashboardViewModel public class DashboardViewModel
{ {
public Topic[] Topics { get; set; } public User User { get; set; }
public ILookup<uint, Heart> Hearts { get; set; } public List<TopicInfo> Topics { get; set; } = new();
}
public class TopicInfo
{
public Topic Topic { get; set; }
public ICollection<Heart> Hearts { get; set; }
public int Utilization { get; set; }
} }

View File

@ -12,6 +12,14 @@ public class LeakyBucket
this.log = log; 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) public bool IsTimedOut(uint key)
{ {
var now = DateTime.UtcNow; var now = DateTime.UtcNow;

View File

@ -6,16 +6,20 @@
<div class="clock">@DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") @TimeZoneInfo.Local.StandardName</div> <div class="clock">@DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") @TimeZoneInfo.Local.StandardName</div>
</div> </div>
<div class="topics-list"> <div class="topics-list">
@foreach (var topic in @Model.Topics) @foreach (var ti in @Model.Topics)
{ {
<div class="topic-info"> <div class="topic-info">
<h3>@topic.Name</h3> <h3>@ti.Topic.Name</h3>
<div> <div>
<span class="token-descr"> Read: </span><span class="token-field">@topic.ReadToken</span> <span class="token-descr"> Read: </span><span class="token-field">@ti.Topic.ReadToken</span>
<span class="token-descr">Write: </span><span class="token-field">@topic.WriteToken</span> <span class="token-descr">Write: </span><span class="token-field">@ti.Topic.WriteToken</span>
</div> </div>
@if (Model.User.TimeoutMultiplier > 0)
@if (@Model.Hearts.Contains(topic.TopicId)) {
<div>
<meter min="0" high="50" max="100" value="@ti.Utilization">@ti.Utilization%</meter>
</div>
}@if (ti.Hearts.Any())
{ {
<table class="hearts-table"> <table class="hearts-table">
<tr> <tr>
@ -24,7 +28,7 @@
<th>Last beat</th> <th>Last beat</th>
<th>Expires on</th> <th>Expires on</th>
</tr> </tr>
@foreach (var heart in @Model.Hearts[topic.TopicId]) @foreach (var heart in @ti.Hearts)
{ {
<tr> <tr>
<td>@heart.Name</td> <td>@heart.Name</td>