From bd437f49e46fae33778585424a3bee2a97ae8ac3 Mon Sep 17 00:00:00 2001 From: Axodouble Date: Thu, 14 May 2026 00:00:58 +0000 Subject: [PATCH] Added RPC calls to get the status from the master on non-master nodes --- internal/daemon/control.go | 2 +- internal/daemon/handlers.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/internal/daemon/control.go b/internal/daemon/control.go index 7c6f515..0d025b3 100644 --- a/internal/daemon/control.go +++ b/internal/daemon/control.go @@ -189,7 +189,7 @@ func (c *controlServer) handleConn(ctx context.Context, conn net.Conn) { func (c *controlServer) dispatch(ctx context.Context, req CtrlRequest) CtrlResponse { switch req.Method { case CtrlStatus: - return ok(c.d.buildStatus()) + return ok(c.d.buildStatusForCLI(ctx)) case CtrlMutate: var body MutateBody diff --git a/internal/daemon/handlers.go b/internal/daemon/handlers.go index 044ec2b..112b685 100644 --- a/internal/daemon/handlers.go +++ b/internal/daemon/handlers.go @@ -113,6 +113,35 @@ func (d *Daemon) registerHandlers() { }) } +// buildStatusForCLI is what the local control plane returns to `qu +// status`. Peers, quorum, and term come from the local view; check +// state is fetched from the master because the aggregator only runs +// there. If the master is unknown or unreachable, falls back to the +// local view (which will show "unknown" for every check). +func (d *Daemon) buildStatusForCLI(ctx context.Context) transport.StatusResponse { + local := d.buildStatus() + if d.quorum.IsMaster() { + return local + } + masterID := d.quorum.Master() + if masterID == "" { + return local + } + addr := d.addressOf(masterID) + if addr == "" { + return local + } + callCtx, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() + var remote transport.StatusResponse + if err := d.client.Call(callCtx, masterID, addr, transport.MethodStatus, transport.StatusRequest{}, &remote); err != nil { + d.logger.Printf("status: fetch from master %s: %v", masterID, err) + return local + } + local.Checks = remote.Checks + return local +} + // buildStatus is shared by both the inter-node Status RPC handler and // the local control plane's "status" command. func (d *Daemon) buildStatus() transport.StatusResponse {