Skip to content

[1/3] Make throttle and batch-size access race-free - #472

Closed
driv3r wants to merge 1 commit into
mainfrom
throttle-recovery/01-safe-inputs
Closed

driv3r wants to merge 1 commit into
mainfrom
throttle-recovery/01-safe-inputs

Conversation

@driv3r

@driv3r driv3r commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Refs #471

Stack: 1/3. Base: main. Next: #473. Merge order: PR 1 → PR 2 → PR 3.

Scope

Makes the shared inputs that gradual copy recovery (#471) composes with race-free. Throttle, polling, batch-size and wire behavior are unchanged.

  • Config.Update stores UpdatableConfig.DataIterationBatchSize atomically. CursorConfig.GetBatchSize and the iterative verifier's reverify batching load it atomically.
  • ControlServer.HandleConfigGet encodes a freshly loaded UpdatableConfig snapshot. The /api/config fields are unchanged.
  • A mutex guards LagThrottler.lag, which Run writes and Throttled reads.

TestConcurrentBatchSizeUpdates drives the real /api/config GET/POST handlers through httptest. Concurrent POSTs alternate between 104 and 200 while CursorConfig.GetBatchSize is read concurrently. The test checks that every observed value is 104 or 200, that a per-table override stays 80, and that a final update to 104 shows up in both the HTTP snapshot and the cursor getter.

Checks run (MySQL 8.0.32 from docker-compose_8.0.yml)

  • MYSQL_VERSION=8.0 go test -race ./test/go -run 'TestConcurrentBatchSizeUpdates|TestThrottlerThrottlesAndUnthrottles|TestThrottlerMultipleServerIDs|TestDataIterator/TestBatchSizeUpdate' -count=1 -p=1: pass.
  • With config.go, cursor.go and control_server.go reverted, TestConcurrentBatchSizeUpdates fails with 3 DATA RACE reports under -race.
  • MYSQL_VERSION=8.0 go test . ./test/go -count=1 -p=1: pass.
  • Real-Ferry smoke (throwaway program; concurrency 1, base 200, no pause, no recovery config): held the first 200-row batch, sent POST /api/config {"DataIterationBatchSize":104}, and GET /api/config returned {"DataIterationBatchSize":104}. The next batch had 104 rows, and all 1000 ordered source and target rows were identical.

Live DataIterationBatchSize updates from the control server raced with
cursor and iterative-verifier reads, and LagThrottler.lag raced between
its update loop and Throttled callers.

- Config.Update stores the live batch size atomically; CursorConfig.GetBatchSize
  and the iterative verifier load it atomically.
- HandleConfigGet encodes a freshly loaded UpdatableConfig snapshot.
- LagThrottler guards lag with a mutex.

Behavior, wire format and polling are unchanged.

Refs #471
@driv3r

driv3r commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

wont do right now

@driv3r driv3r closed this Nov 3, 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