Skip to content

Fix atomic sync gates - #1020

Open
jnunemaker wants to merge 16 commits into
mainfrom
atomic-sync-gates
Open

Fix atomic sync gates#1020
jnunemaker wants to merge 16 commits into
mainfrom
atomic-sync-gates

Conversation

@jnunemaker

Copy link
Copy Markdown
Collaborator

Fixes thundering-herd syncs caused by unsynchronized check-then-act gates in the poll and interval synchronizers. The poll adapter now coordinates in-flight local updates, retries after failed synchronization, and resets sync state after forks; the interval synchronizer now claims each elapsed interval atomically. This keeps concurrent request threads from issuing duplicate remote reads and overlapping local writes for the same sync window. Validated with bundle exec rspec spec/flipper/adapters/poll_spec.rb spec/flipper/adapters/sync/interval_synchronizer_spec.rb and bundle exec rspec spec/flipper/adapters, which passed with the existing 2 sqlite pending examples.

@jnunemaker
jnunemaker marked this pull request as ready for review July 8, 2026 18:42
jnunemaker and others added 13 commits July 21, 2026 16:47
The bare rescue in synced_adapter only cleared @syncing for StandardError,
so a non-StandardError from the Synchronizer (Interrupt, SignalException,
etc.) would leave @syncing true permanently, deadlocking all subsequent
reads waiting on @sync_condition. Use an ensure with a synced flag so state
is always cleared, bumping @last_synced_at only on success. Mirrors the
ensure-based cleanup already in IntervalSynchronizer#call.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Threads that lose the sync claim now return the local adapter immediately
instead of waiting on the syncing thread. The data they serve is at most one
poll interval stale, which is the contract already, and strictly better than
the pre-fix behavior where they read partially applied mid-sync state.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Use PID-scoped atomic gate state so forked child threads converge on one
claim, keep Poll losers nonblocking with a coherent pre-sync snapshot,
and cover contention and failure recovery paths.
Retain stable Ruby mutexes across fork, reset only process-owned state under lock, and preserve nonblocking interval and trusted-snapshot behavior. Add real-fork regression coverage for Memory, Poller, Poll, and IntervalSynchronizer.
@jnunemaker jnunemaker changed the title [codex] Fix atomic sync gates Fix atomic sync gates Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant