Open skywind3000 opened 1 year ago
If the server sends a request or a notification at the same time, ch_evalexpr will not receive the correct response but instead a new request/notification from the server.
The request response and notification from server side have different ID number with JSON encoded text, so vim should be able to distinguish them correctly.
1) client is requesting a server function 2) in that server function, it will request another client-side function. 3) the client is still waiting for the response from the server-side, but it will only receive a new rpc-request.
It could work most of the time, unless the client-side function sends a request to the server again.
The request would block vim, so it should be avoided as much as possible, there is async request function coc#rpc#request_async
which use notification.
particularly within the first 5 seconds after opening a new file. If I input too much, CoC may freeze my gVim.
Avoid invoke coc#rpc#request
during user input.
The request response and notification from server side have different ID number with JSON encoded text, so vim should be able to distinguish them correctly.
Unfortunately, vim can't handle request ID correctly in ch_evalexpr
, it just wait an matched ID from the server side and will buffer any message before it.
step1: f_ch_evalexpr()
https://github.com/vim/vim/blob/6ffcc58be32aa1b337bc839cfe173b68cfde7085/src/channel.c#L5210-L5213
step2: ch_expr_common()
-> channel_read_json_block()
:
https://github.com/vim/vim/blob/6ffcc58be32aa1b337bc839cfe173b68cfde7085/src/channel.c#L4546-L4550
In the channel_get_json()
function, I found It will buffer the current message and wait for the next one when
it meets an unexpected ID:
https://github.com/vim/vim/blob/6ffcc58be32aa1b337bc839cfe173b68cfde7085/src/channel.c#L2478-L2495
There may be an "order problem":
1) client sends an request with id = 100; 2) at the same time, server sends an request with id = 200; 3) client is expecting the response of the msg 100, but it will never receive it, because server is waiting for the response of 200.
The server would have no chance to handle msg 100 because it is still waiting for the response of 200, while the client is waiting for the response of 100 and can’t do anything about msg 200.
I am reading the vim rpc implementation:
https://github.com/neoclide/coc.nvim/blob/eb63f778d09c37095352fb47f75e592d3d2d0192/autoload/coc/client.vim#L175-L182
The function
ch_evalexpr
will send a request to the server and wait for a response. However, the TCP socket is a bi-directional channel. If the server sends a request or a notification at the same time,ch_evalexpr
will not receive the correct response but instead a new request/notification from the server.And the code using
coc#rpc#request(method, args)
will get an unexpected return value.This is likely to happen when the server and client are sending notifications/requests to each other frequently or when the server is busy.
Another potential issue may occur due to nested RPC calls from both sides.
1) client is requesting a server function 2) in that server function, it will request another client-side function. 3) the client is still waiting for the response from the server-side, but it will only receive a new rpc-request.
Sometimes, CoC becomes unresponsive in Vim on some low-end Windows machines, particularly within the first 5 seconds after opening a new file. If I input too much, CoC may freeze my gVim.
Is it possible that it is caused by this problem ?