Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shell is freezing #101

Open
lostl1ght opened this issue Jul 18, 2024 · 4 comments · May be fixed by #102
Open

Shell is freezing #101

lostl1ght opened this issue Jul 18, 2024 · 4 comments · May be fixed by #102
Assignees
Labels
bug Something isn't working

Comments

@lostl1ght
Copy link

lostl1ght commented Jul 18, 2024

Hello!

Describe the bug
Blocked shell sometimes does not unblock. I cannot provide steps to reproduce because it happens sporadically.
The quickest way I'm able to reproduce is committing with lazygit inside toggleterm and setting up an auto command to delete the buffer after writing. It happens 1-5 times out of 10.

Expected behavior
Shell to unblock

Desktop (please complete the following information):

  • Debian 12 on WSL
  • Wezterm + Tmux
  • Neovim 0.10.0

Additional context
After many trials and errors: scheduling API functions in callbacks, deferring them with long timeouts, with short timeouts, I may have an idea of what's happening:

diff --git a/lua/flatten/core.lua b/lua/flatten/core.lua
index 0d1622f..81adaa9 100644
--- a/lua/flatten/core.lua
+++ b/lua/flatten/core.lua
@@ -9,7 +9,9 @@ function M.unblock_guest(guest_pipe)
     "vim.cmd.qa({ bang = true })",
     {}
   )
-  vim.fn.chanclose(response_sock)
+  vim.defer_fn(function()
+    vim.fn.chanclose(response_sock)
+  end, 1000)
 end
 
 function M.notify_when_done(pipe, bufnr, callback, ft)

My idea is that the channel gets closed before guest fully receives the command to close. That's why I tried to give the guest a good second to get the command. With this patch it looks that the freezing is not happening. I'm going to test drive this patch for a few days to see if that's indeed the case.

Also, I'm also deferring closing the channel in maybe_block() just for good measure and I've increased sleep time since (I think) there's not point in wasting CPU time waking up and going to sleep every second.

diff --git a/lua/flatten/guest.lua b/lua/flatten/guest.lua
index ef43b56..107b2b5 100644
--- a/lua/flatten/guest.lua
+++ b/lua/flatten/guest.lua
@@ -20,9 +20,11 @@ function M.maybe_block(block)
   if not block then
     vim.cmd.qa({ bang = true })
   end
-  vim.fn.chanclose(host)
+  vim.defer_fn(function()
+    vim.fn.chanclose(host)
+  end, 1000)
   while true do
-    vim.cmd.sleep(1)
+    vim.cmd.sleep(10)
   end
 end

Please, provide any thoughts and ideas on this issue.

@lostl1ght lostl1ght added the bug Something isn't working label Jul 18, 2024
@willothy
Copy link
Owner

Thanks for reporting, I'll look into this more ASAP :)

@lostl1ght
Copy link
Author

vim.rpcrequest also does the trick since it is a blocking call:

diff --git a/lua/flatten/core.lua b/lua/flatten/core.lua
index 0d1622f..5645f62 100644
--- a/lua/flatten/core.lua
+++ b/lua/flatten/core.lua
@@ -2,7 +2,7 @@ local M = {}

 function M.unblock_guest(guest_pipe)
   local response_sock = vim.fn.sockconnect("pipe", guest_pipe, { rpc = true })
-  vim.rpcnotify(
+  pcall(vim.rpcrequest,
     response_sock,
     "nvim_exec_lua",
     ---@diagnostic disable-next-line: param-type-mismatch

But it has to be pcalled, otherwise I get an error:

(mini.bufremove) vim/_editor.lua:0: nvim_exec2()..BufUnload Autocommands for "<buffer=8>": Vim(append):Error executing lua callback: Invalid channel: 5
stack traceback:
	[C]: in function 'rpcrequest'
	/home/desc/plugins/flatten.nvim/lua/flatten/core.lua:5: in function 'unblock_guest'
	/home/desc/plugins/flatten.nvim/lua/flatten/core.lua:22: in function </home/desc/plugins/flatten.nvim/lua/flatten/core.lua:20>
	[C]: in function 'nvim_exec2'
	vim/_editor.lua: in function <vim/_editor.lua:0>
	[C]: in function 'pcall'
	...site/pack/deps/opt/mini.bufremove/lua/mini/bufremove.lua:234: in function 'delete'
	/home/desc/.config/nvim/lua/plugin/lazygit.lua:17: in function ''
	vim/_editor.lua: in function <vim/_editor.lua:0>

@willothy
Copy link
Owner

There are some complexities with using rpcrequest here - I believe I used to do it that way. If the socket has been closed from the other side, this can also cause a hang. As far as pcall goes, it'd be better to check if the channel is valid beforehand, since that seems to be the cause of the error. You can use nvim_get_chan_info for that.

@lostl1ght
Copy link
Author

I can't put my finger around how the channel becomes invalid. The only two places where channel gets closed is in the autocmd callback and before the sleep loop. nvim_get_chan_info doesn't seem to provide useful info:

{
  client = {
    [true] = 6
  },
  id = 5,
  mode = "rpc",
  stream = "socket"
}

@lostl1ght lostl1ght linked a pull request Jul 20, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants