fix(lsp): buffer messages until connected to server (#28507)

`handle:write(msg)` can fail if the socket is not yet connected to the
server.

Should address https://github.com/neovim/neovim/pull/28398#issuecomment-2078152491
This commit is contained in:
Mathias Fußenegger 2024-04-26 09:57:59 +02:00 committed by GitHub
parent a736e845a4
commit 47dbda97d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -645,9 +645,23 @@ function M.connect(host_or_path, port)
or assert(uv.new_tcp(), 'Could not create new TCP socket')
)
local closing = false
-- Connect returns a PublicClient synchronously so the caller
-- can immediately send messages before the connection is established
-- -> Need to buffer them until that happens
local connected = false
-- size should be enough because the client can't really do anything until initialization is done
-- which required a response from the server - implying the connection got established
local msgbuf = vim.ringbuf(10)
local transport = {
write = function(msg)
handle:write(msg)
if connected then
local _, err = handle:write(msg)
if err and not closing then
log.error('Error on handle:write: %q', err)
end
else
msgbuf:push(msg)
end
end,
is_closing = function()
return closing
@ -679,6 +693,10 @@ function M.connect(host_or_path, port)
handle:read_start(M.create_read_loop(handle_body, transport.terminate, function(read_err)
client:on_error(M.client_errors.READ_ERROR, read_err)
end))
connected = true
for msg in msgbuf do
handle:write(msg)
end
end
if port == nil then
handle:connect(host_or_path, on_connect)