diff --git a/scripts/speculator/README b/scripts/speculator/README index c54e0f2b..82dc3d36 100644 --- a/scripts/speculator/README +++ b/scripts/speculator/README @@ -6,9 +6,13 @@ It serves the following HTTP endpoints: - /diff/rst/123 which gives a diff of the spec's rst at pull request 123. - /diff/html/123 which gives a diff of the spec's HTML at pull request 123. -To run it, you must install the `go` tool, and run: +The build or run, you need a working `go` installation. +Then fetch dependencies: + ` go get github.com/hashicorp/golang-lru` + +To run it, then run: `go run main.go` To build the binary (which is necessary for deployment to the matrix.org -servers), you must again install `go`, and then run: +servers), you must again install `go` and dependencies, and then run: `go build` diff --git a/scripts/speculator/main.go b/scripts/speculator/main.go index e6992d4a..85fb2596 100644 --- a/scripts/speculator/main.go +++ b/scripts/speculator/main.go @@ -25,6 +25,8 @@ import ( "strings" "syscall" "time" + + "github.com/hashicorp/golang-lru" ) type PullRequest struct { @@ -53,6 +55,7 @@ type User struct { var ( port = flag.Int("port", 9000, "Port on which to listen for HTTP") allowedMembers map[string]bool + specCache *lru.Cache // string -> []byte ) func (u *User) IsTrusted() bool { @@ -196,6 +199,10 @@ func (s *server) serveSpec(w http.ResponseWriter, req *http.Request) { } sha = pr.Head.SHA } + if cached, ok := specCache.Get(sha); ok { + w.Write(cached.([]byte)) + return + } dst, err := s.generateAt(sha) defer os.RemoveAll(dst) @@ -210,6 +217,7 @@ func (s *server) serveSpec(w http.ResponseWriter, req *http.Request) { return } w.Write(b) + specCache.Add(sha, b) } func checkAuth(pr *PullRequest) error { @@ -367,6 +375,9 @@ func main() { "richvdh": true, "leonerd": true, } + if err := initCache(); err != nil { + log.Fatal(err) + } rand.Seed(time.Now().Unix()) masterCloneDir, err := gitClone(matrixDocCloneURL, false) if err != nil { @@ -388,3 +399,9 @@ func serveText(s string) func(http.ResponseWriter, *http.Request) { io.WriteString(w, s) } } + +func initCache() error { + c, err := lru.New(50) // Evict after 50 entries (i.e. 50 sha1s) + specCache = c + return err +}