settled() awaits renderSettled() instead of polling the render half - #2214
Conversation
The @ember/test-helpers patch restructures settled(): the render condition is event-driven (await renderSettled(), which resolves at the end of a scheduler flush that left every renderer valid) and only the poll-only conditions (test waiters, pending requests, transitions) re-check in a loop. Quiet is confirmed from a macrotask before resolving: already-queued task sources (worker messages, zero-delay timers) may re-register waiters or dirty state, and a microtask-context observation wins the race against them and settles early -- observed as a real 1-in-4 flake in ember-repl's Compiled() tests until the setTimeout confirm was added. waitUntil imposed the same boundary implicitly by scheduling every check via setTimeout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
Footnotes
|
The tarball moves to all-optimizations+c09efdc8, which replaces the isRenderPending() probe with edge reporting: the renderer notifies when work becomes outstanding and when it completes. The @ember/test-helpers patch turns those edges into an @ember/test-waiters waiter, so rendering settles through the same protocol as every other async source -- isSettled() needs no render clause (its old one is hardwired false to avoid double-counting), and a stuck render is named in test-waiter debug output. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Updated: tarball → Re-verified: builds, 63 lint tasks, full chrome matrix, 7/7 repeat runs on ember-repl (the suite that exposed the macrotask-confirm flake). Upstream draft: emberjs/ember-test-helpers#1574. |
Reworks the settledness patches per review on emberjs/ember-test-helpers#1574: @ember/test-waiters creates a promise per operation in beginAsync, endAsync resolves it and drops it from the pending map, and waitersSettled() composes the promises of whatever is still in flight. @ember/test-helpers' settled() awaits that alongside renderSettled(). The fallback tick stays for waiters that cannot announce completion (pull-only Waiter implementations -- waitersSettled returns a never-resolving promise while one is pending -- plus legacy waiters and request counters). It is 50ms rather than 10 so it loses the race to a frame-paced render tick; at 10ms it decided 30 of 117 iterations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review follow-ups from emberjs/ember-test-waiters#525: each pending operation's promise carries its own resolver, so the map holds nothing but promises and settled() passes them straight to Promise.all -- no array splat, no wrapper objects, no pointless .then. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0fe0ee5
into
NullVoxPopuli:test-ember-source/all-optimizations
Follow-up to #2213: restructures the
@ember/test-helperspatch sosettled()is event-driven for the render condition —await renderSettled()(resolves at the end of a scheduler flush that left every renderer valid), with only the poll-only conditions (waiters, requests, transitions) re-checked in a loop.The one trap, worth recording for the RFC 957 test story: quiet must be confirmed from a macrotask. Already-queued task sources (the repl compiler's worker messages, zero-delay timers) can re-register waiters or dirty state, and an observation made in microtask context wins the race against them and settles early — a real 1-in-4 flake in ember-repl's
Compiled()tests until thesetTimeoutconfirm was added.waitUntilimposed the same boundary implicitly by scheduling every check viasetTimeout.With the confirm in place: ember-repl chrome suite 7/7 clean runs, full chrome matrix green.
🤖 Generated with Claude Code