Skip to content

Commit 89c09ac

Browse files
committed
fix: add missing cleanup and timeouts
Signed-off-by: Bailey Hayes <behayes2@gmail.com>
1 parent 3d4955b commit 89c09ac

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

crates/wash-runtime/src/engine/workload.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use std::{
55
ops::{Deref, DerefMut},
66
path::PathBuf,
77
sync::Arc,
8+
time::Duration,
89
};
910

1011
use anyhow::{Context as _, bail, ensure};
11-
use tokio::{sync::RwLock, task::JoinHandle};
12+
use tokio::{sync::RwLock, task::JoinHandle, time::timeout};
1213
use tracing::{debug, info, trace, warn};
1314
use wasmtime::component::{
1415
Component, Instance, InstancePre, Linker, ResourceAny, ResourceType, Val, types::ComponentItem,
@@ -674,14 +675,22 @@ impl ResolvedWorkload {
674675

675676
let mut results_buf =
676677
vec![Val::Bool(false); results.len()];
677-
// TODO(IMPORTANT): Enforce a timeout on this call
678-
// to prevent hanging indefinitely.
679-
func.call_async(
680-
&mut store,
681-
&params_buf,
682-
&mut results_buf,
678+
679+
// Enforce a timeout on this call to prevent hanging indefinitely
680+
const CALL_TIMEOUT: Duration =
681+
Duration::from_secs(30);
682+
timeout(
683+
CALL_TIMEOUT,
684+
func.call_async(
685+
&mut store,
686+
&params_buf,
687+
&mut results_buf,
688+
),
683689
)
684690
.await
691+
.context(
692+
"function call timed out after 30 seconds",
693+
)?
685694
.context("failed to call function")?;
686695

687696
trace!(

src/main.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,24 @@ async fn main() {
249249
}
250250

251251
// Since some interactive commands may hide the cursor, we need to ensure it is shown again on exit
252+
// Clone the host Arc to move into the ctrl-c handler
253+
let host_for_handler = ctx.host().clone();
252254
if let Err(e) = ctrlc::set_handler(move || {
253255
let term = dialoguer::console::Term::stdout();
254256
let _ = term.show_cursor();
255-
// TODO(IMPORTANT): If the runtime is executing a component here, we need to stop it.
257+
258+
// Stop all running workloads and the host runtime
259+
// Note: Signal handlers run outside the normal runtime context,
260+
// so block_on is safe here and won't deadlock
261+
if let Ok(handle) = tokio::runtime::Handle::try_current() {
262+
let host = host_for_handler.clone();
263+
if let Err(e) = handle.block_on(async move { host.stop().await }) {
264+
eprintln!("Error stopping host: {e:?}");
265+
}
266+
}
267+
268+
// Exit with standard SIGINT code (128 + 2)
269+
std::process::exit(130);
256270
}) {
257271
warn!(err = ?e, "failed to set ctrl_c handler, interactive prompts may not restore cursor visibility");
258272
}

0 commit comments

Comments
 (0)