feat(controller-status): add ctrlstatus opcode + CtrlStatus/CtrlPeer schema + typemap typedefs (task 1.1)
This commit is contained in:
parent
4b75bfa4db
commit
97a501e96e
4 changed files with 59 additions and 4 deletions
|
|
@ -15,8 +15,8 @@
|
||||||
},
|
},
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"generated": true,
|
"generated": true,
|
||||||
"approved": false
|
"approved": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ready_for_implementation": false
|
"ready_for_implementation": true
|
||||||
}
|
}
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
> The work runs along a single request path (schema → controller handler → dispatch gate → libxce client → test command → wait-primary), so tasks are sequential by design; no `(P)` markers. The one HA-critical change is the dispatch-gate allow-list (task 2.2).
|
> The work runs along a single request path (schema → controller handler → dispatch gate → libxce client → test command → wait-primary), so tasks are sequential by design; no `(P)` markers. The one HA-critical change is the dispatch-gate allow-list (task 2.2).
|
||||||
|
|
||||||
- [ ] 1. Foundation: status reply schema + codegen
|
- [ ] 1. Foundation: status reply schema + codegen
|
||||||
- [ ] 1.1 Add the `ctrlstatus` opcode and the status reply payload to the schema
|
- [x] 1.1 Add the `ctrlstatus` opcode and the status reply payload to the schema
|
||||||
- Add a new request opcode `ctrlstatus` (next free ordinal) and a new reply-union member (next free ordinal), plus a lean status payload struct carrying: cluster name, primary name, responder name and role, term, loaded config version and content checksum, committed config version, commit and apply positions, fenced flag, and a bounded list of configured controllers (name, host, port) with a count.
|
- Add a new request opcode `ctrlstatus` (next free ordinal) and a new reply-union member (next free ordinal), plus a lean status payload struct carrying: cluster name, primary name, responder name and role, term, loaded config version and content checksum, committed config version, commit and apply positions, fenced flag, and a bounded list of configured controllers (name, host, port) with a count.
|
||||||
- Keep the payload focused on identity/health only — it must NOT carry the resource/queue/worker inventory.
|
- Keep the payload focused on identity/health only — it must NOT carry the resource/queue/worker inventory.
|
||||||
- Observable: the build regenerates the C types for the new payload and opcode (the generated status type, its reply-union tag, and a free helper exist) and the schema compiles clean.
|
- Observable: the build regenerates the C types for the new payload and opcode (the generated status type, its reply-union tag, and a free helper exist) and the schema compiles clean.
|
||||||
|
|
@ -67,3 +67,4 @@
|
||||||
- All new C types are generated from the schema (task 1.1) — no hand-written struct headers. Build regenerates `controller.capnp.h/.c`.
|
- All new C types are generated from the schema (task 1.1) — no hand-written struct headers. Build regenerates `controller.capnp.h/.c`.
|
||||||
- Task 2.2 is the one HA-critical change (request-handling path): keep it scoped to the single read-only opcode and prove no other opcode's gating widened.
|
- Task 2.2 is the one HA-critical change (request-handling path): keep it scoped to the single read-only opcode and prove no other opcode's gating widened.
|
||||||
- The authoritative redirect (3.2) is what makes wait-primary trustworthy (no stale-standby false success) — it is the resolution of the design-review decision; do not collapse it back into a plain any-node read for wait-primary.
|
- The authoritative redirect (3.2) is what makes wait-primary trustworthy (no stale-standby false success) — it is the resolution of the design-review decision; do not collapse it back into a plain any-node read for wait-primary.
|
||||||
|
- 1.1 LEARNING (affects later tasks): the `$C.mapname(...)` capnp types are NOT auto-generated in this schema — the generated `controller.capnp.c` references HAND-AUTHORED C typedefs in `src/include/typemap.h` (same convention as `xce_clusterconf_t`). So `xce_ctrlstatus_t`/`xce_ctrlpeer_t` (and the `xce_reply_t.data.ctrlstatus` union member) live in `typemap.h`, verified field-for-field against the regenerated codec. `OPCode_ctrlstatus = 40`, `RequestReply_data_ctrlstatus = 12`. `configChecksum` is `xce_data_t*`. The handler/libxce tasks build/encode against these typemap.h types.
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,35 @@ typedef struct {
|
||||||
int success;
|
int success;
|
||||||
} wal_ack_reply_t;
|
} wal_ack_reply_t;
|
||||||
|
|
||||||
|
/* ctrlstatus reply payload (controller-status spec): one configured
|
||||||
|
* controller (CtrlPeer) and the lean identity/health snapshot (CtrlStatus).
|
||||||
|
* The peers list maps via $C.mapname("peers.list")/$C.maplistcount("peers.count")
|
||||||
|
* to the nested { count, list } member below. */
|
||||||
|
typedef struct {
|
||||||
|
char* name;
|
||||||
|
char* host;
|
||||||
|
uint32_t port;
|
||||||
|
} xce_ctrlpeer_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* clusterName;
|
||||||
|
char* primaryName;
|
||||||
|
char* responderName;
|
||||||
|
uint8_t responderRole;
|
||||||
|
uint64_t term;
|
||||||
|
uint64_t configVersion;
|
||||||
|
xce_data_t* configChecksum;
|
||||||
|
uint64_t committedConfigVersion;
|
||||||
|
uint64_t committedLsn;
|
||||||
|
uint64_t appliedLsn;
|
||||||
|
unsigned fenced;
|
||||||
|
struct {
|
||||||
|
int count;
|
||||||
|
xce_ctrlpeer_t** list;
|
||||||
|
} peers;
|
||||||
|
uint32_t peerCount;
|
||||||
|
} xce_ctrlstatus_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t seq;
|
uint64_t seq;
|
||||||
uint32_t opcode;
|
uint32_t opcode;
|
||||||
|
|
@ -220,6 +249,7 @@ typedef struct {
|
||||||
request_vote_reply_t* requestvotereplymsg;
|
request_vote_reply_t* requestvotereplymsg;
|
||||||
state_report_t* state_report;
|
state_report_t* state_report;
|
||||||
wal_ack_reply_t* walackreplymsg;
|
wal_ack_reply_t* walackreplymsg;
|
||||||
|
xce_ctrlstatus_t* ctrlstatus;
|
||||||
} data;
|
} data;
|
||||||
/* Req 7: standby redirect fields — populated when status == XCE_ERR_STANDBY */
|
/* Req 7: standby redirect fields — populated when status == XCE_ERR_STANDBY */
|
||||||
char *redirect_host;
|
char *redirect_host;
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ enum OPCode {
|
||||||
walCatchupEntry @37;
|
walCatchupEntry @37;
|
||||||
preVoteRequest @38;
|
preVoteRequest @38;
|
||||||
preVoteReply @39;
|
preVoteReply @39;
|
||||||
|
ctrlstatus @40;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PeerInfo $C.mapname("xce_peerinfo_t") {
|
struct PeerInfo $C.mapname("xce_peerinfo_t") {
|
||||||
|
|
@ -486,6 +487,28 @@ struct NotifyData $C.mapname("xce_notify_data_t"){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CtrlPeer $C.mapname("xce_ctrlpeer_t") {
|
||||||
|
name @0: Text;
|
||||||
|
host @1: Text;
|
||||||
|
port @2: UInt32;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CtrlStatus $C.mapname("xce_ctrlstatus_t") {
|
||||||
|
clusterName @0: Text;
|
||||||
|
primaryName @1: Text;
|
||||||
|
responderName @2: Text;
|
||||||
|
responderRole @3: UInt8;
|
||||||
|
term @4: UInt64;
|
||||||
|
configVersion @5: UInt64;
|
||||||
|
configChecksum @6: Data;
|
||||||
|
committedConfigVersion @7: UInt64;
|
||||||
|
committedLsn @8: UInt64;
|
||||||
|
appliedLsn @9: UInt64;
|
||||||
|
fenced @10: Bool;
|
||||||
|
peers @11: List(CtrlPeer) $C.mapname("peers.list") $C.maplistcount("peers.count");
|
||||||
|
peerCount @12: UInt32;
|
||||||
|
}
|
||||||
|
|
||||||
struct ClusterConf $C.mapname("xce_clusterconf_t") {
|
struct ClusterConf $C.mapname("xce_clusterconf_t") {
|
||||||
name @0: Text;
|
name @0: Text;
|
||||||
resources @1: List(Resource) $C.mapname("reslist.res") $C.maplistcount("reslist.count");
|
resources @1: List(Resource) $C.mapname("reslist.res") $C.maplistcount("reslist.count");
|
||||||
|
|
@ -563,6 +586,7 @@ struct RequestReply $C.mapname("xce_reply_t"){
|
||||||
requestvotereplymsg @14: RequestVoteReply;
|
requestvotereplymsg @14: RequestVoteReply;
|
||||||
stateReportMsg @15: StateReport $C.mapname("state_report"); # heartbeat reply: standby state
|
stateReportMsg @15: StateReport $C.mapname("state_report"); # heartbeat reply: standby state
|
||||||
walackreplymsg @16: WalAckReply $C.mapname("walackreplymsg"); # WAL apply ACK from standby
|
walackreplymsg @16: WalAckReply $C.mapname("walackreplymsg"); # WAL apply ACK from standby
|
||||||
|
ctrlstatus @17: CtrlStatus; # ctrlstatus reply: identity/health snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
redirectHost @11: Text $C.mapname("redirect_host");
|
redirectHost @11: Text $C.mapname("redirect_host");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue