diff --git a/pkg/ring/model.go b/pkg/ring/model.go index 047b3f8acd3..2055b20854d 100644 --- a/pkg/ring/model.go +++ b/pkg/ring/model.go @@ -182,12 +182,20 @@ func (d *Desc) TokensFor(id string) (tokens, other []uint32) { // IsHealthy checks whether the ingester appears to be alive and heartbeating func (i *IngesterDesc) IsHealthy(op Operation, heartbeatTimeout time.Duration) bool { - if op == Write && i.State != ACTIVE { - return false - } else if op == Read && i.State == JOINING { - return false + healthy := false + + switch op { + case Write: + healthy = (i.State == ACTIVE) + + case Read: + healthy = (i.State == ACTIVE) || (i.State == LEAVING) || (i.State == PENDING) + + case Reporting: + healthy = true } - return time.Now().Sub(time.Unix(i.Timestamp, 0)) <= heartbeatTimeout + + return healthy && time.Now().Sub(time.Unix(i.Timestamp, 0)) <= heartbeatTimeout } // Merge merges other ring into this one. Returns sub-ring that represents the change, diff --git a/pkg/ring/model_test.go b/pkg/ring/model_test.go index fb235f1e63c..4a8c1ef626c 100644 --- a/pkg/ring/model_test.go +++ b/pkg/ring/model_test.go @@ -11,34 +11,39 @@ func TestIngesterDesc_IsHealthy(t *testing.T) { t.Parallel() tests := map[string]struct { - ingester *IngesterDesc - timeout time.Duration - writeExpected bool - readExpected bool + ingester *IngesterDesc + timeout time.Duration + writeExpected bool + readExpected bool + reportExpected bool }{ "ALIVE ingester with last keepalive newer than timeout": { - ingester: &IngesterDesc{State: ACTIVE, Timestamp: time.Now().Add(-30 * time.Second).Unix()}, - timeout: time.Minute, - writeExpected: true, - readExpected: true, + ingester: &IngesterDesc{State: ACTIVE, Timestamp: time.Now().Add(-30 * time.Second).Unix()}, + timeout: time.Minute, + writeExpected: true, + readExpected: true, + reportExpected: true, }, "ALIVE ingester with last keepalive older than timeout": { - ingester: &IngesterDesc{State: ACTIVE, Timestamp: time.Now().Add(-90 * time.Second).Unix()}, - timeout: time.Minute, - writeExpected: false, - readExpected: false, + ingester: &IngesterDesc{State: ACTIVE, Timestamp: time.Now().Add(-90 * time.Second).Unix()}, + timeout: time.Minute, + writeExpected: false, + readExpected: false, + reportExpected: false, }, "JOINING ingester with last keepalive newer than timeout": { - ingester: &IngesterDesc{State: JOINING, Timestamp: time.Now().Add(-30 * time.Second).Unix()}, - timeout: time.Minute, - writeExpected: false, - readExpected: false, + ingester: &IngesterDesc{State: JOINING, Timestamp: time.Now().Add(-30 * time.Second).Unix()}, + timeout: time.Minute, + writeExpected: false, + readExpected: false, + reportExpected: true, }, "LEAVING ingester with last keepalive newer than timeout": { - ingester: &IngesterDesc{State: LEAVING, Timestamp: time.Now().Add(-30 * time.Second).Unix()}, - timeout: time.Minute, - writeExpected: false, - readExpected: true, + ingester: &IngesterDesc{State: LEAVING, Timestamp: time.Now().Add(-30 * time.Second).Unix()}, + timeout: time.Minute, + writeExpected: false, + readExpected: true, + reportExpected: true, }, } @@ -51,6 +56,9 @@ func TestIngesterDesc_IsHealthy(t *testing.T) { actual = testData.ingester.IsHealthy(Read, testData.timeout) assert.Equal(t, testData.readExpected, actual) + + actual = testData.ingester.IsHealthy(Reporting, testData.timeout) + assert.Equal(t, testData.reportExpected, actual) }) } }