in internal/pkg/agent/application/coordinator/coordinator.go [1619:1749]
func (c *Coordinator) checkAndLogUpdate(lastComponentModel []component.Component) {
if lastComponentModel == nil {
c.logger.Debugf("Received initial component update; total of %d components", len(c.componentModel))
return
}
type compCheck struct {
inCurrent bool
inLast bool
diffUnits map[string]diffCheck
}
lastCompMap := convertComponentListToMap(lastComponentModel)
currentCompMap := convertComponentListToMap(c.componentModel)
compDiffMap := map[string]compCheck{}
outDiffMap := map[string]diffCheck{}
// kinda-callbacks for dealing with output logic
foundInLast := func(outName string) {
if outDiff, ok := outDiffMap[outName]; ok {
outDiff.inLast = true
outDiffMap[outName] = outDiff
} else {
outDiffMap[outName] = diffCheck{inLast: true}
}
}
foundInUpdated := func(outName string) {
if outDiff, ok := outDiffMap[outName]; ok {
outDiff.inNew = true
outDiffMap[outName] = outDiff
} else {
outDiffMap[outName] = diffCheck{inNew: true}
}
}
// diff the maps
// find added & updated components
for id, comp := range currentCompMap {
// check output
foundInUpdated(comp.OutputType)
// compare with last state
diff := compCheck{inCurrent: true}
if lastComp, ok := lastCompMap[id]; ok {
diff.inLast = true
// if the unit is in both the past and previous, check for updated units
diff.diffUnits = diffUnitList(lastComp.Units, comp.Units)
foundInLast(lastComp.OutputType)
// a bit of optimization: after we're done, we'll need to iterate over lastCompMap to fetch removed units,
// so delete items we don't need to iterate over
delete(lastCompMap, id)
}
compDiffMap[id] = diff
}
// find removed components
// if something is still in this map, that means it's only in this map
for id, comp := range lastCompMap {
compDiffMap[id] = compCheck{inLast: true}
foundInLast(comp.OutputType)
}
addedList := []string{}
removedList := []string{}
formattedUpdated := []string{}
// reduced to list of added/removed outputs
addedOutputs := []string{}
removedOutputs := []string{}
// take our diff map and format everything for output
for id, diff := range compDiffMap {
if diff.inLast && !diff.inCurrent {
removedList = append(removedList, id)
}
if !diff.inLast && diff.inCurrent {
addedList = append(addedList, id)
}
// format a user-readable list of diffs
if diff.inLast && diff.inCurrent {
units := []string{}
for unitId, state := range diff.diffUnits {
action := ""
if state.inLast && !state.inNew {
action = "removed"
}
if state.inNew && !state.inLast {
action = "added"
}
if state.updated {
action = "updated"
}
if action != "" {
units = append(units, fmt.Sprintf("(%s: %s)", unitId, action))
}
}
if len(units) > 0 {
formatted := fmt.Sprintf("%s: %v", id, units)
formattedUpdated = append(formattedUpdated, formatted)
}
}
}
// format outputs
for output, comp := range outDiffMap {
if comp.inLast && !comp.inNew {
removedOutputs = append(removedOutputs, output)
}
if !comp.inLast && comp.inNew {
addedOutputs = append(addedOutputs, output)
}
}
logStruct := UpdateStats{
Components: UpdateComponentChange{
Added: addedList,
Removed: removedList,
Count: len(c.componentModel),
Updated: formattedUpdated,
},
Outputs: UpdateComponentChange{
Added: addedOutputs,
Removed: removedOutputs,
},
}
c.logger.Infow("component model updated", "changes", logStruct)
}