-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/tools/gopls: add support for multiple concurrent clients #34111
Comments
Thank you for filing a gopls issue! Please take a look at the Troubleshooting section of the gopls Wiki page, and make sure that you have provided all of the relevant information here. |
@gopherbot, please add label FeatureRequest |
In its default state gopls supports a specific header based JSON stream of the LSP on stdin /stdout. In this mode it only supports a single client as stdin/stdout cannot be multiplexed. It also has the flags The protocol spoken between a -remote and -listen gopls is not defined, and never will be, we only support it as a way of intercommunication, not as an API surface. This is because to achieve some of its goals it will have to have significant extensions to the protocol, and may mutate some of the data on the way through. Part of the reason for this is that it should be feasible to have the server run on a separate machine, and it may not have access to the same file system, or it may know the files by different absolute paths etc. These features require a reliable way of translating paths, and also the remote file extension so the true server can ask the intermediary gopls for file contents. It may also be necessary to have some forms of caching and cancelling within the intermediary. The current state is that we use this mode only for debugging. It only gets fixed when we need to use it to debug a problem, and even then it does not get properly fixed. It does mostly work, but there are things like straight proxying of shutdown message causes the shared server to quit when any of clients does. There are also design issues still to fix, things like should we support some kind of "discovery" protocol, should we have a mode where we start a server if one is not running but connect to it if it is, when all the clients go away should the server shut down again, how do we manage the cache so we dont explode because of lots of clients over a very long time, how do we prevent one client from starving the others, how do we manage the config and environment of the server correctly etc |
Thanks for this detail.
Understood. For editors like Vim, Emacs, etc, where users end up starting multiple instances on the same machine having a single instance of Given that, do you have plans to fully support this mode? |
Yes, but I have no time to do anything about it right now. |
Ok, understood. My question was more geared towards ensuring this is something that is being considered as opposed to not. |
I am just being really careful to make sure people do not think I will get round to it any time soon, I don't want someone waiting on it and getting frustrated that I am not doing it! This is also an area where contributions would be welcome, although it would be a very high touch contribution as I have a lot to say about how it is done :) |
Just to add another motivating factor behind this change: having a single instance will amortise the additional cost of running |
Just to update, since this was discussed in slack: I'm working on this now, and should have some progress soon. |
Change https://golang.org/cl/214803 mentions this issue: |
When debugging multiple instances of gopls simultaneously, it is useful to be able to inspect stateful debugging information for each server instance, such as the location of logfiles and server startup information. This CL adds an additional section to the /info http handler, that formats additional information related to the gopls instance handling the request. Updates golang/go#34111 Change-Id: I6cb8073800ce52b0645f1898461a19e1ac980d2b Reviewed-on: https://go-review.googlesource.com/c/tools/+/214803 Reviewed-by: Rebecca Stambler <[email protected]> Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
@findleyr is this a |
Oh, thanks. Yes, I think this can be added to the v1.0.0 milestone (the v0.3.0 feature set is pretty locked-down at the moment). I'll confirm with @stamblerre. |
Change https://golang.org/cl/215739 mentions this issue: |
Change https://golang.org/cl/215740 mentions this issue: |
The passed-in Context is not used, and creates the illusion of a startup dependency problem: existing code is careful to pass in the context containing the correct Client instance. This allows passing in a source.Session, rather than a source.Cache, into lsp server constructors. Updates golang/go#34111 Change-Id: I081ad6fa800b846b63e04d7164577e3a32966704 Reviewed-on: https://go-review.googlesource.com/c/tools/+/215740 Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]> Reviewed-by: Ian Cottrell <[email protected]>
A new test is added to verify that contextual logs are reflected back to the LSP client. In the future when we are considering servers with multiple clients, this test will be used to verify that client log exporting is scoped to the specific client session. Updates golang/go#34111. Change-Id: I29044e5355e25b81a759d064929520345230ea82 Reviewed-on: https://go-review.googlesource.com/c/tools/+/215739 Reviewed-by: Rebecca Stambler <[email protected]>
@myitcv you didn't miss anything: that configuration isn't yet exposed. In fact, that's the last change I have planned for this issue, at which point I think we should close this and open new, more specific issues as needed. I'd put off exposing configuration for the automatic daemon because I wasn't sure of what I wanted to do if the daemon is already running, but with different configuration parameters. For now I will expose just the following two pieces of configuration: Since neither of these affect serving, I think I'm NOT going to hash them into the daemon path as I do for build ID. This means that you may ask for It will be an error to set either of these flags without also setting I think that keeps things simple for now -- we can always revisit in the future if this causes problems (for example, a race between govim and ALE might cause unpredictable startup configuration). |
Change https://golang.org/cl/222669 mentions this issue: |
Change https://golang.org/cl/222670 mentions this issue: |
When running gopls as a forwarder it attempts to forward the LSP to a remote daemon. On posix systems, by default this uses a unix domain socket at a predictable filesystem location. As an extra precaution, attempt to verify that the remote socket is in fact owned by the current user. Also, change the default TCP listen address used on windows to bind to localhost. Updates golang/go#34111 Change-Id: Ib24886d290089a773851c5439586c3ddc9eb797d Reviewed-on: https://go-review.googlesource.com/c/tools/+/222246 Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]>
Change https://golang.org/cl/222671 mentions this issue: |
Change https://golang.org/cl/222717 mentions this issue: |
One thing I've noticed after doing a couple of Is |
Another thing I thought of: how does |
@zikaeroh that's interesting re:CPU during gopls upgrades. I would not expect that, I'll see if I can reproduce. The gopls forwarder starts the daemon with the same path as the forwarder itself. In other words, the sidecar gopls process uses its own path when starting the daemon. We can't use gopls from |
I didn't mean which |
Ah, sorry I misread your comment. You are right, it's possible that a change to the Perhaps we should hash the |
Of course, I see this becoming a slippery slope as I think there are other variables like |
Add a new toplevel `inspect` verb to the gopls command, to expose the internal state of a running gopls server. For now, this verb exposes a single subcommand `sessions`, which lists some information about current server sessions on a gopls daemon. This can be used even if the debug server is not running, which will become the default in a later CL. Updates golang/go#34111 Change-Id: Ib7d654a659fa47280584f9a7301b952cbccc565a Reviewed-on: https://go-review.googlesource.com/c/tools/+/222669 Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]>
Three new flags are added to the serve command, and threaded through to the LSP forwarder: -remote.listen.timeout: -listen.timeout for the auto-started daemon -remote.debug: -debug for the auto-started daemon -remote.logfile: -logfile for the auto-started daemon As part of this change, no longer enable debugging the daemon by default. Notably none of this configuration affects serving, so modifying this configuration has been chosen not to change the path to the automatic daemon. In other words, this configuration has effect only for the forwarder process that starts the daemon: all others will connect to the daemon and inherit whatever configuration it had at startup. This should be OK, because in the common case this configuration should be static across all clients (e.g., many Vim sessions all sharing the same .vimrc). Exposing this configuration made the signature of lsprpc.NewForwarder a bit hard to understand, so I decided to go ahead and switch to a variadic options pattern for initializing both the Forwarder and StreamServer, the latter just for consistency with the Forwarder. Updates golang/go#34111 Change-Id: Iefb71e337befe08b23e451477d19fd57e69f36c6 Reviewed-on: https://go-review.googlesource.com/c/tools/+/222670 Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]>
Previously it was an error to call shutdown while the server was not yet initialized. This can result in session leak for very short-lived sessions. Instead, allow shutdown to proceed and simply log the error. On the other hand, for consistency make it an error to call initialized without first calling initialize. Updates golang/go#34111 Change-Id: I0330d81323ddda6beec0f6ed9eb065f8b717dea0 Reviewed-on: https://go-review.googlesource.com/c/tools/+/222671 Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]>
Now that this issue is closed, should I be filing new issues for the |
I'm in the process of filing them now! You're too fast! |
As per discussion on Slack with @ianthehat & @myitcv this is a feature request for gopls to support multiple concurrent clients.
Vim users often have multiple instances of vim running at the same time, and starting/exiting is a natural part of the workflow. Currently there is a 1 to 1 mapping between vim and gopls (at least when using govim as plugin). It would be really useful to be able to share the same cache and avoid waiting for warmup each time.
See govim/govim#491 as well as #32750 (comment) for details.
The text was updated successfully, but these errors were encountered: