diff --git a/server/backend.go b/server/backend.go index cc80ea3a..871d5b76 100644 --- a/server/backend.go +++ b/server/backend.go @@ -24,6 +24,12 @@ type I struct { IndexTime time.Time } +func (i *I) GetIndexTime() time.Time { + i.Lock() + defer i.Unlock() + return i.IndexTime +} + type Backend struct { Id string Addr string diff --git a/server/server.go b/server/server.go index cbfd83d5..f8db9188 100644 --- a/server/server.go +++ b/server/server.go @@ -201,14 +201,17 @@ func (s *server) ServeHelp(ctx context.Context, w http.ResponseWriter, r *http.R http.Redirect(w, r, "/search", 303) } +const MaxIndexAge = 3*time.Hour + 30*time.Minute + func (s *server) ServeHealthcheck(w http.ResponseWriter, r *http.Request) { - // All backends must have (at some point) reported an index age for us to - // report as healthy. - // TODO: report as unhealthy if a backend goes down after we've spoken to - // it. for _, bk := range s.bk { - if bk.I.IndexTime.IsZero() { - http.Error(w, fmt.Sprintf("unhealthy backend '%s' '%s'\n", bk.Id, bk.Addr), 500) + indexTime := bk.I.GetIndexTime() + if indexTime.IsZero() { + http.Error(w, fmt.Sprintf("unhealthy backend '%s' '%s': no index loaded\n", bk.Id, bk.Addr), 500) + return + } + if age := time.Since(indexTime); age > MaxIndexAge { + http.Error(w, fmt.Sprintf("unhealthy backend '%s' '%s': index is %v old\n", bk.Id, bk.Addr, age.Truncate(time.Second)), 500) return } } @@ -224,11 +227,12 @@ func (s *server) ServeStats(ctx context.Context, w http.ResponseWriter, r *http. now := time.Now() maxBkAge := time.Duration(-1) * time.Second for _, bk := range s.bk { - if bk.I.IndexTime.IsZero() { + indexTime := bk.I.GetIndexTime() + if indexTime.IsZero() { // backend didn't report index time continue } - bkAge := now.Sub(bk.I.IndexTime) + bkAge := now.Sub(indexTime) if bkAge > maxBkAge { maxBkAge = bkAge }