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:
Rongsong Shen 2026-05-21 08:30:43 +00:00
parent 2ed7e34e25
commit f3babec5bc
4 changed files with 224 additions and 16 deletions

View file

@ -128,6 +128,9 @@ int handle_upgrade_config(cluster_t *c, endpoint_t *ep, xce_request_t *req);
char *sanitise_cn(const char *src, size_t maxlen);
#ifdef XCE_TESTING
#include <pthread.h>
#include <stdatomic.h>
/*
* load_primary_config_for_test: test-only wrapper that exercises the path
* resolution logic of load_primary_config() without calling FATAL.
@ -135,4 +138,31 @@ char *sanitise_cn(const char *src, size_t maxlen);
* otherwise. Does NOT perform Cap'n Proto decode or SHA-256 computation.
*/
int load_primary_config_for_test(cluster_t *c);
/*
* push_ctx_t: exposed under XCE_TESTING so unit tests can construct
* synthetic push contexts to drive wait_all_with_timeout_for_test().
* In production builds this type is private to config_repl.c.
*/
typedef struct {
endpoint_t *ep;
xce_peerinfo_t *from;
uint64_t new_tag;
const uint8_t *bytes;
size_t blen;
const uint8_t *sha256;
int acked;
int started;
int done;
} push_ctx_t;
/*
* wait_all_with_timeout_for_test: test-only shim exposing the static
* wait_all_with_timeout() helper for unit tests.
* Joins all started push threads within timeout_ms (CLOCK_MONOTONIC).
* Sets *done = 1 when deadline expires. Returns number of acked threads.
*/
int wait_all_with_timeout_for_test(pthread_t *threads, push_ctx_t *ctxs,
int n, uint32_t timeout_ms,
atomic_int *done);
#endif