Fix targetpool iteration deadlock.

This commit is contained in:
Julius Volz 2013-02-21 19:48:29 +01:00
parent a4e2ccf680
commit 3537edee9f
2 changed files with 30 additions and 3 deletions

View file

@ -90,7 +90,11 @@ func (p *TargetPool) runIteration(results chan format.Result, interval time.Dura
if target.scheduledFor().After(now) { if target.scheduledFor().After(now) {
heap.Push(p, target) heap.Push(p, target)
// None of the remaining targets are ready to be scheduled. Signal that
// we're done processing them in this scrape iteration.
for j := i; j < targetCount; j++ {
finished <- true
}
break break
} }
@ -107,6 +111,6 @@ func (p *TargetPool) runIteration(results chan format.Result, interval time.Dura
close(finished) close(finished)
duration := float64(time.Now().Sub(begin) / time.Millisecond) duration := float64(time.Since(begin) / time.Millisecond)
retrievalDurations.Add(map[string]string{intervalKey: interval.String()}, duration) retrievalDurations.Add(map[string]string{intervalKey: interval.String()}, duration)
} }

View file

@ -15,6 +15,7 @@ package retrieval
import ( import (
"container/heap" "container/heap"
"github.com/prometheus/prometheus/retrieval/format"
"github.com/prometheus/prometheus/utility/test" "github.com/prometheus/prometheus/utility/test"
"testing" "testing"
"time" "time"
@ -45,8 +46,8 @@ func testTargetPool(t test.Tester) {
var scenarios = []struct { var scenarios = []struct {
name string name string
outputs []output
inputs []input inputs []input
outputs []output
}{ }{
{ {
name: "empty", name: "empty",
@ -160,6 +161,28 @@ func TestTargetPool(t *testing.T) {
testTargetPool(t) testTargetPool(t)
} }
func TestTargetPoolIterationWithUnhealthyTargetsFinishes(t *testing.T) {
pool := TargetPool{}
target := &target{
address: "http://example.com/metrics.json",
scheduler: literalScheduler(time.Date(9999, 1, 1, 0, 0, 0, 0, time.UTC)),
}
pool.Push(target)
done := make(chan bool)
go func() {
pool.runIteration(make(chan format.Result), time.Duration(0))
done <- true
}()
select {
case <-done:
break
case <-time.After(time.Duration(1) * time.Second):
t.Fatalf("Targetpool iteration is stuck")
}
}
func BenchmarkTargetPool(b *testing.B) { func BenchmarkTargetPool(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
testTargetPool(b) testTargetPool(b)