forked from hound-search/hound
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request hound-search#297 from etsy/health-check
Add the ability to respond to health checks prior to indexes being built.
- Loading branch information
Showing
4 changed files
with
119 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package web | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"sync" | ||
|
||
"github.com/etsy/hound/api" | ||
"github.com/etsy/hound/config" | ||
"github.com/etsy/hound/searcher" | ||
"github.com/etsy/hound/ui" | ||
) | ||
|
||
// Server is an HTTP server that handles all | ||
// http traffic for hound. It is able to serve | ||
// some traffic before indexes are built and | ||
// then transition to all traffic afterwards. | ||
type Server struct { | ||
cfg *config.Config | ||
dev bool | ||
ch chan error | ||
|
||
mux *http.ServeMux | ||
lck sync.RWMutex | ||
} | ||
|
||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||
if r.URL.Path == s.cfg.HealthCheckURI { | ||
fmt.Fprintln(w, "👍") | ||
return | ||
} | ||
|
||
s.lck.RLock() | ||
defer s.lck.RUnlock() | ||
if m := s.mux; m != nil { | ||
m.ServeHTTP(w, r) | ||
} else { | ||
http.Error(w, | ||
"Hound is not ready.", | ||
http.StatusServiceUnavailable) | ||
} | ||
} | ||
|
||
func (s *Server) serveWith(m *http.ServeMux) { | ||
s.lck.Lock() | ||
defer s.lck.Unlock() | ||
s.mux = m | ||
} | ||
|
||
// Start creates a new server that will immediately start handling HTTP traffic. | ||
// The HTTP server will return 200 on the health check, but a 503 on every other | ||
// request until ServeWithIndex is called to begin serving search traffic with | ||
// the given searchers. | ||
func Start(cfg *config.Config, addr string, dev bool) *Server { | ||
ch := make(chan error) | ||
|
||
s := &Server{ | ||
cfg: cfg, | ||
dev: dev, | ||
ch: ch, | ||
} | ||
|
||
go func() { | ||
ch <- http.ListenAndServe(addr, s) | ||
}() | ||
|
||
return s | ||
} | ||
|
||
// ServeWithIndex allow the server to start offering the search UI and the | ||
// search APIs operating on the given indexes. | ||
func (s *Server) ServeWithIndex(idx map[string]*searcher.Searcher) error { | ||
h, err := ui.Content(s.dev, s.cfg) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
m := http.NewServeMux() | ||
m.Handle("/", h) | ||
api.Setup(m, idx) | ||
|
||
s.serveWith(m) | ||
|
||
return <-s.ch | ||
} |