Skip to content

Commit 2d29ae6

Browse files
committed
Better handling of unassignable targets / jobs
Signed-off-by: Matej Gera <[email protected]>
1 parent 082e678 commit 2d29ae6

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

cmd/otel-allocator/allocation/per_node.go

+23-6
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,29 @@ func (allocator *perNodeAllocator) handleTargets(diff diff.Changes[*target.Item]
178178
}
179179

180180
// Check for additions
181+
unassignedTargetsForJobs := make(map[string]struct{})
181182
for k, item := range diff.Additions() {
182183
// Do nothing if the item is already there
183184
if _, ok := allocator.targetItems[k]; ok {
184185
continue
185186
} else {
186187
// Add item to item pool and assign a collector
187-
allocator.addTargetToTargetItems(item)
188+
collectorAssigned := allocator.addTargetToTargetItems(item)
189+
if !collectorAssigned {
190+
unassignedTargetsForJobs[item.JobName] = struct{}{}
191+
}
192+
}
193+
}
194+
// Check for unassigned targets
195+
if len(unassignedTargetsForJobs) > 0 {
196+
jobs := make([]string, 0, len(unassignedTargetsForJobs))
197+
for j := range unassignedTargetsForJobs {
198+
jobs = append(jobs, j)
188199
}
200+
201+
allocator.log.Info("Could not assign targets for the following jobs due to missing node labels", "jobs", jobs)
189202
}
203+
190204
}
191205

192206
// addTargetToTargetItems assigns a target to the collector and adds it to the allocator's targetItems
@@ -195,18 +209,21 @@ func (allocator *perNodeAllocator) handleTargets(diff diff.Changes[*target.Item]
195209
// INVARIANT: allocator.collectors must have at least 1 collector set.
196210
// NOTE: by not creating a new target item, there is the potential for a race condition where we modify this target
197211
// item while it's being encoded by the server JSON handler.
198-
// Also, any targets that cannot be assigned to a collector due to no matching node name will be dropped.
199-
func (allocator *perNodeAllocator) addTargetToTargetItems(tg *target.Item) {
212+
// Also, any targets that cannot be assigned to a collector, due to no matching node name, will remain unassigned. These
213+
// targets are still "silently" added to the targetItems map, to prevent them from being reported as unassigned on each new
214+
// target items setting.
215+
func (allocator *perNodeAllocator) addTargetToTargetItems(tg *target.Item) bool {
216+
allocator.targetItems[tg.Hash()] = tg
200217
chosenCollector := allocator.findCollector(tg.Labels)
201218
if chosenCollector == nil {
202219
allocator.log.V(2).Info("Couldn't find a collector for the target item", "item", tg, "collectors", allocator.collectors)
203-
return
220+
return false
204221
}
205222
tg.CollectorName = chosenCollector.Name
206-
allocator.targetItems[tg.Hash()] = tg
207223
allocator.addCollectorTargetItemMapping(tg)
208224
chosenCollector.NumTargets++
209-
TargetsPerCollector.WithLabelValues(chosenCollector.Name, leastWeightedStrategyName).Set(float64(chosenCollector.NumTargets))
225+
TargetsPerCollector.WithLabelValues(chosenCollector.Name, perNodeStrategyName).Set(float64(chosenCollector.NumTargets))
226+
return true
210227
}
211228

212229
// findCollector finds the collector that matches the node of the target, on the basis of the

cmd/otel-allocator/allocation/per_node_test.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,23 @@ func TestAllocationPerNode(t *testing.T) {
6262
actualItems := s.TargetItems()
6363

6464
// one target should be skipped
65-
expectedTargetLen := len(targetList) - 1
65+
expectedTargetLen := len(targetList)
6666
assert.Len(t, actualItems, expectedTargetLen)
6767

6868
// verify allocation to nodes
6969
for targetHash, item := range targetList {
7070
actualItem, found := actualItems[targetHash]
7171
// if third target, should be skipped
72-
if targetHash != thirdTarget.Hash() {
73-
assert.True(t, found, "target with hash %s not found", item.Hash())
74-
} else {
75-
assert.False(t, found, "target with hash %s should not be found", item.Hash())
76-
return
77-
}
72+
assert.True(t, found, "target with hash %s not found", item.Hash())
7873

74+
// only the first two targets should be allocated
7975
itemsForCollector := s.GetTargetsForCollectorAndJob(actualItem.CollectorName, actualItem.JobName)
76+
77+
// first two should be assigned one to each collector; if third target, should not be assigned
78+
if targetHash == thirdTarget.Hash() {
79+
assert.Len(t, itemsForCollector, 0)
80+
continue
81+
}
8082
assert.Len(t, itemsForCollector, 1)
8183
assert.Equal(t, actualItem, itemsForCollector[0])
8284
}

0 commit comments

Comments
 (0)