cmd/buildlet: set GOPLSCACHE=$workdir/goplscache

Ordinarily, gopls processes live such long and idle lives that the
internal garbage collector for gopls' file-based cache can easily keep
up with the churn rate and maintain the shared cache at a reasonable
size. But tests burn twice as bright and half as long and, despite
various efforts, have tended to fill the cache volume; see the
attached Go issues.

This change causes the buildlet to set GOPLSCACHE to a fresh
subdirectory of the work dir for each builder run so that each is
cleaned up at the end of the run. This does mean that the tests don't
exercise the shared cache behavior, but the problems our tests
hitherto uncovered were not particularly representative of production.

Updates golang/go#57900
Updates golang/go#57902

Change-Id: I63e91dd873897eb3619929530bc3a75a16b96095
Reviewed-on: https://go-review.googlesource.com/c/build/+/494297
Run-TryBot: Alan Donovan <adonovan@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/cmd/buildlet/buildlet.go b/cmd/buildlet/buildlet.go
index 2cd4ace..c9d5a70 100644
--- a/cmd/buildlet/buildlet.go
+++ b/cmd/buildlet/buildlet.go
@@ -83,7 +83,8 @@
 //	24: removeAllIncludingReadonly
 //	25: use removeAllIncludingReadonly for all work area cleanup
 //	26: clean up path validation and normalization
-const buildletVersion = 26
+//	27: export GOPLSCACHE=$workdir/goplscache
+const buildletVersion = 27
 
 func defaultListenAddr() string {
 	if runtime.GOOS == "darwin" {
@@ -110,11 +111,12 @@
 	setOSRlimit              func() error
 )
 
-// If non-empty, the $TMPDIR and $GOCACHE environment variables to use
-// for child processes.
+// If non-empty, the $TMPDIR, $GOCACHE, and $GOPLSCACHE environment
+// variables to use for child processes.
 var (
-	processTmpDirEnv  string
-	processGoCacheEnv string
+	processTmpDirEnv     string
+	processGoCacheEnv    string
+	processGoplsCacheEnv string
 )
 
 const (
@@ -210,9 +212,13 @@
 	// Set up and clean $TMPDIR and $GOCACHE directories.
 	if runtime.GOOS != "plan9" { // go.dev/cl/207283 seems to indicate plan9 should work, but someone needs to test it.
 		processTmpDirEnv = filepath.Join(*workDir, "tmp")
-		processGoCacheEnv = filepath.Join(*workDir, "gocache")
 		removeAllAndMkdir(processTmpDirEnv)
+
+		processGoCacheEnv = filepath.Join(*workDir, "gocache")
 		removeAllAndMkdir(processGoCacheEnv)
+
+		processGoplsCacheEnv = filepath.Join(*workDir, "goplscache")
+		removeAllAndMkdir(processGoplsCacheEnv)
 	}
 
 	http.HandleFunc("/", handleRoot)
@@ -856,11 +862,11 @@
 		http.Error(w, "HTTP/1.1 or higher required", http.StatusBadRequest)
 		return
 	}
-	// Create *workDir and (if needed) tmp and gocache.
+	// Create *workDir and any needed temporary subdirectories.
 	if !mkdirAllWorkdirOr500(w) {
 		return
 	}
-	for _, dir := range []string{processTmpDirEnv, processGoCacheEnv} {
+	for _, dir := range []string{processTmpDirEnv, processGoCacheEnv, processGoplsCacheEnv} {
 		if dir == "" {
 			continue
 		}
@@ -912,6 +918,9 @@
 	if v := processGoCacheEnv; v != "" {
 		env = append(env, "GOCACHE="+v)
 	}
+	if v := processGoplsCacheEnv; v != "" {
+		env = append(env, "GOPLSCACHE="+v)
+	}
 	if path := r.PostForm["path"]; len(path) > 0 {
 		if kv, ok := pathEnv(runtime.GOOS, env, path, *workDir); ok {
 			env = append(env, kv)