feat: P1-1 handle resource value push via OPCode_notify
Add OPCode_notify handler in go_push_handler top-level switch (not inside handlePush) to receive resource value updates from the controller via xce_notify_data_t/schedUpdateResvals. - Add 8 CGO union accessors for xce_val_t (which, i32, i64, u32, u64, fval, str, bool) since CGO cannot access union fields - Add handleNotifyData() dispatching NotifyData_data_schedUpdateResvals events, iterating xce_resval_list_t and calling cResvalToDistribution - Add cResvalToDistribution in convert.go with 7 separate switch cases for Value_u_* union discriminants (no combining i32/i64) - Add rawResvalData + rawResvalToDistribution pure-Go version in convert_pure.go for testability without CGO - Add 10 TDD tests covering all 7 value types, nil val guard, unknown discriminant, and boolean false - All 42 backend tests passing
This commit is contained in:
parent
dc029a6d14
commit
bc3103a6d5
5 changed files with 365 additions and 23 deletions
|
|
@ -13,16 +13,16 @@ import (
|
|||
const (
|
||||
nTagBits = 2
|
||||
tagShift = 62
|
||||
nClusterIDBits = 6
|
||||
clusterIDShift = 56
|
||||
nApiserverIDBits = 4
|
||||
apiserverIDShift = 52
|
||||
nTimestampBits = 32
|
||||
timestampShift = 20
|
||||
nArrayIdxBits = 15
|
||||
sequenceHighShift = 15 // mirrors SEQUENCE_HIGH_SHIFT in config.h
|
||||
nSequenceBits = 30 // mirrors N_SEQUENCE_BITS in config.h
|
||||
tagJobArray = 0x01 // mirrors TAG_JOB_ARRAY in config.h
|
||||
nClusterIDBits = 6
|
||||
clusterIDShift = 56
|
||||
nApiserverIDBits = 4
|
||||
apiserverIDShift = 52
|
||||
nTimestampBits = 32
|
||||
timestampShift = 20
|
||||
nArrayIdxBits = 15
|
||||
sequenceHighShift = 15 // mirrors SEQUENCE_HIGH_SHIFT in config.h
|
||||
nSequenceBits = 30 // mirrors N_SEQUENCE_BITS in config.h
|
||||
tagJobArray = 0x01 // mirrors TAG_JOB_ARRAY in config.h
|
||||
)
|
||||
|
||||
// extractBits extracts a bit field from id at the given shift position.
|
||||
|
|
@ -260,14 +260,70 @@ func rawHostConfigToModel(r rawHostConfigData) *models.HostInfo {
|
|||
}
|
||||
}
|
||||
|
||||
// rawResvalData mirrors the C xce_resval_t fields used by the Go model.
|
||||
// IsDynamic is always true for push-sourced values (controller sends live measurements).
|
||||
type rawResvalData struct {
|
||||
name string
|
||||
host string
|
||||
valWhich int // mirrors C xce_val_t.which (Value_u_* discriminant)
|
||||
i32 int32
|
||||
i64 int64
|
||||
u32 uint32
|
||||
u64 uint64
|
||||
fval float64
|
||||
sval string
|
||||
bval bool
|
||||
valNil bool // true when the C xce_val_t* was NULL
|
||||
}
|
||||
|
||||
// rawResvalToDistribution maps a rawResvalData to a models.ResourceDistributionInfo.
|
||||
// Returns nil when valNil is true (C val pointer was NULL) or when valWhich
|
||||
// is an unknown discriminant — callers should skip nil results.
|
||||
func rawResvalToDistribution(r rawResvalData) *models.ResourceDistributionInfo {
|
||||
rd := &models.ResourceDistributionInfo{
|
||||
ResourceName: r.name,
|
||||
Location: r.host,
|
||||
IsDynamic: true, // resource values pushed from workers are always dynamic
|
||||
}
|
||||
if r.valNil {
|
||||
return nil
|
||||
}
|
||||
switch r.valWhich {
|
||||
case 0: // Value_u_ivalue32
|
||||
rd.ValueType = int(models.NUMERIC)
|
||||
rd.NumericValue = float64(r.i32)
|
||||
case 2: // Value_u_ivalue64
|
||||
rd.ValueType = int(models.NUMERIC)
|
||||
rd.NumericValue = float64(r.i64)
|
||||
case 1: // Value_u_uvalue32
|
||||
rd.ValueType = int(models.NUMERIC)
|
||||
rd.NumericValue = float64(r.u32)
|
||||
case 3: // Value_u_uvalue64
|
||||
rd.ValueType = int(models.NUMERIC)
|
||||
rd.NumericValue = float64(r.u64)
|
||||
case 5: // Value_u_fvalue
|
||||
rd.ValueType = int(models.NUMERIC)
|
||||
rd.NumericValue = r.fval
|
||||
case 4: // Value_u_svalue
|
||||
rd.ValueType = int(models.STRING)
|
||||
rd.StringValue = r.sval
|
||||
case 6: // Value_u_bvalue
|
||||
rd.ValueType = int(models.BOOLEAN)
|
||||
rd.BooleanValue = r.bval
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
return rd
|
||||
}
|
||||
|
||||
// rawClusterData mirrors the C cluster_config_t fields used by the Go model.
|
||||
// Only config-sourced fields are included (heartbeat_interval, vcpus, inactive_heartbeat_count).
|
||||
// Built-in/sourced fields (Version, Status, ControllerName, etc.) come from LoadBuiltinData
|
||||
// and are not part of the config push conversion.
|
||||
type rawClusterData struct {
|
||||
name string
|
||||
heartbeatInterval int
|
||||
vcpus int
|
||||
heartbeatInterval int
|
||||
vcpus int
|
||||
inactiveHeartbeatCount int
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue