feat(usage): split throttle thresholds per bucket, add draggable gauge markers
This commit is contained in:
@@ -149,11 +149,61 @@ public sealed class UsageSnapshotBuilderTests : IDisposable
|
||||
var repo = new AppSettingsRepository(ctx);
|
||||
var settings = await repo.GetAsync();
|
||||
settings.MaxParallelExecutions = maxParallel;
|
||||
settings.UsageThrottleSoftPct = softPct;
|
||||
settings.UsageThrottleHardPct = hardPct;
|
||||
settings.UsageThrottleFiveHourSoftPct = softPct;
|
||||
settings.UsageThrottleFiveHourHardPct = hardPct;
|
||||
settings.UsageThrottleSevenDaySoftPct = softPct;
|
||||
settings.UsageThrottleSevenDayHardPct = hardPct;
|
||||
await repo.UpdateAsync(settings);
|
||||
}
|
||||
|
||||
private async Task SetPerBucketThrottleAsync(
|
||||
int maxParallel, int fiveSoft, int fiveHard, int sevenSoft, int sevenHard)
|
||||
{
|
||||
using var ctx = _db.CreateContext();
|
||||
var repo = new AppSettingsRepository(ctx);
|
||||
var settings = await repo.GetAsync();
|
||||
settings.MaxParallelExecutions = maxParallel;
|
||||
settings.UsageThrottleFiveHourSoftPct = fiveSoft;
|
||||
settings.UsageThrottleFiveHourHardPct = fiveHard;
|
||||
settings.UsageThrottleSevenDaySoftPct = sevenSoft;
|
||||
settings.UsageThrottleSevenDayHardPct = sevenHard;
|
||||
await repo.UpdateAsync(settings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Per_bucket_throttle_stages_are_reported_for_the_gauges()
|
||||
{
|
||||
await SetThresholdsAsync(80, 90);
|
||||
await SetPerBucketThrottleAsync(maxParallel: 3, fiveSoft: 45, fiveHard: 60, sevenSoft: 70, sevenHard: 85);
|
||||
|
||||
var state = new UsageState();
|
||||
state.ReportSuccess(new UsageSnapshot(
|
||||
new UsageBucket(10, null), new UsageBucket(10, null), Array.Empty<UsageLimitRow>(), DateTime.UtcNow));
|
||||
|
||||
var dto = await CreateBuilder(state, new UsageGateDecision(false, null)).BuildAsync();
|
||||
|
||||
Assert.Equal(45, dto.ThrottleFiveHourSoftPct);
|
||||
Assert.Equal(60, dto.ThrottleFiveHourHardPct);
|
||||
Assert.Equal(70, dto.ThrottleSevenDaySoftPct);
|
||||
Assert.Equal(85, dto.ThrottleSevenDayHardPct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Per_bucket_stages_apply_independently_to_effective_slots()
|
||||
{
|
||||
await SetThresholdsAsync(80, 90);
|
||||
// Both buckets sit at 60%: past the 5h soft stage (45) but below every 7d stage (70/85).
|
||||
await SetPerBucketThrottleAsync(maxParallel: 3, fiveSoft: 45, fiveHard: 90, sevenSoft: 70, sevenHard: 85);
|
||||
|
||||
var state = new UsageState();
|
||||
state.ReportSuccess(new UsageSnapshot(
|
||||
new UsageBucket(60, null), new UsageBucket(60, null), Array.Empty<UsageLimitRow>(), DateTime.UtcNow));
|
||||
|
||||
var dto = await CreateBuilder(state, new UsageGateDecision(false, null)).BuildAsync();
|
||||
|
||||
Assert.Equal(2, dto.EffectiveSlots);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Throttled_slots_and_decisive_bucket_reported()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user