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

Listener API #99

Closed
bollwyvl opened this issue Nov 7, 2019 · 3 comments
Closed

Listener API #99

bollwyvl opened this issue Nov 7, 2019 · 3 comments

Comments

@bollwyvl
Copy link
Collaborator

bollwyvl commented Nov 7, 2019

A number of issues (#95, #17, probably more) have identified a need for writing
concrete files to disk in order for language servers to act on them. This is
sufficient to start the conversation about allowing the pipeline of language
messages to be intercepted by any number of agents. Currently the flow looks like:

                 --> queue --> stdin
                |                |
                |                v
client  <--> handler         language server
                ^                |
                |                v
                 --  queue  <-- stdout

Proposed is to allow any number of listeners to react to the messages.

                 --> listener --> queue --> stdin
                |                            |
                |                            v
client  <--> handler                   language server
                ^                            |
                |                            v
                 --  listener <-- queue <-- stdout

Not proposed is to actually change or prevent the delivery of messages,
nor to encourage direct access to the handlers or servers, but rather to delay
delivery of a message until some external side effect has been completed, in the
initial case, the writing of a file to disk.

This particular case could be achieved through direct use of the existing
ContentsManager API, but in this case, LSP provides a change-based approach
over WebSockets that is likely more performant.

notional API

from jupyter_lsp import on_lsp_message, LanguageServerManager

def load_jupyter_server_extension(nbapp):
    # another extension developer might need to IOLoop.call_later
    mgr = nbapp.language_server_manager

    @on_lsp_message(languages=".*", methods=r"textDocument/did(Open|Close)")
    async def do_thing_with_message(
        message: LSPMessage, 
        manager: LanguageServerManager
    ) -> None:
        # do something with a message

As these cannot change the message, they can be scheduled to run in "parallel".

notional manager changes

import asyncio

class LanguageServerManager
    async write_server_message(message, language):
        await asyncio.gather([
            listener(message, self)
            for listener in listeners
            if listener.should_listen(message, {"language": language})
        ])
        for session in self.get_sessions(language):
            await session.write_message(message)
@krassowski
Copy link
Member

I guess we can close this one?

@krassowski
Copy link
Member

Please reopen if needed!

@bollwyvl
Copy link
Collaborator Author

bollwyvl commented Jan 15, 2020 via email

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

No branches or pull requests

2 participants