feat: add config replication fields to myconf_t, cluster_t, ha_state_t, persist_t; create byteorder.h

This commit is contained in:
Rongsong Shen 2026-05-13 14:15:30 +00:00
parent 78adf3f843
commit 2c375cf476
5 changed files with 96 additions and 1 deletions

View file

@ -18,16 +18,45 @@
* The watchdog (P1-3) will include netio.h directly where it needs endpoint_t.
*/
#include <fcntl.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
#include "config.h" /* XCE_MAXNAME_LEN, MAX_STANDBYS, etc. */
#include "zarray.h"
/* Forward declaration — avoids circular include with cluster_def.h */
typedef struct cluster_s cluster_t;
/* ── Inline PRNG for election jitter ───────────────────────── */
static inline uint64_t xorshift64_next(uint64_t *state)
{
uint64_t x = *state;
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
*state = x;
return x;
}
static inline void ha_seed_jitter(uint64_t *seed, int my_priority)
{
int fd = open("/dev/urandom", O_RDONLY);
if (fd >= 0) {
if (read(fd, seed, 8) == 8 && *seed != 0) { close(fd); return; }
close(fd);
}
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
*seed = (uint64_t)ts.tv_nsec
^ ((uint64_t)my_priority << 56)
^ ((uint64_t)getpid() << 16);
}
/* ── Role enum ─────────────────────────────────────────────── */
typedef enum {
CTRL_PRIMARY = 0,
@ -42,6 +71,8 @@ typedef enum {
#define HA_DEFAULT_ELECTION_TIMEOUT_MS 2000
#define HA_DEFAULT_PROBE_CONNECT_TIMEOUT_MS 500
#define HA_DEFAULT_MAX_PROMOTION_RETRIES 5
#define HA_DEFAULT_ELECTION_JITTER_MAX_MS 200
#define HA_DEFAULT_ELECTION_PRIORITY_STEP_MS 500
typedef struct {
uint32_t heartbeat_interval_ms; /* Primary heartbeat send interval (min 2000 ms) */
@ -49,8 +80,22 @@ typedef struct {
uint32_t election_timeout_ms; /* Election probe shared deadline (min 500 ms) */
uint32_t probe_connect_timeout_ms; /* Per-probe TCP connect timeout */
uint32_t max_promotion_retries; /* Max consecutive failed promotion attempts */
uint32_t election_jitter_max_ms; /* random jitter added to election timeout (default 200) */
uint32_t election_priority_step_ms; /* extra ms per priority level (default 500) */
} ha_config_t;
/* Forward declaration for election probe context */
struct xce_candidate_s;
typedef struct {
struct xce_candidate_s *candidate; /* peer to probe */
void *ssl_ctx; /* SSL_CTX* (void* to avoid openssl header) */
uint32_t timeout_ms;
atomic_int *election_done;
int got_ack;
pthread_t thread;
} probe_ctx_t;
/* ── HA runtime state (embedded in cluster_t as `ha_state_t ha` in P1-5) ── */
typedef struct {
_Atomic uint64_t term; /* Election term — fencing token */
@ -71,6 +116,9 @@ typedef struct {
/* Watchdog thread — started in P1-3 */
_Atomic int watchdog_stop;
pthread_t watchdog_thread;
void *ssl_ctx; /* SSL_CTX* cast; avoids pulling openssl headers here */
uint64_t jitter_seed; /* xorshift64 PRNG state for election jitter */
zarray_t *standby_endpoints; /* connected standby controller endpoints for config push */
} ha_state_t;
/* ── Public API ────────────────────────────────────────────── */
@ -166,6 +214,11 @@ int ha_should_redirect(const ha_state_t *ha);
*/
int ha_no_primary_known(const ha_state_t *ha);
int ha_is_primary(const ha_state_t *ha);
void ha_check_priority_stepdown(ha_state_t *ha, int sender_priority, uint64_t sender_term);
void start_heartbeat_listener(cluster_t *c);
void stop_heartbeat_listener(cluster_t *c);
/* ── P3-6: Test-only failover shim ────────────────────────────── */
#ifdef XCE_TESTING