feat(config-repl): implement wait_all_with_timeout() for push fan-out
Replaces blocking pthread_join() per thread with a CLOCK_MONOTONIC deadline + 5ms poll loop. CONF_PUSH_TIMEOUT_MS (500ms) now enforced. Matches design §6.3 aggregate timeout guarantee. - Add done field to push_ctx_t; push_thread sets it on exit - Add static wait_all_with_timeout() before push_config_to_standbys() - Wire push_config_to_standbys() to use wait_all_with_timeout() - Add #include <stdatomic.h> to config_repl.c - Guard push_ctx_t local typedef with #ifndef XCE_TESTING - Expose push_ctx_t and wait_all_with_timeout_for_test() in header under XCE_TESTING for unit test access - Add test_wait_all_with_timeout_slow_threads (timeout fires, acked=0) - Add test_wait_all_with_timeout_fast_threads (all complete, acked=3) - Update design doc §6.3 with actual implementation signature and 5ms poll interval note
This commit is contained in:
parent
2ed7e34e25
commit
f3babec5bc
4 changed files with 224 additions and 16 deletions
|
|
@ -850,19 +850,22 @@ that the config may not have reached any standby.
|
|||
for (int i = 0; i < n_standbys; i++)
|
||||
pthread_create(&push_threads[i], NULL, push_config_thread, &push_ctx[i]);
|
||||
|
||||
/* Single aggregate wait — 500ms total, not 500ms per standby.
|
||||
* Uses CONF_PUSH_TIMEOUT_MS (default 500ms), distinct from probe_connect_timeout_ms
|
||||
* used in election probing (§9.2). */
|
||||
wait_all_with_timeout(push_threads, n_standbys, CONF_PUSH_TIMEOUT_MS);
|
||||
|
||||
/* Cancel still-running threads via atomic stop flag (same pattern as probe_thread) */
|
||||
atomic_store(&push_done, 1);
|
||||
for (int i = 0; i < n_standbys; i++)
|
||||
pthread_join(push_threads[i], NULL);
|
||||
/* Single aggregate wait — 500ms total, not 500ms per standby. */
|
||||
atomic_int push_done;
|
||||
atomic_init(&push_done, 0);
|
||||
int acked = wait_all_with_timeout(threads, ctxs, n,
|
||||
CONF_PUSH_TIMEOUT_MS, &push_done);
|
||||
|
||||
LOG("Config pushed to %d/%d standbys; restarting", acked, n_standbys);
|
||||
```
|
||||
|
||||
Implemented signature (in `config_repl.c`):
|
||||
```c
|
||||
static int wait_all_with_timeout(pthread_t *threads, push_ctx_t *ctxs,
|
||||
int n, uint32_t timeout_ms, atomic_int *done);
|
||||
```
|
||||
Uses a 5ms poll loop against `ctx->done` flags until the CLOCK_MONOTONIC deadline, then sets `*done = 1` and joins all started threads. The `done` flag allows thread implementations that check it to exit early; `push_thread` sets `ctx->done = 1` on natural completion, so joins return immediately for threads that finished within the timeout.
|
||||
|
||||
Offline standbys recover on their next reconnect via the normal pull mechanism
|
||||
(§5.2) — their `conf/current` will have the old tag, the new primary will detect
|
||||
the mismatch and push via `OP_replConfig`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue