Skip to content

Commit 4bd3ded

Browse files
sanityclaude
andauthored
fix: use async sleep in WASM execution to prevent blocking executor (#1670)
Co-authored-by: Claude <[email protected]>
1 parent 90c091f commit 4bd3ded

File tree

1 file changed

+42
-18
lines changed

1 file changed

+42
-18
lines changed

crates/core/src/wasm_runtime/contract.rs

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use std::{
2-
thread::{self, JoinHandle},
3-
time::Duration,
4-
};
1+
use std::{thread::JoinHandle, time::Duration};
52

63
use super::{ContractExecError, RuntimeResult};
74
use freenet_stdlib::prelude::{
@@ -308,23 +305,50 @@ fn handle_execution_call(
308305
r: JoinHandle<(Result<i64, wasmer::RuntimeError>, Store)>,
309306
rt: &mut super::Runtime,
310307
) -> Result<i64, Errors> {
311-
// Simple implementation: check every 10ms for up to 5 seconds
312-
for _ in 0..500 {
313-
if r.is_finished() {
314-
break;
308+
// Check if we're in a tokio runtime context
309+
if tokio::runtime::Handle::try_current().is_ok() {
310+
// We're in an async context, use block_in_place to avoid blocking the executor
311+
tokio::task::block_in_place(|| {
312+
tokio::runtime::Handle::current().block_on(async {
313+
// Check every 10ms for up to 5 seconds using async sleep
314+
for _ in 0..500 {
315+
if r.is_finished() {
316+
break;
317+
}
318+
tokio::time::sleep(Duration::from_millis(10)).await;
319+
}
320+
321+
if !r.is_finished() {
322+
return Err(Errors::MaxComputeTimeExceeded);
323+
}
324+
325+
let (r, s) = r
326+
.join()
327+
.map_err(|_| Errors::Other(anyhow::anyhow!("Failed to join thread")))?;
328+
rt.wasm_store = Some(s);
329+
r.map_err(Errors::Wasmer)
330+
})
331+
})
332+
} else {
333+
// We're not in an async context (e.g., in tests), fall back to thread::sleep
334+
// This is still better than the original 1-second sleep
335+
for _ in 0..500 {
336+
if r.is_finished() {
337+
break;
338+
}
339+
std::thread::sleep(Duration::from_millis(10));
315340
}
316-
thread::sleep(Duration::from_millis(10));
317-
}
318341

319-
if !r.is_finished() {
320-
return Err(Errors::MaxComputeTimeExceeded);
321-
}
342+
if !r.is_finished() {
343+
return Err(Errors::MaxComputeTimeExceeded);
344+
}
322345

323-
let (r, s) = r
324-
.join()
325-
.map_err(|_| Errors::Other(anyhow::anyhow!("Failed to join thread")))?;
326-
rt.wasm_store = Some(s);
327-
r.map_err(Errors::Wasmer)
346+
let (r, s) = r
347+
.join()
348+
.map_err(|_| Errors::Other(anyhow::anyhow!("Failed to join thread")))?;
349+
rt.wasm_store = Some(s);
350+
r.map_err(Errors::Wasmer)
351+
}
328352
}
329353

330354
fn match_err(

0 commit comments

Comments
 (0)