Skip to content

Commit

Permalink
indexserver: Wait for frontend to start (#30)
Browse files Browse the repository at this point in the history
This should stop the logspam we see when indexserver starts up faster than the
frontend pod.
  • Loading branch information
keegancsmith authored Oct 1, 2019
1 parent 320f79a commit fb5ac48
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
47 changes: 47 additions & 0 deletions cmd/zoekt-sourcegraph-indexserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"flag"
"fmt"
"html/template"
"io"
"io/ioutil"
"log"
"math"
Expand Down Expand Up @@ -95,6 +96,8 @@ func (s *Server) loggedRun(tr trace.Trace, cmd *exec.Cmd) error {

// Run the sync loop. This blocks forever.
func (s *Server) Run() {
waitForFrontend(s.Root)

queue := &Queue{}

// Start a goroutine which updates the queue with commits to index.
Expand Down Expand Up @@ -408,6 +411,50 @@ func resolveRevision(root *url.URL, repo, spec string) (string, error) {
return b.String(), nil
}

func ping(root *url.URL) error {
u := root.ResolveReference(&url.URL{Path: "/.internal/ping"})
resp, err := http.Get(u.String())
if err != nil {
return err
}

defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("ping: bad HTTP response status %d", resp.StatusCode)
}
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 16))
if err != nil {
return err
}
if want := []byte("pong"); !bytes.Equal(body, want) {
return fmt.Errorf("ping: bad HTTP response body %q (want %q)", string(body), string(want))
}
return nil
}

func waitForFrontend(root *url.URL) {
warned := false
lastWarn := time.Now()
for {
err := ping(root)
if err == nil {
break
}

if time.Since(lastWarn) > 15*time.Second {
warned = true
lastWarn = time.Now()
log.Printf("frontend API not reachable, will try again: %s", err)
}

time.Sleep(250 * time.Millisecond)
}

if warned {
log.Println("frontend API is now reachable. Starting indexing...")
}
}

func tarballURL(root *url.URL, repo, commit string) string {
return root.ResolveReference(&url.URL{Path: fmt.Sprintf("/.internal/git/%s/tar/%s", repo, commit)}).String()
}
Expand Down
46 changes: 46 additions & 0 deletions cmd/zoekt-sourcegraph-indexserver/main_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package main

import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"reflect"
"strings"
"testing"
"time"
)

func TestGetIndexOptions(t *testing.T) {
Expand Down Expand Up @@ -84,3 +87,46 @@ func TestListRepos(t *testing.T) {
t.Fatalf("unexpected request path. got %q, want %q", gotURL.Path, want)
}
}

func TestPing(t *testing.T) {
var response []byte
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/.internal/ping" {
http.Error(w, "not found", http.StatusNotFound)
return
}
_, _ = w.Write(response)
}))
defer server.Close()

root, err := url.Parse(server.URL)
if err != nil {
t.Fatal(err)
}

// Ping fails
response = []byte("hello")
err = ping(root)
if got, want := fmt.Sprintf("%v", err), "bad HTTP response body"; !strings.Contains(got, want) {
t.Errorf("wanted ping to fail,\ngot: %q\nwant: %q", got, want)
}

response = []byte("pong")
err = ping(root)
if err != nil {
t.Errorf("wanted ping to succeed, got: %v", err)
}

// We expect waitForFrontend to just work now
done := make(chan struct{})
go func() {
waitForFrontend(root)
close(done)
}()

select {
case <-done:
case <-time.After(5 * time.Second):
t.Fatal("waitForFrontend blocking")
}
}

0 comments on commit fb5ac48

Please sign in to comment.