Skip to content

Commit e246041

Browse files
authored
Carry over negative lookup in target cache. (#91)
1 parent 656cbaa commit e246041

File tree

2 files changed

+84
-5
lines changed

2 files changed

+84
-5
lines changed

targets/cache.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,29 @@ func (c *Cache) refresh(ctx context.Context) error {
108108
c.mtx.Lock()
109109
defer c.mtx.Unlock()
110110

111-
for _, t := range apiResp.Data.ActiveTargets {
112-
key := cacheKey(t.Labels.Get("job"), t.Labels.Get("instance"))
111+
for _, target := range apiResp.Data.ActiveTargets {
112+
key := cacheKey(target.Labels.Get("job"), target.Labels.Get("instance"))
113113

114114
// If the exact target already exists, reuse the same memory object.
115115
for _, prev := range c.targets[key] {
116-
if labelsEqual(t.Labels, prev.Labels) {
117-
t = prev
116+
if labelsEqual(target.Labels, prev.Labels) {
117+
target = prev
118118
break
119119
}
120120
}
121-
repl[key] = append(repl[key], t)
121+
repl[key] = append(repl[key], target)
122+
}
123+
124+
// If negative lookups still cannot be found in retrieved response,
125+
// the negative lookups should be carried over to the new cache, so when
126+
// Get is called, it won't aggressively call refresh() again.
127+
for key, target := range c.targets {
128+
if target != nil {
129+
continue
130+
}
131+
if _, ok := repl[key]; !ok {
132+
repl[key] = nil
133+
}
122134
}
123135

124136
c.targets = repl

targets/cache_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,73 @@ func TestTargetCache_Success(t *testing.T) {
205205
}
206206
}
207207

208+
func TestTargetCache_EmptyEntry(t *testing.T) {
209+
var handler func() []*Target
210+
211+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
212+
var resp apiResponse
213+
resp.Status = "success"
214+
resp.Data.ActiveTargets = handler()
215+
if err := json.NewEncoder(w).Encode(resp); err != nil {
216+
t.Fatal(err)
217+
}
218+
}))
219+
220+
ctx, cancel := context.WithCancel(context.Background())
221+
defer cancel()
222+
223+
u, err := url.Parse(ts.URL)
224+
if err != nil {
225+
t.Fatal(err)
226+
}
227+
228+
c := NewCache(nil, nil, u)
229+
// Initialize cache with negative-cached target.
230+
c.targets[cacheKey("job1", "instance-not-exists")] = nil
231+
232+
// No target in initial response.
233+
handler = func() []*Target {
234+
return []*Target{}
235+
}
236+
c.Get(ctx, labels.FromStrings("__name__", "metric1", "job", "job1", "instance", "instance1"))
237+
238+
// Empty entry should be kept in cache.
239+
val, ok := c.targets[cacheKey("job1", "instance-not-exists")]
240+
if !ok {
241+
t.Fatalf("Negative cache should be kept.")
242+
}
243+
if val != nil {
244+
t.Fatalf("Unexpected value job1/instance-not-exists: %v", val)
245+
}
246+
247+
// Create a new empty entry by querying job/instance pair not available.
248+
c.Get(ctx, labels.FromStrings("__name__", "metric2", "job", "job2", "instance", "instance-not-exists"))
249+
val, ok = c.targets[cacheKey("job2", "instance-not-exists")]
250+
if !ok {
251+
t.Fatalf("Negative cache should be kept.")
252+
}
253+
if val != nil {
254+
t.Fatalf("Unexpected value job2/instance-not-exists: %v", val)
255+
}
256+
257+
// Add a new instance into response, which will trigger replacing cache.
258+
handler = func() []*Target {
259+
return []*Target{
260+
{Labels: labels.FromStrings("job", "job1", "instance", "instance1")},
261+
}
262+
}
263+
c.Get(ctx, labels.FromStrings("__name__", "metric1", "job", "job1", "instance", "instance1"))
264+
265+
// Empty entry created should be kept in cache.
266+
val, ok = c.targets[cacheKey("job2", "instance-not-exists")]
267+
if !ok {
268+
t.Fatalf("Negative cache should be kept.")
269+
}
270+
if val != nil {
271+
t.Fatalf("Unexpected value job2/instance-not-exists: %v", val)
272+
}
273+
}
274+
208275
func TestDropTargetLabels(t *testing.T) {
209276
cases := []struct {
210277
series, target, result labels.Labels

0 commit comments

Comments
 (0)