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

Synchronous call initiated through a response of an async call drops the results of the sync call. #566

Open
Badhi opened this issue Apr 19, 2024 · 4 comments

Comments

@Badhi
Copy link

Badhi commented Apr 19, 2024

I have created a sample plugin that recreates my issue below.

  • lua in test_plugin/lua/test_plugin/init.lua
M = {}

function M.run()
    vim.fn.Start(1)
    vim.fn.Start(2)
end

function M.update(data)
    print(vim.fn.GetData(data))
end

return M
  • python in test_plugin/rplugin/python3/test_plugin.py
import pynvim
import logging

@pynvim.plugin
class TestPlugin(object):
    def __init__(self, nvim : pynvim.Nvim):
        logging.basicConfig(filename = 'test.log', level='DEBUG')
        self.nvim = nvim

    @pynvim.function('Start', sync=False)
    def start(self, args):
        logging.debug('start called')
        d = args[0]
        self.nvim.exec_lua("require'test_plugin'.update(...)", d, async_ = True)

    @pynvim.function('GetData', sync = True)
    def getData(self, args):
        logging.debug('getdata called')
        d = args[0]
        return d

Here, when i call lua require'test_plugin'.run() I could see both start and getData functions in python getting called twice but the return values of the getData function is never captured by the neovim

Also, if I remove one of the vim.fn.Start calls in run() function, everything works fine.

Appreciate if someone can help me with this and check if I'm not using the pynvim apis incorrectly

@justinmk
Copy link
Member

but the return values of the getData function is never captured by the neovim

The code is only calling print() on the values. Maybe the printed message is not shown because of redraw? Try appending the GetData() results to a list, then check the contents of that list.

@Badhi
Copy link
Author

Badhi commented Apr 25, 2024

Hi @justinmk,
Thanks for the suggestion. I tried to add the results to the list and check the results with a new call and I could see the list is still empty.

But I was able to fix the issue in a different way, but not sure if it just hides the real issue or if that is the real "usage" of the API

The fix was to schedule all the work that is done in the update function to the next in the event loop by using vim.schedule like below

function M.update(data)
    vim.schedule(function()
        print(vim.fn.GetData(data))
    end)
end

I think it makes sense since we first have to give up the current call state that was initiated by rpc call to process other rpc calls?

@justinmk
Copy link
Member

I could see the list is still empty.

Are you certain that start() is called in your example (debug('start called') is written to the logs)?

I think it makes sense since we first have to give up the current call state that was initiated by rpc call to process other rpc calls?

It's certainly tricky when the "call stack" is multiply-bidirectional.

Thanks for providing this test case and info. This is something we should either document, detect, or actually support.

@Badhi
Copy link
Author

Badhi commented Apr 26, 2024

Are you certain that start() is called in your example (debug('start called') is written to the logs)?

Yes, following is the log output for the failing scenario (I have enabled some debug logs in pynvim as well)

DEBUG:root:start called
DEBUG:root:start called
DEBUG:pynvim.plugin.host:calling request handler for "test_plugin/rplugin/python3/test_plugin.py:function:GetData", args: "[[1]]"
DEBUG:root:getdata called
DEBUG:pynvim.plugin.host:request handler for 'test_plugin/rplugin/python3/test_plugin.py:function:GetData [[1]]' returns: 1
DEBUG:pynvim.plugin.host:calling request handler for "test_plugin/rplugin/python3/test_plugin.py:function:GetData", args: "[[2]]"
DEBUG:root:getdata called
DEBUG:pynvim.plugin.host:request handler for 'test_plugin/rplugin/python3/test_plugin.py:function:GetData [[2]]' returns: 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants