mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-24 00:00:46 +00:00
d5c6fac3ad
The drill picker's $effect watched `scope` and called `ensureLoaded` on every change. `ensureLoaded` reads `loaded[kind]` synchronously (to decide whether to show a spinner), so the effect ended up subscribed to the very signal it fills. Each fetch result wrote `loaded[kind] = items`; Svelte 5's $state proxy notifies on every property set even when the reference is unchanged from cache, which refired the effect, which called `ensureLoaded` again, which awaited the cached fetch, which wrote `loaded[kind]` again... runaway loop. In `/scripts/edit/...` the picker's lifecycle stabilised quickly enough to mask the loop, but in a session pane (multiple warm sessions, picker kept alive by the surrounding state) the cycle spun freely — 29.8 million iterations in <100 ms during testing, enough to OOM Firefox / kill the Chromium tab. Two changes: - Replace the scope-watching $effect with an explicit `setScope()` helper called from `drill()`, `goUp()`, and `onMount`. Fetch is now a callback reaction to user navigation, never a reactive consequence of one. No closed feedback cycle is possible. - Untrack the `loaded[kind]` read inside `ensureLoaded`. The search $effect (which loads every kind on first keystroke) is still a reactive caller; the untrack stops it from subscribing to the signal `ensureLoaded` fills, so the same loop can't form there.
Windmill frontend
The Windmill frontend written in Svelte 5 + Tailwind CSS
The frontend is under AGPL, see the LICENSE file at the root of this repo