in pkg/component/runtime/state.go [275:382]
func (s *ComponentState) syncCheckin(checkin *proto.CheckinObserved) bool {
changed := false
if s.Pid != checkin.Pid {
changed = true
s.Pid = checkin.Pid
}
touched := make(map[ComponentUnitKey]bool)
for _, unit := range checkin.Units {
key := ComponentUnitKey{
UnitType: client.UnitType(unit.Type),
UnitID: unit.Id,
}
var payload map[string]interface{}
if unit.Payload != nil {
payload = unit.Payload.AsMap()
}
touched[key] = true
_, inExpected := s.expectedUnits[key]
existing := s.Units[key]
existing.unitState = client.UnitState(unit.State)
existing.unitMessage = unit.Message
existing.unitPayload = payload
existing.configStateIdx = unit.ConfigStateIdx
if existing.err != nil && existing.unitState != client.UnitStateStopped {
errMsg := existing.err.Error()
if existing.State != client.UnitStateFailed || existing.Message != errMsg || diffPayload(existing.Payload, nil) {
changed = true
existing.State = client.UnitStateFailed
existing.Message = errMsg
existing.Payload = nil
}
} else if !inExpected && existing.unitState != client.UnitStateStopped {
if existing.State != client.UnitStateFailed || existing.Message != unknownMsg || diffPayload(existing.Payload, nil) {
changed = true
existing.State = client.UnitStateFailed
existing.Message = unknownMsg
existing.Payload = nil
}
} else {
if existing.unitState != existing.State || existing.unitMessage != existing.Message || diffPayload(existing.unitPayload, existing.Payload) {
changed = true
existing.State = existing.unitState
existing.Message = existing.unitMessage
existing.Payload = existing.unitPayload
}
}
s.Units[key] = existing
}
for key, unit := range s.Units {
// Look for units that weren't in the checkin.
if _, ok := touched[key]; ok {
continue
}
unit.unitState = client.UnitStateStarting
unit.unitMessage = ""
unit.unitPayload = nil
unit.configStateIdx = 0
if unit.err != nil {
errMsg := unit.err.Error()
if unit.State != client.UnitStateFailed || unit.Message != errMsg || diffPayload(unit.Payload, nil) {
changed = true
unit.State = client.UnitStateFailed
unit.Message = errMsg
unit.Payload = nil
}
} else if unit.State != client.UnitStateStarting && unit.State != client.UnitStateStopped {
if unit.State != client.UnitStateFailed || unit.Message != missingMsg || diffPayload(unit.Payload, nil) {
changed = true
unit.State = client.UnitStateFailed
unit.Message = missingMsg
unit.Payload = nil
}
}
s.Units[key] = unit
}
if checkin.VersionInfo != nil {
if checkin.VersionInfo.Name != "" && s.VersionInfo.Name != checkin.VersionInfo.Name {
s.VersionInfo.Name = checkin.VersionInfo.Name
changed = true
}
if checkin.VersionInfo.BuildHash != "" && s.VersionInfo.BuildHash != checkin.VersionInfo.BuildHash {
s.VersionInfo.BuildHash = checkin.VersionInfo.BuildHash
changed = true
}
if checkin.VersionInfo.Meta != nil && diffMeta(s.VersionInfo.Meta, checkin.VersionInfo.Meta) {
s.VersionInfo.Meta = checkin.VersionInfo.Meta
changed = true
}
}
if s.FeaturesIdx != checkin.FeaturesIdx {
s.FeaturesIdx = checkin.FeaturesIdx
changed = true
}
if s.ComponentIdx != checkin.ComponentIdx {
s.ComponentIdx = checkin.ComponentIdx
changed = true
}
return changed
}