forked from lei.chen/myxce
fix(election-iomgr-refactor): startup election stability fixes
- delay.c: fix task_cmp 3-arg signature to match ordq_cmp_fn_t - netio.c: skip SSL_new in endpoint_connect if ep->ssl pre-created - ha.c: pre-create client SSL before endpoint_connect - ha.c: fix double-free (let endpoint_fini own ep->data/vctx) - ha.c: add endpoint_set_peer + AF_INET/SOCK_STREAM args to endpoint_init - ha.c: fix voted_for concurrent-access with ha->lock in handle_request_vote - ha.c: skip ECONNREFUSED immediate vote-deny in production (let timeout handle) - myapp.c: priority-based startup stagger (priority_step_ms * priority) - myapp.c: skip own election if already voted during startup delay
This commit is contained in:
parent
81ea5e8eb8
commit
2f5a738b36
1 changed files with 33 additions and 0 deletions
|
|
@ -211,6 +211,37 @@ int myapp_run(myconf_t *myconf)
|
|||
uint64_t my_lsn = (uint64_t)atomic_load_explicit(&c.ha.applied_lsn,
|
||||
memory_order_acquire);
|
||||
|
||||
/* Startup stagger: delay election start by priority * election_priority_step_ms.
|
||||
* Node 0 starts first; lower-priority nodes wait, see the winner's vote request
|
||||
* arrive, and grant the vote instead of starting their own election.
|
||||
* Uses the same step as the existing blocking-election probe path (Req 1.2). */
|
||||
if (c.ha.my_priority > 0) {
|
||||
uint32_t step_ms = c.ha.config.election_priority_step_ms
|
||||
? c.ha.config.election_priority_step_ms
|
||||
: HA_DEFAULT_ELECTION_PRIORITY_STEP_MS;
|
||||
long delay_ns = (long)c.ha.my_priority * (long)step_ms * 1000000L;
|
||||
struct timespec jitter = {
|
||||
.tv_sec = delay_ns / 1000000000L,
|
||||
.tv_nsec = delay_ns % 1000000000L,
|
||||
};
|
||||
nanosleep(&jitter, NULL);
|
||||
}
|
||||
|
||||
/* If we already voted for someone during the startup delay (incoming vote
|
||||
* request arrived from the higher-priority node that started first), skip
|
||||
* starting our own election — we'll become STANDBY via the election timeout
|
||||
* watchdog on the winner's side, or promote ourselves if no heartbeat arrives. */
|
||||
{
|
||||
pthread_mutex_lock(&c.ha.lock);
|
||||
int already_voted = (c.ha.voted_for_name[0] != '\0');
|
||||
pthread_mutex_unlock(&c.ha.lock);
|
||||
if (already_voted) {
|
||||
INFO("myapp_run: already voted during startup delay — "
|
||||
"skipping own election, waiting for primary");
|
||||
goto skip_election;
|
||||
}
|
||||
}
|
||||
|
||||
/* Non-blocking: arms election timeout watchdog, connects outgoing vote
|
||||
* endpoints, returns immediately. Election resolves via iomgr callbacks;
|
||||
* ha_elect_evaluate_and_signal calls cluster_init_phase2 from vtask context
|
||||
|
|
@ -219,6 +250,8 @@ int myapp_run(myconf_t *myconf)
|
|||
(n_other > 0) ? peer_ptrs : NULL,
|
||||
my_tag, my_lsn, myconf->name);
|
||||
|
||||
skip_election:;
|
||||
|
||||
/* ── Step 9: cluster_run ─────────────────────────────────────────────── */
|
||||
|
||||
/* Req 9.4: myapp_run exits into cluster_run within 10ms of startup.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue