vim-denops/denops.vim

Sometimes connection closed by channel error

kuuote opened this issue · 5 comments

kuuote commented

Problem

Connection closed by ch 4 returned a response with an unknown request id. Ensure the client is properly synchronized in some case

To Repoduce

  1. introduce following plugins

fece0a2
vim-skk/skkeleton@d31549c

  1. introduce init.vim
set rtp+=/path/to/vim-denops/denops.vim
set rtp+=/path/to/vim-skk/skkeleton

autocmd User DenopsPluginPost:skkeleton call skkeleton#initialize()
autocmd User skkeleton-initialize-pre call skkeleton#config({})
nnoremap i i<Plug>(skkeleton-enable)<Esc>
sleep 500m
  1. Launch Neovim (HEAD or Stable 0.9.1)

nvim --clean -u init.vim

  1. press i immediately

Screen Shot

Screenshot_20230719-125225

kuuote commented

skkeleton無しでの再現手順は後ほど用意します

kuuote commented
[denops] (skkeleton) d -> v: [0] request: call("denops#api#cmd", "doautocmd <nomodeline> User DenopsSystemPluginPre:skkeleton", {})
[denops] (skkeleton) v -> d: [0] response: 0
[denops] (skkeleton) d -> v: [1] request: call("denops#api#eval", "exists(n) ? g:skkeleton#debug : v", {"n":"g:skkeleton#debug","v":false})
[denops] (skkeleton) v -> d: [1] response: false
[denops] (skkeleton) d -> v: [2] request: call("denops#api#cmd", "doautocmd <nomodeline> User DenopsSystemPluginPost:skkeleton", {})
Error detected while processing function skkeleton#handle[1]..skkeleton#request[4]..denops#request[1]..denops#server#request[4]..denops#_internal#server#chan#request[4]..denops#_internal#rpc#nvim#request:
line    1:
Error invoking 'invoke' on channel 4:
ch 4 returned a response with an unknown request id. Ensure the client is properly synchronized
Error detected while processing function skkeleton#handle[1]..skkeleton#request[4]..denops#request[1]..denops#server#request[4]..denops#_internal#server#chan#request[4]..denops#_internal#rpc#nvim#request:
line    1:
Error invoking 'invoke' on channel 4:
Invalid channel: 4
Error detected while processing function skkeleton#handle[1]..skkeleton#request[4]..denops#request[1]..denops#server#request[4]..denops#_internal#server#chan#request[4]..denops#_internal#rpc#nvim#request:
line    1:
Error invoking 'invoke' on channel 4:
Invalid channel: 4

[denops] (skkeleton) v -> d: [0] request: initialize()
[denops] (skkeleton) d -> v: [3] request: call("denops#api#cmd", "doautocmd <nomodeline> User skkeleton-initialize-pre", {})
[denops] (skkeleton) v -> d: [1] request: enable({}, {"prevInput":"","completeInfo":{"pum_visible":0,"mode":"","selected":-1,"items":[]},"mode":"i","completeType":"native"})
[denops] (skkeleton) d -> v: [4] request: call("denops#api#cmd", "doautocmd <nomodeline> User skkeleton-initialize-pre", {})
[denops] (skkeleton) v -> d: [2] response: 0
[denops] (skkeleton) v -> d: [2] request: config({})
[denops] (skkeleton) d -> v: [2] response: undefined
[denops] (skkeleton) v -> d: [3] request: config({})
[denops] (skkeleton) d -> v: [3] response: undefined
[denops] Unexpected error Error: Session is not running
[denops]     at Session.shutdown (https://deno.land/x/messagepack_rpc@v2.0.3/session.ts:212:13)
[denops]     at Neovim.dispose (file:///Users/alisue/ghq/github.com/vim-denops/denops.vim/denops/@denops-private/host/nvim.ts:77:19)
[denops]     at using (https://deno.land/x/disposable@v1.1.1/using.ts:16:20)
[denops]     at eventLoopTick (ext:core/01_core.js:183:11)
[denops]     at async handleConn (file:///Users/alisue/ghq/github.com/vim-denops/denops.vim/denops/@denops-private/cli.ts:37:3)
kuuote commented

https://github.com/kuuote/denops-issue-268
こちらを使えばskkeleton無しで再現できると思います

Shougo commented

It seems neovim's bug.

@@ -321,26 +319,32 @@ static void parse_msgpack(Channel *channel)
       }
       arena_mem_free(arena_finish(&p->arena));
     } else if (p->type == kMessageTypeResponse) {
-      ChannelCallFrame *frame = kv_last(channel->rpc.call_stack);
-      if (p->request_id != frame->request_id) {
-        char buf[256];
-        snprintf(buf, sizeof(buf),
-                 "ch %" PRIu64 " returned a response with an unknown request "
-                 "id. Ensure the client is properly synchronized",
-                 channel->id);
-        chan_close_with_error(channel, buf, LOGLVL_ERR);
+      size_t size = kv_size(channel->rpc.call_stack);
+      for (size_t i = 0; i < size; i++) {
+        ChannelCallFrame *frame = kv_Z(channel->rpc.call_stack, i);
+        if (frame->returned) {
+          continue;
+        }
+        if (frame->request_id == p->request_id) {
+          frame->returned = true;
+          frame->errored = (p->error.type != kObjectTypeNil);
+          if (frame->errored) {
+            frame->result = p->error;
+            // TODO(bfredl): p->result should not even be decoded
+            // api_free_object(p->result);
+          } else {
+            frame->result = p->result;
+          }
+          frame->result_mem = arena_finish(&p->arena);
+          goto end;
+        }
       }
-      frame->returned = true;
-      frame->errored = (p->error.type != kObjectTypeNil);
-
-      if (frame->errored) {
-        frame->result = p->error;
-        // TODO(bfredl): p->result should not even be decoded
-        // api_free_object(p->result);
-      } else {
-        frame->result = p->result;
-      }
-      frame->result_mem = arena_finish(&p->arena);
+      char buf[256];
+      snprintf(buf, sizeof(buf),
+               "ch %" PRIu64 " returned a response with an unknown request "
+               "id. Ensure the client is properly synchronized",
+               channel->id);
+      chan_close_with_error(channel, buf, LOGLVL_ERR);
     } else {
       log_client_msg(channel->id, p->type == kMessageTypeRequest, p->handler.name);
 
@@ -353,6 +357,7 @@ static void parse_msgpack(Channel *channel)
       handle_request(channel, p, arg);
     }
   }
+end:
 
   if (unpacker_closed(p)) {
     chan_close_with_error(channel, p->unpack_error.msg, LOGLVL_ERR);
@@ -361,8 +366,7 @@ static void parse_msgpack(Channel *channel)
 }