use std::time::{Duration, Instant};
const PREFILL_WORK_TOKENS_PER_SEC: f64 = 64.0;
const PREFILL_WORK_MIN: Duration = Duration::from_secs(60);
const PREFILL_WORK_MAX: Duration = Duration::from_secs(30 * 60);
pub(super) fn cache_operation_deadline(
admission_timeout: Duration,
prompt_tokens: usize,
) -> Instant {
let prompt_budget = Duration::from_secs_f64(prompt_tokens as f64 / PREFILL_WORK_TOKENS_PER_SEC)
.clamp(PREFILL_WORK_MIN, PREFILL_WORK_MAX);
let now = Instant::now();
now.checked_add(admission_timeout.saturating_add(prompt_budget))
.unwrap_or_else(|| now + PREFILL_WORK_MAX)
}
#[cfg(test)]
mod tests {
use super::{PREFILL_WORK_MAX, cache_operation_deadline};
use std::time::{Duration, Instant};
#[test]
fn cache_operation_deadline_scales_with_prompt_and_stays_bounded() {
let admission = Duration::from_secs(60);
let small = cache_operation_deadline(admission, 128);
assert!(small.duration_since(Instant::now()) >= Duration::from_secs(119));
let large = cache_operation_deadline(admission, 60_000);
assert!(
large.duration_since(Instant::now()) >= Duration::from_secs(60 + 60),
"60k-token prompt must get more than the bare admission timeout"
);
let huge = cache_operation_deadline(admission, usize::MAX);
assert!(
huge.duration_since(Instant::now())
<= admission + PREFILL_WORK_MAX + Duration::from_secs(5),
"deadline must remain bounded"
);
}
}