Skip to content

多模冗余 XMR API

多模冗余(X-Modular Redundancy)投票层:把「N 份冗余 + 投票选举」收敛为按组名 join 的位置透明角色。两个变体(Full / Tiny)均支持,头文件 onepath_xmr.h。可靠性模型与能力边界见 多模冗余(XMR)

数据类型

onepath_xmr_t

c
typedef struct onepath_xmr *onepath_xmr_t;

XMR 长驻角色句柄(worker / 投票消费端 / 存储副本),不透明。由 onepath_xmr_compute / onepath_xmr_consume / onepath_xmr_store 创建,由 onepath_xmr_close 销毁。

onepath_xmr_sink_t

c
typedef struct onepath_xmr_sink onepath_xmr_sink_t;

worker 计算结果输出汇,不透明。由 XMR 在调用 worker 计算函数时传入,worker 通过 onepath_xmr_emit() 向其发射结果。

onepath_xmr_result_t

选举结果,作为投票消费端 / 读端选举回调的参数。data 指向选举出的值,仅在回调期间有效

c
typedef struct {
    const char *group;     /* 组名                                         */
    uint64_t    seq;       /* 计算: 任务序号; 存储: 0                       */
    const char *sign;      /* 存储: 数据键; 计算: NULL                      */
    const void *data;      /* 选举出的值                                    */
    size_t      data_len;  /* 值长度 (字节)                                 */
    int         votes;     /* 与胜者一致的票数                              */
    int         n;         /* 参与投票的候选数 (已剔除 CRC 失败者)          */
    int         agreed;    /* 1 = 达到多数 (可靠); 0 = 无定论 (DMR 检出分歧) */
} onepath_xmr_result_t;
字段类型含义
groupconst char *组名
sequint64_t计算场景:任务序号;存储场景:0
signconst char *存储场景:数据键(组内相对 sign);计算场景:NULL
dataconst void *选举出的值(仅回调期间有效)
data_lensize_t值长度(字节)
votesint与胜者一致的票数
nint参与投票的候选数(已剔除 CRC 失败者)
agreedint1 = 达到多数(结果可靠);0 = 无定论(DMR 检出分歧)

agreed=0 时结果不应被当作可靠结果(见 多模冗余(XMR))。

onepath_xmr_result_cb

c
typedef void (*onepath_xmr_result_cb)(void *ud, const onepath_xmr_result_t *r);

选举结果回调。onepath_xmr_consume 在每次选举出计算结果时调用,onepath_xmr_get 对每个选举出的键调用一次。

  • 参数
    • ud — 用户上下文(创建时透传)
    • r — 选举结果,仅回调期间有效

onepath_xmr_compute_fn

c
typedef void (*onepath_xmr_compute_fn)(void *ud, const void *in, size_t in_len,
                                       onepath_xmr_sink_t *sink);

worker 计算函数:对一条任务输入产出一份结果,经 onepath_xmr_emit() 发射到 sink

  • 参数
    • ud — 用户上下文(onepath_xmr_compute 创建时透传)
    • in — 任务输入指针
    • in_len — 任务输入长度(字节)
    • sink — 结果输出汇,传给 onepath_xmr_emit()

onepath_xmr_candidate_t

一个投票候选,供自定义投票函数使用。

c
typedef struct {
    const void *data;   /* 候选值指针 */
    size_t      len;    /* 候选值长度 */
} onepath_xmr_candidate_t;
字段类型含义
dataconst void *候选值指针
lensize_t候选值长度

onepath_xmr_vote_fn

c
typedef int (*onepath_xmr_vote_fn)(void *ud, const onepath_xmr_candidate_t *c,
                                   size_t n, size_t *winner);

自定义投票函数。从 n 个候选中选出胜者,写入胜者索引到 *winner 并返回 ONEPATH_OK;无定论时返回非 0。传 NULL 表示使用默认精确多数投票。

  • 参数
    • ud — 用户上下文(vote_ud 透传)
    • c — 候选数组
    • n — 候选数量
    • winner — 输出胜者索引
  • 返回值ONEPATH_OK 选出胜者,非 0 无定论

选项

onepath_xmr_opts_t

c
typedef struct {
    int                 expected;
    int                 quorum;
    uint32_t            window_ms;
    onepath_xmr_vote_fn vote_fn;
    void               *vote_ud;
    int                 integrity;
    const char         *republish_sign;
    const char         *node_id;
    const char         *encoding;
} onepath_xmr_opts_t;

XMR 选项。传 NULL 给各入口即全部取默认值。

字段类型含义默认
expectedint钉死 N;0 = 存活感知自动计数0(auto)
quorumint需多少票一致;0 = 多数 ⌊N/2⌋+10
window_msuint32_t一次选举的收齐超时(毫秒);0 = 默认 20000(2000 ms)
vote_fnonepath_xmr_vote_fn自定义投票函数;NULL = 精确多数NULL
vote_udvoid *透传给 vote_fn 的上下文NULL
integrityint端到端校验模式:ONEPATH_XMR_CRC32 / ONEPATH_XMR_NONEONEPATH_XMR_CRC32
republish_signconst char *消费端非空则把选举结果转发到此 sign 供下游扇出;NULL = 仅回调NULL
node_idconst char *覆盖自动服务 ID(sid)编号;NULL = 用本节点 sidNULL
encodingconst char *发布编码;NULL = 默认NULL

同组一致性

同一组内各角色的 integrity 设置应一致(默认全开即一致)。

ONEPATH_XMR_OPTS_DEFAULT

c
#define ONEPATH_XMR_OPTS_DEFAULT \
    { 0, 0, 0, NULL, NULL, ONEPATH_XMR_CRC32, NULL, NULL, NULL }

onepath_xmr_opts_t 的默认初始化宏,按字段顺序展开为:expected=0quorum=0window_ms=0vote_fn=NULLvote_ud=NULLintegrity=ONEPATH_XMR_CRC32republish_sign=NULLnode_id=NULLencoding=NULL。等价于传 NULL 给各入口。

计算 NMR

onepath_xmr_submit

c
int onepath_xmr_submit(onepath_session_t s, const char *group,
                       const void *data, size_t len);

生产者:向 XMR 组提交一条计算任务。任务被组内全部 worker 订阅,每次调用自增内部任务序号。

  • 参数
    • s — 会话句柄
    • group — 组名
    • data — 任务数据指针
    • len — 任务数据长度(字节)
  • 返回值ONEPATH_OK 成功,ONEPATH_ERR_PARAM 参数无效

onepath_xmr_compute

c
int onepath_xmr_compute(onepath_session_t s, onepath_xmr_t *out,
                        const char *group,
                        onepath_xmr_compute_fn fn, void *ud,
                        const onepath_xmr_opts_t *opts);

worker:加入 XMR 组,订阅任务并发布计算结果。可在任意机器上 spawn 任意多个;自动声明存活感知供投票端感知 N。

  • 参数
    • s — 会话句柄
    • out — 成功时写入角色句柄
    • group — 组名
    • fn — 计算函数(见 onepath_xmr_compute_fn
    • ud — 透传给 fn 的上下文
    • opts — 选项,传 NULL 使用全默认
  • 返回值ONEPATH_OK 成功,ONEPATH_ERR_PARAM 参数无效,ONEPATH_ERR 声明失败
  • 注意:使用完毕后须调用 onepath_xmr_close() 销毁

onepath_xmr_consume

c
int onepath_xmr_consume(onepath_session_t s, onepath_xmr_t *out,
                        const char *group,
                        onepath_xmr_result_cb cb, void *ud,
                        const onepath_xmr_opts_t *opts);

投票消费端(= voter + consumer 合并):订阅组内全部 worker 结果,按任务序号分组,CRC 校验剔除被翻转者,达到多数(或 window_ms 超时)即投票并回调选举结果。这是「边缘投票」:在消费侧本地完成,不依赖单独的投票节点(无单点)。opts->republish_sign 非空时同时把选举结果转发到该 sign 供下游扇出。

  • 参数
    • s — 会话句柄
    • out — 成功时写入角色句柄
    • group — 组名
    • cb — 选举结果回调(见 onepath_xmr_result_cb
    • ud — 透传给 cb 的上下文
    • opts — 选项,传 NULL 使用全默认
  • 返回值ONEPATH_OK 成功,ONEPATH_ERR_PARAM 参数无效,ONEPATH_ERR 声明失败
  • 注意:使用完毕后须调用 onepath_xmr_close() 销毁

onepath_xmr_emit

c
int onepath_xmr_emit(onepath_xmr_sink_t *sink,
                     const void *out, size_t len);

在 worker 计算函数内产出一份结果,发射到传入的 sink

  • 参数
    • sink — 传入计算函数的输出汇
    • out — 结果数据指针
    • len — 结果数据长度(字节)
  • 返回值ONEPATH_OK 成功,ONEPATH_ERR_PARAM 参数无效

存储 NMR

onepath_xmr_store

c
int onepath_xmr_store(onepath_session_t s, onepath_xmr_t *out,
                      const char *group,
                      const onepath_xmr_opts_t *opts);

存储副本:加入 XMR 组,订阅写入并存储,应答读取查询。可在任意机器 spawn 任意多个组成冗余副本。

  • 参数
    • s — 会话句柄
    • out — 成功时写入角色句柄
    • group — 组名
    • opts — 选项,传 NULL 使用全默认
  • 返回值ONEPATH_OK 成功,ONEPATH_ERR_PARAM 参数无效,ONEPATH_ERR 声明失败
  • 注意:使用完毕后须调用 onepath_xmr_close() 销毁

onepath_xmr_put

c
int onepath_xmr_put(onepath_session_t s, const char *group,
                    const char *sign, const void *data, size_t len);

写入:向 XMR 组写一个键值,广播到全部副本。

  • 参数
    • s — 会话句柄
    • group — 组名
    • sign — 数据键(组内相对 sign,如 "sensor/temp"
    • data — 值数据指针
    • len — 值长度(字节)
  • 返回值ONEPATH_OK 成功,ONEPATH_ERR_PARAM 参数无效

onepath_xmr_get

c
int onepath_xmr_get(onepath_session_t s, const char *group,
                    const char *sign,
                    const onepath_xmr_opts_t *opts,
                    onepath_xmr_result_cb cb, void *ud);

读取并选举:查询全部副本,按键投票选出可靠值(读端边缘投票)。CRC 校验剔除被翻转的回复后投票,对每个选举出的键回调一次 cb

  • 参数
    • s — 会话句柄
    • group — 组名
    • sign — 组内相对 sign(通配或具体键)
    • opts — 选项,传 NULL 使用全默认
    • cb — 每个选举键的结果回调(见 onepath_xmr_result_cb
    • ud — 透传给 cb 的上下文
  • 返回值:选举出的键数(>=0),或负的错误码

通用

onepath_xmr_close

c
void onepath_xmr_close(onepath_xmr_t h);

关闭并销毁 XMR 角色句柄(worker / 投票消费端 / 存储副本通用)。

  • 参数h — 角色句柄,可为 NULL

常量

完整性校验模式,用于 onepath_xmr_opts_t.integrity

常量含义
ONEPATH_XMR_NONE0不加端到端校验
ONEPATH_XMR_CRC321每份结果带 CRC32(默认)

内存与所有权

  • 句柄创建 / 销毁配对onepath_xmr_compute / onepath_xmr_consume / onepath_xmr_store 创建的角色句柄,均须由 onepath_xmr_close() 销毁;onepath_xmr_close(NULL) 安全。
  • 结果生命周期onepath_xmr_result_t.data 及回调内指针仅在回调期间有效,如需保留请自行拷贝。
  • 选项所有权onepath_xmr_opts_t 中字符串字段(republish_sign / node_id / encoding)由调用方持有;入口在创建时按需拷贝,调用返回后调用方即可释放原字符串。
  • 会话关闭顺序:销毁角色句柄应在关闭会话之前完成。资源销毁顺序见 内存管理

相关指南

  • 多模冗余(XMR) — 设计要点、N / quorum / 投票策略、可靠性模型与能力边界、跨节点快速开始。

OnePath™ 是西安汉为信息技术有限公司的注册商标。