Repository: go
Issue: x/tools/gopls: Shutdown does not interrupt current "work"
Labels: NeedsInvestigation,gopls,Tools

<!-- Please answer these questions before submitting your issue. Thanks! -->

### What version of Go are you using (`go version`)?

<pre>
$ go version
go version devel +135c9f45ec Wed Mar 31 04:13:44 2021 +0000 linux/amd64
$ go list -m golang.org/x/tools
golang.org/x/tools v0.1.1-0.20210330233337-8c34cc9cafff
$ go list -m golang.org/x/tools/gopls
golang.org/x/tools/gopls v0.0.0-20210330233337-8c34cc9cafff
</pre>

### Does this issue reproduce with the latest release?

Yes

### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/myitcv/.cache/go-build"
GOENV="/home/myitcv/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/myitcv/gostuff/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/myitcv/gostuff"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/myitcv/gos"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/myitcv/gos/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="devel +135c9f45ec Wed Mar 31 04:13:44 2021 +0000"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/myitcv/gostuff/src/github.com/myitcv/govim/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3492538628=/tmp/go-build -gno-record-gcc-switches"
</pre></details>

### What did you do?

A recent fix in `govim` means that when Vim shuts down, it triggers a shutdown sequence as follows:

1. User types `:q` (or equivalent) 
2. Vim send `govim` a `VimLeave` event, which fires before exiting Vim, and blocks on the processing of this event
3. `govim` does some of its own tidy up
4. `govim` calls the `gopls.Shutdown` method, blocking on its return
4. `govim` does some more tidying up before finally returning to Vim
5. With the `VimLeave` event now processed, Vim exits

This fix ensures that `govim` and `gopls` properly tidy up (temporary files) after themselves.

However, this appears to have highlighted an issue: that calling `Shutdown` does not interrupt existing "work" that `gopls` might be doing. Two things point to this being the case:

* Per https://github.com/golang/go/issues/41558#issuecomment-805733025, Vim does not exit until such time as the initial package load has completed (the `Shutdown` call appears to be blocked whilst the package load is happening)
* As reported by @mvdan on Slack, "work" triggered off the back of a file change "storm" also cannot be interrupted, i.e. Vim does not exit until all the file change notifications _and corresponding work_ have been handled.

As noted on Slack, in the case of the second issue there are many other issues at play, but it would still seem, like in the first case, desirable for `Shutdown` to be able to interrupt anything that `gopls` is doing.

For now we have a workaround in `govim`, to set a deadline of 500ms for the `Shutdown` call to be processed. The impact of this being that if the call to `Shutdown` exceed the deadline, `gopls`' temporary files (and other things?) are not tidied up. 

### What did you expect to see?

`Shutdown` being handled immediately, and not blocking on current "work".

### What did you see instead?

As above.

---

cc @stamblerre

FYI @leitzler @mvdan