feat(ha-config-bootstrap): extract cluster_open_listener, reorder startup before election (task 3.2)

This commit is contained in:
Rongsong Shen 2026-05-28 05:03:50 +00:00
parent 0a881804a0
commit 6272fc8eb2
4 changed files with 94 additions and 28 deletions

View file

@ -641,6 +641,59 @@ int cluster_init_phase1(cluster_t* c)
/* cbuf used by cluster_run() to signal restart/stop */
cbuf_init(&(c->wbuf), 1, sizeof(int));
/* Sentinel: -1 means iomgr not yet initialised.
* cluster_init_phase2() uses this to skip re-init when myapp_run()
* has already called iomgr_init() before election. */
c->iomgr.epoll_fd = -1;
/* Sentinel: fd=-1 means the listener socket is not yet open.
* cluster_open_listener() uses this for its idempotency guard. */
c->ep.fd = -1;
return 0;
}
int cluster_open_listener(cluster_t* c)
{
int rc;
if (c == NULL)
return -EINVAL;
/* Idempotent: if the listener socket is already open, do nothing. */
if (c->ep.fd >= 0)
return 0;
/* Determine listen port: prefer per-candidate port from --peers list,
* fall back to cluster_config->port if config is already loaded. */
uint32_t my_port = 0;
{
const xce_cluster_config_t* pcfg = &c->myconf->peers_cfg;
for (int j = 0; j < pcfg->candidates_count; j++) {
const char* key = pcfg->candidates[j].name[0]
? pcfg->candidates[j].name
: pcfg->candidates[j].hostname;
if (strncmp(key, c->myconf->name, XCE_MAXNAME_LEN - 1) == 0) {
my_port = pcfg->candidates[j].port;
break;
}
}
}
if (my_port == 0) {
if (c->myconf->cluster_config != NULL) {
my_port = (uint32_t)c->myconf->cluster_config->port;
} else {
ERROR("cluster_open_listener: no port in --peers and cluster_config "
"not yet loaded; specify port in --peers list");
return -EINVAL;
}
}
rc = endpoint_init(&(c->ep), AF_INET, SOCK_STREAM, (int)my_port, 5);
if (rc < 0)
return rc;
endpoint_set_peer(&(c->ep), c->myhost);
return 0;
}
@ -705,39 +758,28 @@ int cluster_init_phase2(cluster_t* c)
(zarray_item_killer_t)resval_obj_killer);
c->workermgr = makeInstance(&xkvmgr_type, &workermgr_params);
c->qmgr = makeInstance(&xkvmgr_type, &qmgr_params);
iomgr_init(&(c->iomgr));
iomgr_set_ssl_ctx(&(c->iomgr), ssl_ctx);
/* iomgr and vtaskmgr are initialised in cluster_open_listener() /
* myapp_run() before election. Guard against re-initialisation when
* cluster_init() (legacy wrapper) calls cluster_init_phase2() directly. */
if (c->iomgr.epoll_fd < 0) {
iomgr_init(&(c->iomgr));
iomgr_set_ssl_ctx(&(c->iomgr), ssl_ctx);
} else {
/* ssl_ctx may have been set before phase1; always refresh it here. */
iomgr_set_ssl_ctx(&(c->iomgr), ssl_ctx);
}
xstring_table_init(c->myconf->cluster_config->xstrings->nhash_slots);
job_obj_init(5381, 5381);
zarray_init(&(c->endpoints), 16, endpoint_killer);
/* Determine listen port: prefer per-candidate port from --peers list,
* fall back to cluster_config->port */
uint32_t my_port = 0;
{
const xce_cluster_config_t* pcfg = &c->myconf->peers_cfg;
for (int j = 0; j < pcfg->candidates_count; j++) {
const char* key = pcfg->candidates[j].name[0]
? pcfg->candidates[j].name
: pcfg->candidates[j].hostname;
if (strncmp(key, c->myconf->name, XCE_MAXNAME_LEN - 1) == 0) {
my_port = pcfg->candidates[j].port;
break;
}
}
}
if (my_port == 0)
my_port = (uint32_t)c->myconf->cluster_config->port;
rc = endpoint_init(&(c->ep), AF_INET, SOCK_STREAM, (int)my_port, 5);
if (rc < 0) {
/* Open the listener socket (idempotent — skipped if already opened before
* election via cluster_open_listener()). */
rc = cluster_open_listener(c);
if (rc < 0)
return rc;
}
endpoint_set_peer(&(c->ep), c->myhost);
for (i = 0; i < c->ncontrollers; i++) {
controller_init(&(c->controllers[i]), c);
@ -746,8 +788,11 @@ int cluster_init_phase2(cluster_t* c)
zarray_init(&(c->configs), 64, NULL /* FIXME */);
/* Req 4.3: use --vcpus CLI value; fall back to built-in default (8).
* The cluster config 'vcpus' field has been removed (Req 4.4 deprecation). */
{
* The cluster config 'vcpus' field has been removed (Req 4.4 deprecation).
* vtaskmgr_init() is guarded by n_vcpus==0: myapp_run() calls it before
* election; the guard here covers the legacy cluster_init() path where
* it has not been called yet. */
if (c->vtaskmgr.n_vcpus == 0) {
int nvcpus = (c->myconf->vcpus > 0) ? c->myconf->vcpus : 8;
vtaskmgr_init(&(c->vtaskmgr), nvcpus);
}