playground: bound compilation time too
We already limited execution time.
Change-Id: I4cdf0178e08632ad25e4a7c5d6d63a9a00131e31
Reviewed-on: https://go-review.googlesource.com/c/playground/+/194601
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
diff --git a/README.md b/README.md
index fe6ac19..5ee85f9 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
## Running
```bash
-docker run --name=play --rm -d -p 8080:8080 playground
+docker run --name=play --rm -p 8080:8080 golang/playground &
# run some Go code
cat /path/to/code.go | go run client.go | curl -s --upload-file - localhost:8080/compile
```
diff --git a/sandbox.go b/sandbox.go
index f43eb07..7b6909f 100644
--- a/sandbox.go
+++ b/sandbox.go
@@ -34,16 +34,23 @@
)
const (
- maxRunTime = 2 * time.Second
+ maxCompileTime = 5 * time.Second
+ maxRunTime = 2 * time.Second
// progName is the implicit program name written to the temp
// dir and used in compiler and vet errors.
progName = "prog.go"
)
+const goBuildTimeoutError = "timeout running go build"
+
// Responses that contain these strings will not be cached due to
// their non-deterministic nature.
-var nonCachingErrors = []string{"out of memory", "cannot allocate memory"}
+var nonCachingErrors = []string{
+ "out of memory",
+ "cannot allocate memory",
+ goBuildTimeoutError,
+}
type request struct {
Body string
@@ -363,7 +370,10 @@
exe := filepath.Join(tmpDir, "a.out")
goCache := filepath.Join(tmpDir, "gocache")
- cmd := exec.Command("go", "build", "-o", exe, buildPkgArg)
+
+ ctx, cancel := context.WithTimeout(context.Background(), maxCompileTime)
+ defer cancel()
+ cmd := exec.CommandContext(ctx, "go", "build", "-o", exe, buildPkgArg)
cmd.Dir = tmpDir
var goPath string
cmd.Env = []string{"GOOS=nacl", "GOARCH=amd64p32", "GOCACHE=" + goCache}
@@ -381,7 +391,12 @@
cmd.Env = append(cmd.Env, "GO111MODULE=off") // in case it becomes on by default later
}
cmd.Env = append(cmd.Env, "GOPATH="+goPath)
+ t0 := time.Now()
if out, err := cmd.CombinedOutput(); err != nil {
+ if ctx.Err() == context.DeadlineExceeded {
+ log.Printf("go build timed out after %v", time.Since(t0))
+ return &response{Errors: goBuildTimeoutError}, nil
+ }
if _, ok := err.(*exec.ExitError); ok {
// Return compile errors to the user.
@@ -396,7 +411,7 @@
}
return nil, fmt.Errorf("error building go source: %v", err)
}
- ctx, cancel := context.WithTimeout(context.Background(), maxRunTime)
+ ctx, cancel = context.WithTimeout(context.Background(), maxRunTime)
defer cancel()
cmd = exec.CommandContext(ctx, "sel_ldr_x86_64", "-l", "/dev/null", "-S", "-e", exe, testParam)
rec := new(Recorder)