Open michaelpj opened 2 years ago
Today I was attempting to use sendRequest
but got some surprising behavior. I was attempting to read a user response from SWindowShowMessageRequest
before continuing by using putMVar
inside the response handler, and a readMVar
outside, but turns out it just blocks indefinitely as the handler doesn't get called. I later thought that this is not done concurrently in the manner I thought and was left clueless on how to handle this, and I see now that this is a known problem, but what workarounds are there for this? Or, is there anything lsp
users can do while this isn't resolved?
Hm, I would expect the MVar
-based solution to work, but I admit I'm not 100% clear on the mechnaics myself. I suspect that indeed your entire server is running single-threaded, so the response cannot be processed while you're sitting waiting on the MVar
.
HLS avoids this by using the reactor pattern, but I wonder if we should build something like that in, since I think basically everyone will want concurrent processing of messages. And indeed, the bit that I linked to which handles progress reporting is arguably broken for this reason.
@heitor-lassarote is it possible that you were waiting on the MVar in inside a handler, in which case and no responses from the client can be observed because the outer handler never returns
Something like this
myHandler _ = do
res <- newEmptyMVar
sendRequest LSP.SMethod_WindowShowMessageRequest _ (putMVar res)
takeMVar res >>= handleMyRequest
One easy solution is to wait on the mvar in another thread so that the outer handler (myHandler
) can finish
myHandler _ = do
res <- newEmptyMVar
sendRequest LSP.SMethod_WindowShowMessageRequest _ (putMVar res)
forkIO $ takeMVar res >>= handleMyRequest
sendRequest
gives you anLspId
, but you can't say "wait until this is responded to". Instead you have a callback-based interface, which isn't easy for clients to use (empirically, see e.g. https://github.com/haskell/lsp/blob/master/lsp/src/Language/LSP/Server/Core.hs#L619).