feat: P0-1e expand handleConfigPush with host config and cluster dispatch

Wires the remaining cluster_config_t data into the notification pipeline:
- dispatchConfigPush() extracted as a pure-Go helper (CGO-free, testable)
  that drives OnQueueUpdated, OnResourceUpdated, OnHostConfigUpdated, and
  OnClusterUpdated from a single config push event
- handleConfigPush() delegates to dispatchConfigPush via the new helper,
  eliminating the previous inline loops
- OnHostConfigUpdated and OnClusterUpdated added to NotificationHandler
  interface and implemented with partial-merge semantics in DefaultHandler
- rawHostConfigData/rawHostConfigToModel and rawClusterData/rawClusterToModel
  added to convert_pure.go with their CGO extraction counterparts in convert.go

Safety fixes from code review:
- OnHostUpdated, OnHostConfigUpdated, OnClusterUpdated now copy *incoming to
  a local merged value before mutation, closing the TOCTOU window between
  store.Get and store.Put under concurrent pushes
- cClusterConfQueues and cClusterConfResources gain nil-pointer guards
  matching the existing guard in cClusterConfHostConfigs
- handleConfigPush gains an explicit gHandler nil check
- cClusterConfToClusterInfo returns nil on empty clustername (prevents phantom
  empty-key write to store.Clusters); handleConfigPush logs a warning when nil
- 36 unit tests passing (CGO_ENABLED=0)
This commit is contained in:
Rongsong Shen 2026-04-16 11:25:03 +00:00
parent 00c4472d6c
commit 893812e7aa
8 changed files with 850 additions and 11 deletions

View file

@ -213,6 +213,9 @@ func handleDataset(d *C.dataset_t) C.int {
// handleConfigPush processes a cluster configuration push.
func handleConfigPush(cfgdata *C.xce_configdata_t) C.int {
if gHandler == nil {
return 0
}
if cfgdata.data_which != C.ConfigData_data_clusterconfig {
return 0
}
@ -222,14 +225,16 @@ func handleConfigPush(cfgdata *C.xce_configdata_t) C.int {
return 0
}
for _, q := range cClusterConfQueues(conf) {
qi := q
gHandler.OnQueueUpdated(&qi)
}
for _, r := range cClusterConfResources(conf) {
ri := r
gHandler.OnResourceUpdated(&ri)
cluster := cClusterConfToClusterInfo(conf)
if cluster == nil {
logger.Warn("handleConfigPush: cluster_config_t has empty clustername; skipping OnClusterUpdated")
}
dispatchConfigPush(gHandler,
cClusterConfQueues(conf),
cClusterConfResources(conf),
cClusterConfHostConfigs(conf),
cluster,
)
return 0
}