@0xdefcdf6377db2e8e; using C = import "/c.capnp"; $C.fieldgetset; $C.codecgen; $C.extraheader("#include \"clusterconfig.h\""); $C.extraheader("#include \"typemap.h\""); enum OPCode { nop @0; reply @1; hello @2; join @3; shutdown @4; get @5; push @6; update @7; jobdispatch @8; startjob @9; notify @10; jobsub @11; jobstatus @12; jobrusage @13; hostcontrol @14; jobcontrol @15; newschedjobs @16; clusterconf @17; queuecontrol @18; runtasks @19; setpreason @20; clrpreason @21; replEntry @22; replAck @23; redirect @24; heartbeat @25; steppingDown @26; replSnapshot @27; replCatchUpDone @28; replConfig @29; replConfigPush @30; upgradeConfig @31; requestVote @32; probeConfigTag @33; walAck @34; upgradeConfigAck @35; snapshotTransfer @36; walCatchupEntry @37; preVoteRequest @38; preVoteReply @39; ctrlstatus @40; } struct PeerInfo $C.mapname("xce_peerinfo_t") { host @0: Text $C.mapname("name"); key @1: Text; } struct HostBasedReason $C.mapname("xce_host_reason_t") { host @0: Text; reason @1: UInt32; } struct ResourceBasedReason $C.mapname("xce_res_reason_t") { resource @0: Text; host @1: Text; reason @2: UInt32; } struct JobPendReason $C.mapname("xce_job_preason_t") { mainReason @0: UInt32 $C.mapname("main_reason"); hostReasons @1: List(HostBasedReason) $C.mapname("host_based_reasons") $C.maplistcount("nhost_reasons"); resReasons @2: List(ResourceBasedReason) $C.mapname("res_based_reasons") $C.maplistcount("nres_reasons"); } struct StrList $C.mapname("xce_strlist_t") { data @0: List(Text) $C.mapname("data") $C.maplistcount("count"); } struct TimeWindowTime $C.mapname("xce_timewindow_time_t") { day @0: UInt32 $C.mapname("day"); hour @1: UInt32 $C.mapname("hour"); min @2: UInt32 $C.mapname("min"); } struct TimeWindowSeg $C.mapname("xce_timewindow_seg_config_t") { timezone @0: Text $C.mapname("tz"); open @1: TimeWindowTime $C.mapname("open"); close @2: TimeWindowTime $C.mapname("close"); } struct TimeWindow $C.mapname("xce_timewindow_config_t") { segs @0: List(TimeWindowSeg) $C.mapname("segs") $C.maplistcount("nsegs"); } struct GroupConfig $C.mapname("xce_group_config_t") { name @0: Text $C.mapname("name"); members @1: List(Text) $C.mapname("members.data") $C.maplistcount("members.count"); exmembers @2: List(Text) $C.mapname("ex_members.data") $C.maplistcount("ex_members.count"); } # This data structure will not be transfer in wire # directly, it will be assembled by multiple Data packet struct Dataset $C.mapname("dataset_t") { table @0: UInt32; nrows @1: UInt32; rows @2: Void; # do NOT change this, it's place holder } struct ResKey $C.mapname("xce_reskey_t") { resname @0: Text; hostname @1: Text; } struct MatchCondition $C.mapname("xce_match_t") { condition :union $C.mapuniontag("type") { matchall @0: Void; matchjid @1: UInt64 $C.mapname("jobid"); matchwname @2: Text $C.mapname("wname"); matchreskey @3: ResKey $C.mapname("reskey"); } } struct HostAttrs $C.mapname("hostattrs_t") { type @0: Text $C.mapname("hosttype"); model @1: Text $C.mapname("hostmodel"); cpufactor @2: Float64; maxcpus @3: Int32; maxmem @4: Float64; maxswap @5: Float64; maxtmp @6: Float64; ndisks @7: Int32; } struct Worker $C.mapname("xce_worker_t"){ name @0: Text; attrs @1: HostAttrs; status @2: UInt32; dispatchWindow @3: TimeWindow $C.mapname("dispatch_window_config"); thresholds @4: List(Threshold) $C.mapname("thresholds") $C.maplistcount("nthresholds"); resvals @5: List(NameValue) $C.mapname("resvals_to_sched") $C.maplistcount("nresvals_to_sched"); deadSince @6: UInt64 = 0 $C.mapname("dead_since"); # epoch seconds; set when worker becomes UNAVAILABLE } enum HostRole { client @0; worker @1; scheduler @2; controller @3; apiserver @4; } struct JoinData $C.mapname("xce_joindata_t") { role @0: HostRole; data :union { nodata @1: Void; attrs @2: HostAttrs; } } struct Value $C.mapname("xce_val_t"){ u :union $C.mapuniontag("which") { ivalue32 @0: Int32; uvalue32 @1: UInt32; ivalue64 @2: Int64; uvalue64 @3: UInt64; svalue @4: Text; fvalue @5: Float64; bvalue @6: Bool; } } struct LimitValue $C.mapname("xce_limit_val_t") { resname @0: Text $C.mapname("resname"); percentage @1: Bool $C.mapname("percent"); value @2: Float64 $C.mapname("val"); } struct ValueWithIdx $C.mapname("xce_val_with_idx_t") { idx @0: UInt32; val @1: Value $C.mapname("val"); } struct NameValue $C.mapname("xce_name_val_t") { name @0: Text $C.mapname("name"); val @1: Value $C.mapname("val"); } struct ConfigVar $C.mapname("xce_config_t") { name @0: Text; value @1: Text; } struct ResourceDistribution $C.mapname("res_distribution_t") { value @0: Value; hosts @1: List(Text) $C.maplistcount("nhosts"); } struct Resource $C.mapname("xce_resource_t"){ name @0: Text; desc @1: Text; idx @2: Int32; valtype @3: Int32; ordtype @4: Int32; flags @5: Int32; interval @6: Int32; lastReport @7: UInt64 $C.mapname("last_report"); # distributions @8: List(ResourceDistribution) $C.maplistcount("ndistributions"); # hostBased @9: Value $C.mapname("hbased_defined"); } struct Threshold $C.mapname("xce_res_threshold_t"){ name @0: Text; sched @1: Float64; stop @2: Float64; } struct QueueConf $C.mapname("xce_queue_t") { name @0: Text $C.mapname("queue"); attrs @1: UInt32; status @2: UInt32; priority @3: Int32; acceptIntervals @4: Int32 $C.mapname("accept_interval"); schedDelay @5: Int32 $C.mapname("sched_delay"); resreq @6: Text; users @7: GroupConfig $C.mapname("users"); hosts @8: GroupConfig $C.mapname("hosts"); thresholds @9: List(Threshold) $C.maplistcount("nthresholds"); preExec @10: Text $C.mapname("pre_exec"); postExec @11: Text $C.mapname("post_exec"); runWindow @12: TimeWindow $C.mapname("runwindow_config"); dispatchWindow @13: TimeWindow $C.mapname("dispatchwindow_config"); } struct Conf4Sched $C.mapname("xce_conf4sched_t"){ clustername @0: Text; configvars @1: List(ConfigVar) $C.mapname("confvars") $C.maplistcount("n_confvars"); resources @2: List(Resource) $C.maplistcount("n_resources"); queues @3: List(QueueConf) $C.maplistcount("n_queues"); ugroups @4: List(GroupConfig) $C.maplistcount("n_ugroups"); hgroups @5: List(GroupConfig) $C.maplistcount("n_hgroups"); resvals @6: List(NameValue) $C.mapname("resvals") $C.maplistcount("nresvals"); hproviders @7: List(ScalerConfig) $C.mapname("hproviders") $C.maplistcount("nhproviders"); limits @8: List(LimitConfig) $C.mapname("limits") $C.maplistcount("nlimits"); } struct Conf4Worker $C.mapname("xce_conf4worker_t") { clustername @0: Text; configvars @1: List(ConfigVar) $C.mapname("confvars") $C.maplistcount("n_confvars"); } struct ConfigData $C.mapname("xce_configdata_t") { data :union $C.mapuniontag("data_which") { schedconfig @0: Conf4Sched $C.mapname("conf4sched"); workerconfig @1: Conf4Worker $C.mapname("conf4worker"); clusterconfig @2: ClusterConfig $C.mapname("clusterconfig"); } } struct JobPIDInfo $C.mapname("job_pidinfo_t"){ jobId @0: UInt64 $C.mapname("jobid"); pids @1: List(UInt32) $C.mapname("pids") $C.maplistcount("npids"); pgids @2: List(UInt32) $C.mapname("pgids") $C.maplistcount("npgids"); exdata @3: Text $C.mapname("exdata"); } struct JobFail $C.mapname("job_failinfo_t"){ jobId @0: UInt64 $C.mapname("jobid"); code @1: Int32 $C.mapname("code"); desc @2: Text $C.mapname("detail"); stage @3: UInt32 $C.mapname("stage"); } struct JobStartInfo $C.mapname("job_startinfo_t"){ exechome @0: Text; execcwd @1: Text; execuser @2: Text; cmdline @3: Text; exdata @4: Text; launchtype @5: Text $C.mapname("launch_type"); qPreExec @6: Text $C.mapname("q_pre_exec"); qPostExec @7: Text $C.mapname("q_post_exec"); preExec @8: Text $C.mapname("job_pre_exec"); postExec @9: Text $C.mapname("job_post_exec"); } struct Job $C.mapname("xce_job_t"){ jobid @0: UInt64; submitData @1: JobSubmitData $C.mapname("submit"); subtime @2: UInt64 $C.mapname("sub_time"); queuetime @3: UInt64 $C.mapname("queue_time"); starttime @4: UInt64 $C.mapname("start_time"); finishtime @5: UInt64 $C.mapname("finish_time"); state @6: UInt32; allocs @7: JobAlloc $C.mapname("allocs"); runtime @8: UInt32 $C.mapname("run_time"); pidinfo @9: JobPIDInfo; pendreason @10: JobPendReason $C.mapname("pend_reasons"); transientSince @11: UInt64 = 0 $C.mapname("transient_since"); # epoch seconds; set when job enters JOB_STAT_TRANSIENT } struct SchedJob $C.mapname("xce_job_t"){ jobid @0: UInt64; submitData @1: JobSubmitData $C.mapname("submit"); subtime @2: UInt64 $C.mapname("sub_time"); queuetime @3: UInt64 $C.mapname("queue_time"); starttime @4: UInt64 $C.mapname("start_time"); finishtime @5: UInt64 $C.mapname("finish_time"); state @6: UInt32; allocs @7: JobAlloc $C.mapname("allocs"); runtime @8: UInt32 $C.mapname("run_time"); } struct SchedJobRusages $C.mapname("xce_job_rusages_t") { jobid @0: UInt64 $C.mapname("jobid"); usages @1: List(ResUsage) $C.mapname("usages") $C.maplistcount("count"); } struct JobData $C.mapname("xce_jobs_data_t") { ntotal @0: UInt32 $C.mapname("n_total"); pos @1: UInt32; jobs @2: List(Job) $C.maplistcount("count"); } struct SchedJobData $C.mapname("xce_jobs_data_t") { ntotal @0: UInt32 $C.mapname("n_total"); pos @1: UInt32; jobs @2: List(SchedJob) $C.maplistcount("count"); } struct WorkerData $C.mapname("xce_workers_data_t"){ ntotal @0: UInt32 $C.mapname("n_total"); pos @1: UInt32; workers @2: List(Worker) $C.maplistcount("count"); } struct ResourceData $C.mapname("xce_resource_data_t") { ntotal @0: UInt32 $C.mapname("n_total"); pos @1: UInt32; resources @2: List(Resource) $C.maplistcount("count"); } struct ResourceVal $C.mapname("xce_resval_t") { name @0: Text $C.mapname("name"); host @1: Text $C.mapname("host"); val @2: Value $C.mapname("val"); } struct ResourceVals $C.mapname("xce_resval_data_t") { ntotal @0: UInt32 $C.mapname("n_total"); pos @1: UInt32; vals @2: List(ResourceVal) $C.mapname("vals") $C.maplistcount("count"); } struct Data $C.mapname("xce_data_t"){ data :union $C.mapuniontag("table") { schedjobs @0: SchedJobData $C.mapname("jobs"); schedworkers @1: WorkerData $C.mapname("workers"); jobs @2: JobData $C.mapname("jobs"); workers @3: WorkerData $C.mapname("workers"); resources @4: ResourceData $C.mapname("resources"); resvals @5: ResourceVals $C.mapname("resvals"); } } struct Get $C.mapname("xce_get_t") { table @0: UInt32; condition @1: MatchCondition; } struct ResValList $C.mapname("xce_resval_list_t") { vals @0: List(ResourceVal) $C.mapname("vals") $C.maplistcount("count"); } struct ResUsage $C.mapname("xce_rusage_t") { name @0: Text $C.mapname("resname"); value @1: Float64 $C.mapname("value"); } struct JobRusages $C.mapname("xce_job_rusages_t") { jobid @0: UInt64 $C.mapname("jobid"); pids @1: List(Int32) $C.mapname("pids") $C.maplistcount("npids"); pgids @2: List(Int32) $C.mapname("pgids") $C.maplistcount("npgids"); usages @3: List(ResUsage) $C.mapname("usages") $C.maplistcount("count"); } struct Update $C.mapname("xce_update_data_t") { data :union $C.mapuniontag("table") { nodata @0: Void; resvals @1: ResValList $C.mapname("resvals"); jobrusages @2: JobRusages $C.mapname("jobrusages"); } } struct ResAlloc $C.mapname("xce_alloc_t"){ name @0: Text $C.mapname("resname"); resvId @1: Text $C.mapname("reserve"); instid @2: UInt64; value @3: Float64; from @4: UInt64; # alloc start time duration @5: Int64; } struct HostAlloc $C.mapname("xce_host_alloc_t"){ host @0: Text; allocs @1: List(ResAlloc) $C.mapname("allocs") $C.maplistcount("nallocs"); } struct JobAlloc $C.mapname("xce_job_alloc_t"){ jobid @0: UInt64; allocs @1: List(HostAlloc) $C.mapname("allocs") $C.maplistcount("nhosts"); allocsShared @2: List(ResAlloc) $C.mapname("allocs_shared") $C.maplistcount("nres_shared"); } struct JobDispatch $C.mapname("xce_job_dispatch_t"){ allocs @0: List(JobAlloc) $C.maplistcount("njobs"); } struct HostLaunch $C.mapname("xce_host_launch_t") { host @0: Text $C.mapname("host"); nranks @1: UInt32 $C.mapname("nranks"); } struct JobLaunch $C.mapname("xce_launch_t") { hosts @0: List(HostLaunch) $C.mapname("hosts") $C.maplistcount("nhosts"); } struct JobExecInfo $C.mapname("xce_job_exec_t"){ jobid @0: UInt64; startinfo @1: JobStartInfo $C.mapname("start_info"); launchinfo @2: JobLaunch $C.mapname("launchinfo"); } struct JobFinishInfo $C.mapname("xce_jobfinish_t") { jobid @0: UInt64; code @1: Int32 $C.mapname("exit_code"); } struct TaskPidInfo $C.mapname("xce_task_pidinfo_t") { jobid @0: UInt64 $C.mapname("jobid"); host @1: Text $C.mapname("host"); taskidx @2: Int32 $C.mapname("taskidx"); pids @3: List(UInt32) $C.mapname("pids") $C.maplistcount("npids"); pgids @4: List(UInt32) $C.mapname("pgids") $C.maplistcount("npgids"); exdata @5: Text $C.mapname("exdata"); clientidx @6: UInt32 $C.mapname("clientidx"); } struct TaskFailInfo $C.mapname("xce_task_failinfo_t") { jobid @0: UInt64 $C.mapname("jobid"); host @1: Text $C.mapname("host"); taskidx @2: Int32 $C.mapname("taskidx"); code @3: Int32 $C.mapname("code"); detail @4: Text $C.mapname("detail"); clientidx @5: Int32 $C.mapname("clientidx"); } struct TaskFinish $C.mapname("xce_task_finish_t") { jobid @0: UInt64 $C.mapname("jobid"); host @1: Text $C.mapname("host"); taskidx @2: UInt32 $C.mapname("taskidx"); exitcode @3: Int32 $C.mapname("exit_code"); clientidx @4: Int32 $C.mapname("clientidx"); } struct NotifyData $C.mapname("xce_notify_data_t"){ data :union $C.mapuniontag("event") $C.mapname("data"){ jobPidInfo @0: JobPIDInfo $C.mapname("pidinfo"); jobFailInfo @1: JobFail $C.mapname("failinfo"); jobDispatchFail @2: JobFail $C.mapname("dispatchfail"); jobFinishInfo @3: JobFinishInfo $C.mapname("finishinfo"); schedStartJob @4: UInt64 $C.mapname("sched_start_job"); schedExitJob @5: UInt64 $C.mapname("sched_exit_job"); schedFailJob @6: UInt64 $C.mapname("sched_fail_job"); schedUpdateJob @7: SchedJob $C.mapname("sched_update_job"); schedUpdateResvals @8: ResValList $C.mapname("sched_update_resvals"); stoppedJob @9: UInt64 $C.mapname("stopped_job"); resumedJob @10: UInt64 $C.mapname("resumed_job"); ckptinfo @11: CheckpointInfo $C.mapname("ckptinfo"); schedUpdateQueue @12: QueueConf $C.mapname("sched_update_queue"); taskPidInfo @13: TaskPidInfo $C.mapname("taskinfo"); taskFailInfo @14: TaskFailInfo $C.mapname("taskfailinfo"); taskFinish @15: TaskFinish $C.mapname("taskfinish"); postDoneJob @16: UInt64 $C.mapname("pdone_job"); schedJobRusages @17: SchedJobRusages $C.mapname("sched_job_rusages"); updateJob @18: Job $C.mapname("update_job"); } } 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: Text; 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; responderTimeMs @13: UInt64 $C.mapname("responder_time_ms"); # responder's wall-clock at sample time (epoch milliseconds) } struct ClusterConf $C.mapname("xce_clusterconf_t") { name @0: Text; resources @1: List(Resource) $C.mapname("reslist.res") $C.maplistcount("reslist.count"); queues @2: List(QueueConf) $C.mapname("qlist.queues") $C.maplistcount("qlist.count"); workers @3: List(Worker) $C.mapname("wlist.workers") $C.maplistcount("wlist.count"); } struct JobSubmitData $C.mapname("job_submit_data_t") { queue @0: Text; user @1: Text; mintasks @2: UInt32; maxtasks @3: UInt32; jobname @4: Text $C.mapname("job_name"); project @5: Text $C.mapname("project_name"); ugroup @6: Text $C.mapname("user_group"); description @7: Text $C.mapname("job_description"); resreq @8: Text; startinfo @9: JobStartInfo $C.mapname("start_info"); } struct JobSubmit $C.mapname("xce_job_submit_t") { jobid @0: UInt64; arraySize @1: UInt64 $C.mapname("array_size"); submit @2: JobSubmitData; } struct JobSignal $C.mapname("xce_signal_t") { signo @0: UInt32 $C.mapname("signo"); force @1: Int32 $C.mapname("force"); } struct CheckpointOptions $C.mapname("xce_ckpt_options_t"){ kill @0: UInt32 $C.mapname("kill"); method @1: Text $C.mapname("method"); } struct CheckpointInfo $C.mapname("xce_ckptinfo_t") { jobid @0: UInt64; ckptinfo @1: Text; } struct JobControl $C.mapname("xce_jobctrl_t") { jobid @0: UInt64 $C.mapname("jobid"); u :union $C.mapuniontag("action") $C.mapname("u") { siginfo @1: JobSignal; ckptoption @2: CheckpointOptions; } } struct QueueControl $C.mapname("xce_queuectrl_t") { action @0: UInt32 $C.mapname("action"); queue @1: Text $C.mapname("queue"); } struct HostControl $C.mapname("xce_hostctrl_t") { action @0: UInt32 $C.mapname("action"); hostname @1: Text $C.mapname("hostname"); } struct RequestReply $C.mapname("xce_reply_t"){ seq @0: UInt64; opcode @1: OPCode; status @2: Int32; data : union { nodata @3: Void; debugmsg @4: Text; getdata @5: Data; jobid @6: UInt64; clusterconf @7: ClusterConf; replconfigreplymsg @8: ReplConfigReply; replconfigpushreplymsg @9: ReplConfigPushReply; upgradeconfigreplymsg @10: UpgradeConfigReply; ctrlhelloreplymsg @13: CtrlHelloReply; requestvotereplymsg @14: RequestVoteReply; stateReportMsg @15: StateReport $C.mapname("state_report"); # heartbeat reply: standby state 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"); redirectPort @12: UInt16 $C.mapname("redirect_port"); } struct TaskHost $C.mapname("xce_taskhost_t") { host @0: Text; ntasks @1: UInt32; exechome @2: Text; execcwd @3: Text; execuser @4: Text; cmdline @5: Text; exdata @6: Text; launchtype @7: Text $C.mapname("launch_type"); } struct RunTask $C.mapname("xce_taskrun_t") { clientidx @0: Int32 $C.mapname("clientidx"); hosts @1: List(TaskHost) $C.mapname("taskhosts") $C.maplistcount("nhosts"); jobid @2: UInt64 $C.mapname("jobid"); } struct PendReason $C.mapname("xce_pendreason_t") { jobid @0: UInt64 $C.mapname("jobid"); reasons @1: JobPendReason $C.mapname("reasons"); } struct PendReasonSet $C.mapname("xce_preason_set_t") { reason @0: List(PendReason) $C.mapname("reasons") $C.maplistcount("nreasons"); } struct ClearPReason $C.mapname("xce_clear_reason_t") { jobs @0: List(UInt64) $C.mapname("jobs") $C.maplistcount("njobs"); } struct Request $C.mapname("xce_request_t"){ opcode @0: OPCode; seq @1: UInt64; from @2: PeerInfo; body : union { nomsg @3: Void; replymsg @4: RequestReply; hellomsg @5: Text; joinmsg @6: JoinData; configpushmsg @7: ConfigData; pushmsg @8: Data; getmsg @9: Get; datamsg @10: Dataset; dispatchmsg @11: JobDispatch; jobstartmsg @12: JobExecInfo; notifymsg @13: NotifyData; jobsubmsg @14: JobSubmit; updatemsg @15: Update; jobctrlmsg @16: JobControl; queuectrlmsg @17: QueueControl; runtaskmsg @18: RunTask; preasonmsg @19: PendReasonSet; clrpreasonmsg @20: ClearPReason; hostctrlmsg @21: HostControl; replconfigrequestmsg @22: ReplConfigRequest; replconfigpushrequestmsg @23: ReplConfigPushRequest; upgradeconfigrequestmsg @24: UpgradeConfigRequest; heartbeatmsg @25: HeartbeatMsg; ctrlhellomsg @26: CtrlHelloRequest; requestvotemsg @27: RequestVoteRequest; walcatchupentrymsg @28: WalCatchupEntry; snapshottransfermsg @29: SnapshotTransfer; } } struct HashZArrayConfig $C.mapname("hash_zarray_config_t") { nHashSlots @0: UInt32 $C.mapname("nhash_slots"); delta @1: UInt32 $C.mapname("delta"); } struct ResmgrConfig $C.mapname("resmgr_config_t") { nHashSlots @0: UInt32 $C.mapname("nhash_slots"); delta @1: UInt32 $C.mapname("delta"); instDelta @2: UInt32 $C.mapname("inst_delta"); } struct MasterCandidate $C.mapname("master_candidate_t") { name @0: Text $C.mapname("name"); host @1: Text $C.mapname("host"); port @2: UInt32 $C.mapname("port"); } struct HostConfig $C.mapname("xce_hostconfig_t") { name @0: Text $C.mapname("name"); model @1: Text $C.mapname("hostmodel"); type @2: Text $C.mapname("hosttype"); mxj @3: UInt32 $C.mapname("mxj"); resources @4: List(ConfigVar) $C.mapname("resources") $C.maplistcount("nresources"); thresholds @5: List(Threshold) $C.mapname("thresholds") $C.maplistcount("nthresholds"); dispatchwindows @6: TimeWindow $C.mapname("dispatchwindow"); } struct ScalerConfig $C.mapname("scaler_config_t") { name @0: Text $C.mapname("name"); type @1: Text $C.mapname("prov_type"); confPath @2: Text $C.mapname("conf_path"); scriptPath @3: Text $C.mapname("script_path"); scriptOption @4: Text $C.mapname("script_option"); } struct LimitConfig $C.mapname("xce_limit_config_t") { name @0: Text $C.mapname("name"); users @1: GroupConfig $C.mapname("users"); queues @2: GroupConfig $C.mapname("queues"); projects @3: GroupConfig $C.mapname("projects"); hosts @4: GroupConfig $C.mapname("hosts"); val @5: LimitValue $C.mapname("val"); perUser @6: Bool $C.mapname("per_user"); perQueue @7: Bool $C.mapname("per_queue"); perProject @8: Bool $C.mapname("per_project"); perHost @9: Bool $C.mapname("per_host"); } struct ClusterConfig $C.mapname("cluster_config_t") { clusterName @0: Text $C.mapname("clustername"); port @1: UInt32 $C.mapname("port"); candidates @2: List(MasterCandidate) $C.mapname("candidates") $C.maplistcount("ncandidates"); heartbeatInterval @3: UInt32 $C.mapname("heartbeat_interval"); inactiveHeartbeatCount @4: UInt32 $C.mapname("inactive_heartbeat_count"); fetchJobInterval @5: UInt32 $C.mapname("fetch_job_interval"); netioTimeout @6: UInt32 $C.mapname("netio_timeout"); vcpus @7: UInt32 $C.mapname("vcpus"); # deprecated: use --vcpus CLI flag; kept for config blob backward compatibility resources @8: List(Resource) $C.mapname("resources") $C.maplistcount("nres"); queues @9: List(QueueConf) $C.mapname("queues") $C.maplistcount("nqueues"); ugroups @10: List(GroupConfig) $C.mapname("ugroups") $C.maplistcount("nugroups"); hgroups @11: List(GroupConfig) $C.mapname("hgroups") $C.maplistcount("nhgroups"); hostConfigs @12: List(HostConfig) $C.mapname("hconfigs") $C.maplistcount("nhconfigs"); jobmgr @13: HashZArrayConfig; workermgr @14: HashZArrayConfig; qmgr @15: HashZArrayConfig; resmgr @16: ResmgrConfig; xstrings @17: HashZArrayConfig; hproviders @18: List(ScalerConfig) $C.mapname("hproviders") $C.maplistcount("nhproviders"); limits @19: List(LimitConfig) $C.mapname("limits") $C.maplistcount("nlimits"); configGeneration @20: UInt64 $C.mapname("config_generation"); } # ── Persistence configuration (Part 2.6) ──────────────────────────── # $C.mapname uses capnp_persist_cfg_t (not persist_config_t) to avoid # collision with the plain-C struct already defined in persist.h. struct PersistConfig $C.mapname("capnp_persist_cfg_t") { walSyncMs @0 :UInt32 = 10; snapIntervalS @1 :UInt32 = 60; snapWalSizeMb @2 :UInt32 = 64; finishedRetainS @3 :UInt32 = 3600; workerRetainS @4 :UInt32 = 86400; syncTimeoutMs @5 :UInt32 = 50; snapKeepN @6 :UInt32 = 2; transientJobTimeoutS @7 :UInt32 = 300; } # ── Snapshot header (Part 2.5) ─────────────────────────────────────── struct SnapshotHeader $C.mapname("capnp_snap_hdr_t") { lsn @0 :UInt64; term @1 :UInt64; timestamp @2 :UInt64; version @3 :UInt32 = 1; nJobs @4 :UInt32; nQueues @5 :UInt32; nWorkers @6 :UInt32; checksum @7 :UInt32; headerChecksum @8 :UInt32; } # ── HA heartbeat ──────────────────────────────────────────────────── struct HeartbeatMsg $C.mapname("heartbeat_msg_t") { senderPriority @0: UInt32 $C.mapname("sender_priority"); term @1: UInt64 $C.mapname("term"); committedLsn @2: UInt64 $C.mapname("committed_lsn"); committedConfigTag @3: UInt64 $C.mapname("committed_config_tag"); } # ── Config replication message structs ────────────────────────────── struct ReplConfigRequest $C.mapname("repl_config_req_t") { versionTag @0: UInt64 $C.mapname("version_tag"); } struct ReplConfigReply $C.mapname("repl_config_reply_t") { upToDate @0: Bool $C.mapname("up_to_date"); versionTag @1: UInt64 $C.mapname("version_tag"); sha256 @2: Data $C.mapname("sha256"); bytes @3: Data $C.mapname("bytes"); } struct ReplConfigPushRequest $C.mapname("repl_config_push_req_t") { versionTag @0: UInt64 $C.mapname("version_tag"); sha256 @1: Data $C.mapname("sha256"); bytes @2: Data $C.mapname("bytes"); } struct ReplConfigPushReply $C.mapname("repl_config_push_reply_t") { accepted @0: Bool $C.mapname("accepted"); versionTag @1: UInt64 $C.mapname("version_tag"); } struct UpgradeConfigRequest $C.mapname("upgrade_config_req_t") { sha256 @0: Data $C.mapname("sha256"); bytes @1: Data $C.mapname("bytes"); } struct UpgradeConfigReply $C.mapname("upgrade_config_reply_t") { versionTag @0: UInt64 $C.mapname("version_tag"); error @1: Text $C.mapname("error"); ackedCount @2: UInt32 $C.mapname("acked_count"); } # ── WAL replication envelope (Part 6 — NOT the on-disk format) ─────── # Named ReplEnvelope to avoid collision with the on-disk wal_entry_hdr_t. struct ReplEnvelope $C.mapname("capnp_repl_envelope_t") { term @0 :UInt64; lsn @1 :UInt64; entryType @2 :UInt32; payload @3 :Data; crc @4 :UInt32; prevCrc @5 :UInt32; } # ── HA election and replication message structs (Task 1.1) ─────────── # Heartbeat reply state report — standby piggybacks its replication state # onto every OPCode_nop reply so the primary can drive convergence decisions. struct StateReport $C.mapname("state_report_t") { appliedLsn @0 :UInt64 $C.mapname("applied_lsn"); # standby's last applied WAL LSN configTag @1 :UInt64 $C.mapname("config_tag"); # standby's current config version tag } struct RequestVoteRequest $C.mapname("request_vote_req_t") { term @0 :UInt64 $C.mapname("term"); candidateId @1 :Text $C.mapname("candidate_id"); configTag @2 :UInt64 $C.mapname("config_tag"); lastLogLsn @3 :UInt64 $C.mapname("last_log_lsn"); } struct RequestVoteReply $C.mapname("request_vote_reply_t") { term @0 :UInt64 $C.mapname("term"); voteGranted @1 :Bool $C.mapname("vote_granted"); peerConfigTag @2 :UInt64 $C.mapname("peer_config_tag"); peerLastLogLsn @3 :UInt64 $C.mapname("peer_last_log_lsn"); } struct ProbeConfigTagRequest $C.mapname("probe_config_tag_req_t") { name @0 :Text $C.mapname("name"); } struct ProbeConfigTagReply $C.mapname("probe_config_tag_reply_t") { configTag @0 :UInt64 $C.mapname("config_tag"); } struct WalAckRequest $C.mapname("wal_ack_req_t") { term @0 :UInt64 $C.mapname("term"); lsn @1 :UInt64 $C.mapname("lsn"); } struct WalAckReply $C.mapname("wal_ack_reply_t") { term @0 :UInt64 $C.mapname("term"); lsn @1 :UInt64 $C.mapname("lsn"); success @2 :Bool $C.mapname("success"); } struct UpgradeConfigAck $C.mapname("upgrade_config_ack_t") { term @0 :UInt64 $C.mapname("term"); ackedTag @1 :UInt64 $C.mapname("acked_tag"); success @2 :Bool $C.mapname("success"); } # ── Snapshot chunk transfer (Req 4.1–4.2) ─────────────────────────── # Used for OPCode_snapshotTransfer: full state snapshot transferred as # a sequence of fixed-size chunks (64 KB max each). Restart-on-reconnect # semantics — no resumption state needed. Fields @0 and @1 are preserved # for wire-protocol continuity; @2–@5 carry the chunk envelope. struct SnapshotTransfer $C.mapname("snapshot_transfer_t") { snapshotLsn @0 :UInt64 $C.mapname("snapshot_lsn"); # checkpoint LSN this snapshot corresponds to payload @1 :Data $C.mapname("payload"); # chunk payload (64 KB max) chunkIndex @2 :UInt32 $C.mapname("chunk_index"); # 0-based chunk number chunkOffset @3 :UInt64 $C.mapname("chunk_offset"); # byte offset in the full snapshot totalSize @4 :UInt64 $C.mapname("total_size"); # total snapshot size in bytes isLast @5 :Bool $C.mapname("is_last"); # true for the final chunk } struct WalCatchupEntry $C.mapname("wal_catchup_entry_t") { lsn @0 :UInt64 $C.mapname("lsn"); entryType @1 :UInt8 $C.mapname("entry_type"); payload @2 :Data $C.mapname("payload"); entries @3 :List(WalCatchupEntry) $C.mapname("entries") $C.maplistcount("n_entries"); } struct CtrlHelloRequest $C.mapname("ctrl_hello_req_t") { name @0 :Text $C.mapname("name"); key @1 :Data $C.mapname("key"); appliedLsn @2 :UInt64 $C.mapname("applied_lsn"); configTag @3 :UInt64 $C.mapname("config_tag"); } struct CtrlHelloReply $C.mapname("ctrl_hello_reply_t") { committedLsn @0 :UInt64 $C.mapname("committed_lsn"); needsSnapshot @1 :Bool $C.mapname("needs_snapshot"); configTag @2 :UInt64 $C.mapname("config_tag"); }