Skip to content

Add timeout support to pyhl::Runtime with cancellable host sleep - #73

Merged
danbugs merged 7 commits into
mainfrom
feat/pyhl-timeout
May 19, 2026
Merged

Add timeout support to pyhl::Runtime with cancellable host sleep#73
danbugs merged 7 commits into
mainfrom
feat/pyhl-timeout

Conversation

@danbugs

@danbugs danbugs commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add run_code_with_timeout() to pyhl::Runtime — an alternative to run_code() that kills guest execution after a caller-specified deadline using Hyperlight's InterruptHandle. run_code() remains unchanged for callers that don't need timeouts.
  • Fix __hl_sleep host function to be cancellable — previously used std::thread::sleep() which blocks the vCPU thread for up to 60s and can't be interrupted by kill() since the vCPU isn't in KVM_RUN. Replaced with a condvar-based sleep (SleepCancel) that wakes immediately when cancelled.
  • Expose SleepCancel and interrupt_handle() on Sandbox so consumers can wire up their own timeout logic
  • Add integration tests for busy spin kill, time.sleep kill, fast code passthrough, and post-timeout recovery
  • Bump version to 0.6.0

danbugs added 4 commits May 19, 2026 21:38
Signed-off-by: danbugs <danilochiarlone@gmail.com>
std::thread::sleep() restarts on EINTR, so interrupt_handle.kill()
could never wake a sleeping guest — the host function blocked for the
full duration (up to 60s cap). Replace with a Condvar-based sleep
that can be woken immediately by SleepCancel::cancel().

Signed-off-by: danbugs <danilochiarlone@gmail.com>
Signed-off-by: danbugs <danilochiarlone@gmail.com>
Signed-off-by: danbugs <danilochiarlone@gmail.com>
Copilot AI review requested due to automatic review settings May 19, 2026 23:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds timeout enforcement for pyhl::Runtime guest execution by introducing a new run_code_with_timeout() API backed by Hyperlight interrupt support, and updates the host-side __hl_sleep implementation to be cancellable so timeouts can interrupt sleeping guests.

Changes:

  • Add Runtime::run_code_with_timeout() that interrupts guest execution after a deadline and attempts to leave the runtime usable for subsequent calls.
  • Replace blocking __hl_sleep with a condition-variable-based sleep that can be cancelled via a shared SleepCancel token; expose Sandbox::interrupt_handle() and Sandbox::sleep_cancel() for external timeout wiring.
  • Add/extend tests for busy-spin kill, time.sleep kill, fast-path execution, and post-timeout recovery; bump host crate version to 0.6.0.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
host/tests/pyhl_runtime.rs Adds integration tests validating timeout behavior and recovery.
host/src/pyhl.rs Introduces run_code_with_timeout() that spawns a watchdog thread to cancel sleep and kill the guest on deadline.
host/src/lib.rs Implements SleepCancel, wires it into __hl_sleep, and exposes cancellation/interrupt handles on Sandbox.
host/Cargo.toml Bumps crate version to 0.6.0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread host/src/lib.rs Outdated
Comment on lines +113 to +114
/// the host function returns and the execution loop can check
/// `is_cancelled()`.
Comment thread host/src/lib.rs Outdated
if *guard {
return;
}
let _ = cvar.wait_timeout(guard, dur);
Comment thread host/src/pyhl.rs
Comment on lines +362 to +375
match call_result {
Ok(()) => {
t.exit_code = self.sandbox.last_exit_code();
Ok(t)
}
Err(_) if timed_out => {
// Restore so the next call starts clean.
self.sandbox.sleep_cancel.reset();
self.sandbox.restore()?;
Err(anyhow!(
"execution timed out after {:.1}s",
timeout.as_secs_f64()
))
}
Signed-off-by: danbugs <danilochiarlone@gmail.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linux Benchmarks

Details
Benchmark suite Current: 10f713e Previous: ca05c5a Ratio
hello_world (median) 20 ms 20 ms 1
pandas (median) 110 ms 110 ms 1
density (per VM) 7 MB 7 MB 1
snapshot (disk) 385 MiB 385 MiB 1

This comment was automatically generated by workflow using github-action-benchmark.

danbugs added 2 commits May 19, 2026 23:13
- Fix doc comment on SleepCancel (no is_cancelled method exists)
- Use wait_timeout_while to handle spurious condvar wakeups
- Reset sleep_cancel unconditionally after timer joins to handle
  race where timer fires as guest call completes

Signed-off-by: danbugs <danilochiarlone@gmail.com>
Signed-off-by: danbugs <danilochiarlone@gmail.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows Benchmarks

Details
Benchmark suite Current: 10f713e Previous: ca05c5a Ratio
hello_world (median) 262 ms 266 ms 0.98
pandas (median) 805 ms 817 ms 0.99
density (per VM) 6 MB 6 MB 1
snapshot (disk) 392 MiB 392 MiB 1

This comment was automatically generated by workflow using github-action-benchmark.

@danbugs
danbugs merged commit d8524a9 into main May 19, 2026
79 checks passed
@danbugs
danbugs deleted the feat/pyhl-timeout branch May 19, 2026 23:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants