Repository: neovim
Issue: API: responding to rpcrequest and sending command race and leave messages on the wire
Labels: bug,channels-rpc

- `nvim --version`: NVIM v0.4.2 (RelWithDebInfo) -- also able to reproduce in a local build of `f26df8bb66158baacb79c79822babaf137607cd6` (2 days old at time of writing)
- Operating system/version: CentOS
- Terminal name/version: gnome-terminal
- `$TERM`: xterm-256color

I was building a plugin which responds to some events using rpcrequests and noticed that when the plugin sends a response to an rpcrequest to nvim, immediately followed by an nvim api command (e.g. nvim_get_cursor), the api command is not getting run. I did some more digging and it looks like when the response to the rpcrequest and the following command are sent in quick succession, the latter is not read off of the wire and therefore is not handled until more messages are sent between neovim and the plugin.

### Steps to reproduce using `nvim -u NORC`

Since the plugin is written in OCaml (and I don’t expect the neovim maintainers to build it in order to repro), I've dumped the raw network traffic that is getting sent back and forth into a file to make this easier for others to reproduce. Socat also allows us to batch the replies up, which guarantees that we see the behaviour that the plugin is experiencing.

#### Setup the msgpack.in file

This file will contain the raw bytes for a response to the rpcrequest we call below, immediately followed by a call to nvim_get_cursor:

```
xxd -r > /path/to/msgpack.in
00000000: 9401 01c0 c094 000a b36e 7669 6d5f 7769 .........nvim_wi
00000010: 6e5f 6765 745f 6375 7273 6f72 91cd 0437 n_get_cursor...7
```
This corresponds to the following messages in JSON back-to-back:
```JSON
[ 1, 1, null, null ]
[ 0, 10, "nvim_win_get_cursor", [ 1079 ] ]
```

#### Run nvim and fire off an rpcrequest

The request will be responded to with the msgpack.in file that we just created:

```
nvim -u NORC

# open a new terminal and run:
socat -t100 -x -v SYSTEM:"read -n 1 c; cat /path/to/msgpack.in; read line" UNIX-CONNECT:$NVIM_LISTEN_ADDRESS

# note: the reason for the second read is so that the socket stays open and we can see that no new messages have arrived
# in the original neovim, find the channel id for the rpc connection, and run:
:call rpcrequest(chan_id, "a", v:null)

# verify output in socat terminal
```

### Actual behaviour
Socat shows the following output (there is no response from neovim - i.e. the new request is not being served)

```
< 2020/08/04 14:41:20.715661 length=7 from=0 to=6
94 00 01 a1 61 91 c0 ....a..
--
> 2020/08/04 14:41:25.218110 length=32 from=0 to=31
94 01 01 c0 c0 94 00 0a ........
b3 6e 76 69 6d 5f 77 69 6e 5f 67 65 74 5f 63 75 .nvim_win_get_cu
72 73 6f 72 91 cd 04 37 rsor...7
--
```
The corresponding JSON being sent back and forth is:
```JSON
<
[ 0, 1, "a", [ null ] ]
>
[ 1, 1, null, null ]
[ 0, 10, "nvim_win_get_cursor", [ 1079 ] ]
```

### Expected behaviour

Socat should show a response to the api call, something along the lines of:

```
< 2020/08/04 14:06:23.789820 length=7 from=0 to=6
94 00 01 a1 61 91 c0 ....a..
--
> 2020/08/04 14:06:56.808369 length=32 from=0 to=31
94 01 01 c0 c0 94 00 0a ........
b3 6e 76 69 6d 5f 77 69 6e 5f 67 65 74 5f 63 75 .nvim_win_get_cu
72 73 6f 72 91 cd 04 37 rsor...7
--
< 2020/08/04 14:06:56.835193 length=30 from=7 to=36
94 01 0a ...
92 01 b7 49 6e 76 61 6c 69 64 20 77 69 6e 64 6f ...Invalid windo
77 20 69 64 3a 20 31 30 37 39 c0 w id: 1079.
--
```
Again, the corresponding JSON is:
```JSON
<
[ 0, 1, "a", [ null ] ]
>
[ 1, 1, null, null ]
[ 0, 10, "nvim_win_get_cursor", [ 1079 ] ]
<
[ 1, 10, [ 1, "Invalid window id: 1079" ], null ]
```


Note: `>` indicates a message from the socat stub to neovim, and `<` indicates a message from neovim to the socat stub.

I'm wondering if this is at all related to #8634, since this explains commands "not returning" (or rather, the commands are left on the wire and then processed whenever neovim next processes incoming rpc messages).