///|
pub(all) struct RequestEvent {
at_ms : Int
cost : Int
key : String
} derive(Eq, Debug)
///|
pub(all) struct Workload {
events : Array[RequestEvent]
} derive(Debug)
///|
pub fn Workload::new() -> Workload {
Workload::{ events: [] }
}
///|
pub fn Workload::burst(count : Int, at_ms : Int) -> Workload {
let workload = Workload::new()
for _ in 0.. Workload {
let workload = Workload::new()
for i in 0.. Int {
self.events.length()
}
///|
pub(all) struct TraceEntry {
at_ms : Int
decision : Decision
} derive(Debug)
///|
pub(all) struct SimulationReport {
mut trace : Array[TraceEntry]
mut allowed_count : Int
mut rejected_count : Int
} derive(Debug)
///|
pub fn SimulationReport::new() -> SimulationReport {
SimulationReport::{ trace: [], allowed_count: 0, rejected_count: 0 }
}
///|
pub fn SimulationReport::record(
self : SimulationReport,
at_ms : Int,
decision : Decision,
) -> Unit {
self.trace.push({ at_ms, decision })
if decision.is_allowed() {
self.allowed_count = self.allowed_count + 1
} else {
self.rejected_count = self.rejected_count + 1
}
}
///|
pub fn SimulationReport::allowed(self : SimulationReport) -> Int {
self.allowed_count
}
///|
pub fn SimulationReport::rejected(self : SimulationReport) -> Int {
self.rejected_count
}
///|
pub fn SimulationReport::total(self : SimulationReport) -> Int {
self.allowed_count + self.rejected_count
}
///|
pub fn SimulationReport::csv(self : SimulationReport) -> String {
let mut out = "time_ms,allowed,retry_after_ms\n"
for entry in self.trace {
out = out +
"\{entry.at_ms},\{entry.decision.is_allowed()},\{entry.decision.retry_after_ms()}\n"
}
out
}
///|
pub(all) struct Simulator {}
///|
pub fn Simulator::run_token_bucket(
limiter : TokenBucket,
workload : Workload,
) -> SimulationReport {
let report = SimulationReport::new()
for event in workload.events {
report.record(event.at_ms, limiter.allow_at(event.at_ms, cost=event.cost))
}
report
}
///|
pub fn Simulator::run_fixed_window(
limiter : FixedWindow,
workload : Workload,
) -> SimulationReport {
let report = SimulationReport::new()
for event in workload.events {
report.record(event.at_ms, limiter.allow_at(event.at_ms, cost=event.cost))
}
report
}