From ac7ac99ced0a470b2d1d59db1cfd1e3ed41392a3 Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Fri, 17 Apr 2026 06:48:25 +0000 Subject: [PATCH] refactor: make merge semantics explicit in OnHostConfigUpdated/OnClusterUpdated Start from existing entry and apply this-source's fields, rather than starting from incoming and restoring the other-source's fields. The new pattern makes it immediately clear which fields each push type WRITES, without having to reason about which fields are being "restored". OnHostUpdated keeps the merged := *incoming + if ok guard because the worker push also populates HostModel/HostType from attrs; config-sourced values must only win when a prior config push has already set them. All 37 backend unit tests pass. --- src/frontend/apiserver/backend/handler.go | 64 ++++++++--------------- 1 file changed, 22 insertions(+), 42 deletions(-) diff --git a/src/frontend/apiserver/backend/handler.go b/src/frontend/apiserver/backend/handler.go index c3964c4..0a76824 100644 --- a/src/frontend/apiserver/backend/handler.go +++ b/src/frontend/apiserver/backend/handler.go @@ -38,52 +38,32 @@ func (h *DefaultHandler) OnHostUpdated(incoming *models.HostInfo) { store.Hosts.Put(merged.HostName, merged) } -// OnHostConfigUpdated merges config-sourced fields into an existing host entry. -// Worker-sourced fields (HostStatus, CPUFactor, NumCPUs, MaxMem, MaxSwap, -// MaxTmp, NumDisk, NumRun, NumSSusp, NumUSusp, NumDone) are preserved from -// the prior entry if one exists. -// NumCores, NumThreads, Topology, SchedStop are preserved here but currently -// have no write path in rawWorkerData — they remain zero until a future worker -// push source populates them (analogous to the DisptWindow deferral). +// OnHostConfigUpdated applies config-sourced fields onto the existing host entry. +// All other fields (worker-sourced) are preserved from the prior entry. +// NumCores, NumThreads, Topology, SchedStop have no current write path in +// rawWorkerData and remain zero until a future push source populates them +// (analogous to the DisptWindow deferral). func (h *DefaultHandler) OnHostConfigUpdated(incoming *models.HostInfo) { - merged := *incoming - if existing, ok := store.Hosts.Get(merged.HostName); ok { - merged.HostStatus = existing.HostStatus - merged.CPUFactor = existing.CPUFactor - merged.NumCPUs = existing.NumCPUs - merged.NumCores = existing.NumCores - merged.NumThreads = existing.NumThreads - merged.MaxMem = existing.MaxMem - merged.MaxSwap = existing.MaxSwap - merged.MaxTmp = existing.MaxTmp - merged.NumDisk = existing.NumDisk - merged.NumRun = existing.NumRun - merged.NumSSusp = existing.NumSSusp - merged.NumUSusp = existing.NumUSusp - merged.NumDone = existing.NumDone - merged.Topology = existing.Topology - merged.SchedStop = existing.SchedStop - } - store.Hosts.Put(merged.HostName, merged) + existing, _ := store.Hosts.Get(incoming.HostName) + existing.HostName = incoming.HostName + existing.HostModel = incoming.HostModel + existing.HostType = incoming.HostType + existing.MaxSlot = incoming.MaxSlot + existing.DisptWindow = incoming.DisptWindow + store.Hosts.Put(existing.HostName, existing) } -// OnClusterUpdated merges config-sourced fields into an existing cluster entry. -// Built-in fields (Version, Status, ControllerName, NumServers, Resources, -// HostTypes, HostModels, ClusterAdmins) are preserved from the prior entry -// if one exists. +// OnClusterUpdated applies config-sourced fields onto the existing cluster entry. +// All other fields (built-in/worker-sourced: Version, Status, ControllerName, +// NumServers, Resources, HostTypes, HostModels, ClusterAdmins) are preserved +// from the prior entry. func (h *DefaultHandler) OnClusterUpdated(incoming *models.ClusterInfo) { - merged := *incoming - if existing, ok := store.Clusters.Get(merged.ClusterName); ok { - merged.Version = existing.Version - merged.Status = existing.Status - merged.ControllerName = existing.ControllerName - merged.NumServers = existing.NumServers - merged.Resources = existing.Resources - merged.HostTypes = existing.HostTypes - merged.HostModels = existing.HostModels - merged.ClusterAdmins = existing.ClusterAdmins - } - store.Clusters.Put(merged.ClusterName, merged) + existing, _ := store.Clusters.Get(incoming.ClusterName) + existing.ClusterName = incoming.ClusterName + existing.HeartbeatInterval = incoming.HeartbeatInterval + existing.Vcpus = incoming.Vcpus + existing.InactiveHeartbeatCount = incoming.InactiveHeartbeatCount + store.Clusters.Put(existing.ClusterName, existing) } func (h *DefaultHandler) OnResourceUpdated(res *models.ResourceDefinitionInfo) {