mirror of
https://github.com/lexmount/moli.git
synced 2026-10-30 16:07:24 +00:00
fix(runtime): preserve typed fetch timeout for late inner results
This commit is contained in:
@@ -137,9 +137,11 @@ impl FetchDeadline {
|
||||
where
|
||||
F: Future<Output = Result<T>>,
|
||||
{
|
||||
// Tokio polls the inner future first. A result queued after the deadline
|
||||
// must not replace the typed timeout when both are ready on the next poll.
|
||||
match tokio::time::timeout_at(self.at, future).await {
|
||||
Ok(result) => result,
|
||||
Err(_) => Err(anyhow::Error::new(FetchReadinessTimeout::new(
|
||||
Ok(result) if tokio::time::Instant::now() < self.at => result,
|
||||
_ => Err(anyhow::Error::new(FetchReadinessTimeout::new(
|
||||
self.timeout,
|
||||
phase,
|
||||
))),
|
||||
@@ -193,6 +195,24 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn expired_deadline_wins_over_a_ready_inner_result() -> Result<()> {
|
||||
for result in [Ok(()), Err(anyhow::anyhow!("inner operation timed out"))] {
|
||||
let deadline = FetchDeadline::new(Duration::ZERO)?;
|
||||
let error = deadline
|
||||
.wait(
|
||||
FetchTimeoutPhase::WaitingForScript,
|
||||
std::future::ready(result),
|
||||
)
|
||||
.await
|
||||
.unwrap_err();
|
||||
let timeout = error.downcast_ref::<FetchReadinessTimeout>().unwrap();
|
||||
assert_eq!(timeout.timeout(), Duration::ZERO);
|
||||
assert_eq!(timeout.phase(), FetchTimeoutPhase::WaitingForScript);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn impossible_deadline_range_is_an_anyhow_error() {
|
||||
let error = FetchDeadline::new(Duration::MAX).unwrap_err();
|
||||
|
||||
Reference in New Issue
Block a user