forked from lei.chen/myxce
Three identical static copies (controller, worker, scheduler) replaced with a single xce_parse_peers() in src/lib/cluster.c. The libxce version is the canonical implementation: stores the logical name from 'name=host:port' syntax so daemons on the same dev host can identify themselves by name rather than IP address.
128 lines
4.2 KiB
C
128 lines
4.2 KiB
C
/* src/include/xce/cluster.h — cluster discovery and reconnect API (P2.5-1)
|
|
*
|
|
* xce_connect_cluster() returns endpoint_t* (cast to void*).
|
|
* The SSL* is accessible as ((endpoint_t*)result)->ssl.
|
|
*/
|
|
#ifndef XCE_CLUSTER_H
|
|
#define XCE_CLUSTER_H
|
|
|
|
#include <stddef.h>
|
|
#include "config.h" /* MAX_HA_CANDIDATES, XCE_MAXHOSTNAME_LEN */
|
|
|
|
/**
|
|
* A single controller candidate.
|
|
* name: logical name from "name=host:port" syntax (empty if omitted).
|
|
* Matching against myconf->name allows multiple controllers on the same
|
|
* dev host to distinguish themselves by name rather than IP address.
|
|
*/
|
|
typedef struct {
|
|
char name[XCE_MAXNAME_LEN];
|
|
char hostname[XCE_MAXHOSTNAME_LEN];
|
|
int port;
|
|
} xce_candidate_t;
|
|
|
|
/**
|
|
* Cluster connection configuration.
|
|
* Populated by each caller (worker/scheduler/apiserver) from --peers and
|
|
* --ca-cert CLI flags. libxce never reads config files.
|
|
*
|
|
* candidates_count must be in [1, MAX_HA_CANDIDATES].
|
|
* A WARN is logged at startup if candidates_count > 3.
|
|
*/
|
|
typedef struct {
|
|
xce_candidate_t candidates[MAX_HA_CANDIDATES];
|
|
int candidates_count;
|
|
char ca_cert_path[4096]; /* path to CA cert for TLS verify */
|
|
char identity[256]; /* "from" name sent to controller */
|
|
char key[256]; /* authentication key */
|
|
} xce_cluster_config_t;
|
|
|
|
/**
|
|
* Reconnect state machine states.
|
|
*/
|
|
typedef enum {
|
|
XCE_RECONNECT_IDLE = 0,
|
|
XCE_RECONNECT_CONNECTING,
|
|
XCE_RECONNECT_BACKOFF,
|
|
XCE_RECONNECT_CONNECTED,
|
|
XCE_RECONNECT_FAILED
|
|
} xce_reconnect_state_t;
|
|
|
|
/**
|
|
* Reconnect context (use xce_reconnect_* functions to operate).
|
|
*/
|
|
typedef struct {
|
|
xce_cluster_config_t* config;
|
|
xce_reconnect_state_t state;
|
|
int attempt;
|
|
int backoff_ms; /* current backoff delay in ms */
|
|
void* endpoint; /* endpoint_t* when CONNECTED */
|
|
} xce_reconnect_ctx_t;
|
|
|
|
/* Redirect follow limit */
|
|
#define XCE_MAX_REDIRECTS 4
|
|
|
|
/* Backoff parameters — initial kept short so tests stay fast */
|
|
#define XCE_RECONNECT_INITIAL_BACKOFF_MS 100
|
|
#define XCE_RECONNECT_MAX_BACKOFF_MS 30000
|
|
#define XCE_RECONNECT_BACKOFF_MULTIPLIER 2
|
|
|
|
/* --- Public API --- */
|
|
|
|
/**
|
|
* xce_cluster_config_validate() — validate a populated xce_cluster_config_t.
|
|
*
|
|
* Returns 0 on success, -EINVAL if:
|
|
* - candidates_count < 1 or > MAX_HA_CANDIDATES
|
|
* - any candidate has empty hostname or port <= 0
|
|
* - ca_cert_path is empty
|
|
* - identity is empty
|
|
*/
|
|
int xce_cluster_config_validate(const xce_cluster_config_t* cfg);
|
|
|
|
/**
|
|
* xce_connect_cluster() — connect to the cluster via candidate list.
|
|
*
|
|
* Iterates candidates in order, attempting a TLS connection to each.
|
|
* Returns endpoint_t* (cast to void*) on success, NULL if all fail.
|
|
*/
|
|
void* xce_connect_cluster(xce_cluster_config_t* cfg);
|
|
|
|
/**
|
|
* xce_reconnect_init() — initialise a reconnect context.
|
|
* Returns 0 on success, -EINVAL on bad arguments.
|
|
*/
|
|
int xce_reconnect_init(xce_reconnect_ctx_t* rctx, xce_cluster_config_t* cfg);
|
|
|
|
/**
|
|
* xce_reconnect_step() — drive one step of the reconnect state machine.
|
|
*
|
|
* Call in a loop until state == XCE_RECONNECT_CONNECTED or FAILED.
|
|
* Sleeps backoff_ms in BACKOFF state (skipped when mock connect is set).
|
|
*
|
|
* Returns 0 to continue, -1 when in terminal state.
|
|
*/
|
|
int xce_reconnect_step(xce_reconnect_ctx_t* rctx);
|
|
|
|
/**
|
|
* xce_reconnect_fini() — release resources held by a reconnect context.
|
|
*/
|
|
void xce_reconnect_fini(xce_reconnect_ctx_t* rctx);
|
|
|
|
/**
|
|
* xce_parse_peers() — parse "--peers name=host:port,..." into cfg->candidates[].
|
|
*
|
|
* Each token may be "name=host:port" or bare "host:port".
|
|
* The name field is stored when present; it allows multiple daemons on the
|
|
* same host to identify themselves by logical name rather than IP address.
|
|
*
|
|
* Returns 0 on success, -1 on empty/NULL input or any parse error.
|
|
*/
|
|
int xce_parse_peers(const char* peers_str, xce_cluster_config_t* cfg);
|
|
|
|
/* Test seam: set to non-NULL to override the real connect (unit tests only) */
|
|
typedef void* (*xce_connect_fn_t)(const char* host, int port,
|
|
const char* ca_cert);
|
|
void xce_cluster_set_connect_fn(xce_connect_fn_t fn);
|
|
|
|
#endif /* XCE_CLUSTER_H */
|