gopls daemon process issue and solution suggestion

Skip to first unread message

Qi Wang

Sep 4, 2020, 10:00:04 AM9/4/20
to golang-tools
daemon process issue:
after install vim-go and coc.nvim and setup gopls correctly, I found there are two gopls daemon servers.

/go/bin/gopls serve -listen unix;/tmp/nvimPaFflp/gopls-0285b6-daemon.shared -listen.timeout 1m0s
/go/bin/gopls serve -listen unix;/tmp/gopls-0285b6-daemon.shared -listen.timeout 1m0s 21430

Root cause: vim-go and coc.nvim use different TMPDIR. for vim-go TMPDIR is "/tmp/" for coc.nvim TMPDIR is "/tmp/nvimPaFflp/". while gopls (autostart_posix.go) use os.TempDir() to to build the unix socket address. thus two daemon process appear.

solution suggestion:
the suggest solution is to change the gopls code. because os.TempDir() is very easy to be changed by others.

see this for the detail analysis.

Robert Findley

Sep 4, 2020, 12:41:02 PM9/4/20
to Qi Wang, golang-tools
Thanks for your investigation.  Another alternative is to manage the daemon manually, as described in, but I understand that's not ideal.

I can look into solutions on the gopls side.  Is there a specific gopls change that you would like to propose?

- Rob

You received this message because you are subscribed to the Google Groups "golang-tools" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
To view this discussion on the web visit

Qi Wang

Sep 5, 2020, 10:22:30 AM9/5/20
to golang-tools
the biggest application of language server (gopls) is for the IDE: vscode or vim/neovim. automatic gopls management is the right direction for those IDE. people always want simple and good thing. for vim-go or coc-go, manually  manage the language server will not be easy, it's even harder for other developers to use it. a lot of post on the github already prove that. 

I absolutely support the automatic daemon management. while keep the manually management available for some rare cases.

i am not very familiar with the gopls code. after investigated the vim-go, coc-go and coc.nvim for some time. i turned to gopls. it took me several days to understand the daemon related code. If i am familiar with the gopls code, a PR will appear. 

there is indeed an improvement I will propose:
  1. when edit a file, such as internal/lsp/lsprpc/lsprpc.go , 
  2. you see a  statement in line 289, "func connectToRemote":
    "network, address = autoNetworkAddress(goplsPath, inAddr)",
    now, to find the autoNetworkAddress func, you send a 'definition' query to the gopls server.
  3. in current implementation,  'definition' query will return the internal/lsp/lsprpc/autostart_default.go result. and the editor jump to that file without any choice. this implementation will mislead the developer. i checked the code several times and finally notice the 'build tags'
  4. the propose is to return the internal/lsp/lsprpc/autostart_posix.go , the behavior of 'definition' query should consider the 'build tags', in this case, it is "// +build darwin dragonfly freebsd linux netbsd openbsd solaris".
if you think my propose is needed. i will file an issue. maybe  a PR will appear. 

qi wang

Robert Findley

Sep 7, 2020, 7:05:08 PM9/7/20
to Qi Wang, golang-tools
Thanks, I do think this discussion is probably most suited for the issue tracker. I opened an issue for the daemon discovery / TMPDIR problem at

Regarding the particular example you mentioned (autostart_posix.go): this is not a case of multiple definitions, but rather a variable being overwritten based on build constraints.  This was done so that the list of build constraints is only maintained in one place.  But if it were the case of multiple definitions (which is a common pattern), you are right that gopls would not handle this very gracefully.  We have an open issue for this, which I think covers your request:

Qi Wang

Sep 8, 2020, 9:45:43 PM9/8/20
to golang-tools
I will check the

Reply all
Reply to author
0 new messages