Skip to content

Coalesce reload broadcasts within a quiet window#116

Open
joeljunstrom wants to merge 1 commit into
hotwired:mainfrom
joeljunstrom:debounce-changes
Open

Coalesce reload broadcasts within a quiet window#116
joeljunstrom wants to merge 1 commit into
hotwired:mainfrom
joeljunstrom:debounce-changes

Conversation

@joeljunstrom
Copy link
Copy Markdown

Listen + macOS fsevents commonly fires several writes for a single logical change: esbuild rewriting a bundle plus its sourcemap, editors performing atomic-rename saves, asset pipelines touching siblings. Each write currently flows through Hotwire::Spark::Change#broadcast and reaches the browser as a separate reload frame, producing visible flicker and redundant work.

This behaviour / issue becomes apperant when running Falcon in development due to the increased concurrency.

Routes broadcasts through Hotwire::Spark::Debouncer, a trailing-edge debouncer keyed on [action, canonical_changed_path]. Each event extends a quiet-window deadline; once no event has arrived for debounce_window seconds (default 0.1), pending entries flush as one broadcast per key. The shared state is mutex-guarded; the actual broadcast runs outside the lock so ActionCable latency does not serialize incoming watcher events. Per-block rescue keeps one failing broadcast from dropping siblings in the same flush.

This is part of an ongoing effort to make rails development be as nice as usual when using Falcon / fiber concurrency in local development.

Note that #109 is required in order for Spark to work under falcon

Listen + macOS fsevents commonly fires several writes for a single
logical change: esbuild rewriting a bundle plus its sourcemap, editors
performing atomic-rename saves, asset pipelines touching siblings. Each
write currently flows through `Hotwire::Spark::Change#broadcast` and
reaches the browser as a separate reload frame, producing visible flicker
and redundant work.

This behaviour / issue becomes apperant when running Falcon in development
due to the increased concurrency.

Routes broadcasts through `Hotwire::Spark::Debouncer`, a trailing-edge
debouncer keyed on `[action, canonical_changed_path]`. Each event extends
a quiet-window deadline; once no event has arrived for `debounce_window`
seconds (default 0.1), pending entries flush as one broadcast per key.
The shared state is mutex-guarded; the actual broadcast runs outside the
lock so ActionCable latency does not serialize incoming watcher events.
Per-block rescue keeps one failing broadcast from dropping siblings in
the same flush.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant