///|
pub(all) struct BudgetForecast {
report : BudgetReport
lookback_minutes : Int
bad_per_hour_x100 : Int
minutes_to_exhaustion : Int
state : String
} derive(Eq, Debug)
///|
pub fn forecast_budget(
target : SloTarget,
window : RequestWindow,
lookback_minutes : Int,
) -> BudgetForecast {
let report = evaluate_budget(target, window)
let lookback = if lookback_minutes > 0 {
lookback_minutes
} else {
window.minutes
}
let bad_per_hour_x100 = if lookback <= 0 {
0
} else {
report.actual_bad * 60 * 100 / lookback
}
let minutes_to_exhaustion = if report.remaining_bad <= 0 {
0
} else if bad_per_hour_x100 <= 0 {
2147483647
} else {
report.remaining_bad * 60 * 100 / bad_per_hour_x100
}
{
report,
lookback_minutes: lookback,
bad_per_hour_x100,
minutes_to_exhaustion,
state: if report.remaining_bad < 0 {
"exhausted"
} else if minutes_to_exhaustion <= 60 {
"critical"
} else {
"tracking"
},
}
}
///|
pub fn BudgetForecast::exhausted(self : BudgetForecast) -> Bool {
self.state == "exhausted"
}