feat: add scheduler::flush() to replace sleep(Duration::ZERO) in tests#4044
feat: add scheduler::flush() to replace sleep(Duration::ZERO) in tests#4044Madoshakalaka merged 3 commits intomasterfrom
Conversation
|
Visit the preview URL for this PR (updated for commit 9279fb5): https://yew-rs-api--pr4044-test-runner-lite-7n47edyn.web.app (expires Thu, 12 Mar 2026 16:13:33 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 |
Benchmark - coreYew MasterPull Request |
Size ComparisonDetails
✅ None of the examples has changed their size significantly. |
Benchmark - SSRYew MasterDetails
Pull RequestDetails
|
a210fdb to
22fc46c
Compare
Add a public `scheduler::flush()` async function that properly waits for all pending scheduler work to complete. This replaces the 61 uses of `sleep(Duration::ZERO).await` across 12 test files with a semantically clear, centralized call that can be improved in the future. Consecutive zero-duration sleeps (used in hydration tests as a conservative measure) are collapsed to a single flush(), since one macrotask yield is sufficient to drain all cascading microtask work.
22fc46c to
6f2cd3e
Compare
| sleep(Duration::ZERO).await; | ||
| sleep(Duration::ZERO).await; | ||
| sleep(Duration::ZERO).await; | ||
| scheduler::flush().await; |
There was a problem hiding this comment.
real proof of flush correctness
|
properly gated too (no binary size diff) It will help with #4033 |
packages/yew/src/scheduler.rs
Outdated
| /// Future returned by [`flush()`] that resolves when the scheduler finishes all pending work. | ||
| /// | ||
| /// On each poll, this future eagerly drains any currently-queued scheduler work via | ||
| /// `start_now()`. It then checks whether the scheduler has been re-scheduled (via | ||
| /// `IS_SCHEDULED`), which indicates that spawned microtasks (e.g., from Suspense futures | ||
| /// resolving) will trigger more work. If so, it re-registers its waker and yields, allowing | ||
| /// those microtasks to execute before the next poll. This loop continues until the scheduler | ||
| /// is truly idle. | ||
| #[cfg(all( | ||
| any(test, feature = "test"), | ||
| target_arch = "wasm32", | ||
| not(target_os = "wasi"), | ||
| not(feature = "not_browser_env") | ||
| ))] | ||
| #[derive(Debug)] | ||
| pub struct Flush { | ||
| _priv: (), | ||
| } | ||
|
|
||
| #[cfg(all( | ||
| any(test, feature = "test"), | ||
| target_arch = "wasm32", | ||
| not(target_os = "wasi"), | ||
| not(feature = "not_browser_env") | ||
| ))] | ||
| impl std::future::Future for Flush { | ||
| type Output = (); | ||
|
|
||
| fn poll( | ||
| self: std::pin::Pin<&mut Self>, | ||
| cx: &mut std::task::Context<'_>, | ||
| ) -> std::task::Poll<()> { | ||
| start_now(); | ||
|
|
||
| if arch::is_scheduled() { | ||
| flush_wakers::register(cx.waker().clone()); | ||
| std::task::Poll::Pending | ||
| } else { | ||
| std::task::Poll::Ready(()) | ||
| } | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
This future could be simply implemented with std::future::poll_fn.
| target_arch = "wasm32", | ||
| not(target_os = "wasi"), | ||
| not(feature = "not_browser_env") | ||
| ))] |
There was a problem hiding this comment.
Could these three lines be moved into the function for a uniform signature (and documentation) across targets.
There was a problem hiding this comment.
Done, both targets now use pub async fn flush()
bc3f126 to
9279fb5
Compare
Description
a small part of #2679
Checklist