You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current DocumentConnectionManager wraps WebSocket sessions from the upstream jupyter-lspjupyter_server extension, which in turn manages the discovery and running of, and JSON-RPC communication with, heavyweight processes on the server.
Many of the widely-used Language Servers are written in JS/TypeScript, but run in nodejs, historically a difficult-to-manage runtime dependency for Jupyter interactive computing users.
Proposed Solution
However, many of these nodejs-based language Servers can be made to run in the browser. Allowing such servers to be independently packaged and distributed as JupyterLab extensions would provide additional editing support for non-kernel (or not-yet-kernel) content, without requiring a nodejs installation.
Of particular interest to JupyterLab itself is a JSON Schema-aware Language Server, which would allow for, at a minimum, improving the user experience of the JupyterLab JSON Settings Editor and the myriad JSON-adjacent files used to develop JupyterLab.
The initial work would move WebSocket/REST wrapper code around, and prepare for extensibility:
DocumentConnectionManager
add registerConnector, probably with a key (e.g. package name) and rank
remove all WebSocket-related code with façades for the methods provided by the connectors
LanguageServerManager
remove all REST code with façades for the methods provided by the connectors
SocketConnector
re-add the WebSocket and REST code here
provide this as in new plugin that requires the main plugin
With this functionality extracted, a second connector would be added that supported the postMessage protocol, including WebWorker, iframe, and other browser tabs. This level of isolation (vs running in the main UI loop) is critical, as the Language Server architecture does not have very pretty failure modes, and many widely-used servers will simply die and need to be restarted. Further, outside of pure JS servers, a number of Language Servers can be compiled to browser-executable WebAssembly, but often at a significant, unpredictable runtime cost.
WorkerConnector
add an implementation that manages one-server-session-per-postMessage-compatible containers
allow for registering new sources of workers
use schema-constrained postMessage to communicate between the main UI loop and a worker
LSP messages
contents
settings
stderr
In parallel, but likely in a @jupyter-lsp repo, a concrete implementation of a WebWorker-based JSON server would demonstrate this functionality.
Additional context
The initial goal is to make additive, backwards-compatible changes such as to not break compatibility with downstream packages, most notably those published as open source by Jupyter Code of Conduct-adhering @jupyter-lsp subproject. Other, uninspectable, proprietary, and variously-well-behaved downstreams certainly exist, however, so this means leaving the public and protected method signatures basically unchanged.
Below are some sketches of how the architecture would evolve:
With the second connector out of the way, any number of other implementations would be possible, without impairing the ability of the architecture and user experience to be further evolved.
KernelConnector
Co-locating a kernel and a language server has a number of advantages and challenges, but is too divisive to implement here.
An early prototype (predating jupyterlab-lsp) showed hand-made LSP messages passed over the high-level Jupyter Widget transport, running in-loop with ipykernel/IPython.
Another prototype PR to jupyter-lsp demonstrated a proxy kernel, which reused the entire python-based LanguageServerManager to manage multiple language servers, communicating with the frontend over a well-characterized Jupyter kernel WebSocket, using the comm protocol.
Other, proprietary implementations have been described in the weekly Jupyter Server call for entirely separate mechanisms.
Multiple Connections
Many languages would benefit from the insights provided by multiple simultaneous Language Servers. This is orthogonal to the proposed work, as it would almost certainly entail breaking changes.
The text was updated successfully, but these errors were encountered:
References
Problem
The current
DocumentConnectionManager
wraps WebSocket sessions from the upstreamjupyter-lsp
jupyter_server
extension, which in turn manages the discovery and running of, and JSON-RPC communication with, heavyweight processes on the server.Many of the widely-used Language Servers are written in JS/TypeScript, but run in
nodejs
, historically a difficult-to-manage runtime dependency for Jupyter interactive computing users.Proposed Solution
However, many of these
nodejs
-based language Servers can be made to run in the browser. Allowing such servers to be independently packaged and distributed as JupyterLab extensions would provide additional editing support for non-kernel (or not-yet-kernel) content, without requiring anodejs
installation.Of particular interest to JupyterLab itself is a JSON Schema-aware Language Server, which would allow for, at a minimum, improving the user experience of the JupyterLab JSON Settings Editor and the myriad JSON-adjacent files used to develop JupyterLab.
The initial work would move WebSocket/REST wrapper code around, and prepare for extensibility:
DocumentConnectionManager
registerConnector
, probably with a key (e.g. package name) and rankLanguageServerManager
SocketConnector
provide
this as in new plugin that requires the main pluginWith this functionality extracted, a second connector would be added that supported the
postMessage
protocol, including WebWorker,iframe
, and other browser tabs. This level of isolation (vs running in the main UI loop) is critical, as the Language Server architecture does not have very pretty failure modes, and many widely-used servers will simply die and need to be restarted. Further, outside of pure JS servers, a number of Language Servers can be compiled to browser-executable WebAssembly, but often at a significant, unpredictable runtime cost.WorkerConnector
postMessage
-compatible containerspostMessage
to communicate between the main UI loop and a workerIn parallel, but likely in a
@jupyter-lsp
repo, a concrete implementation of aWebWorker
-based JSON server would demonstrate this functionality.Additional context
The initial goal is to make additive, backwards-compatible changes such as to not break compatibility with downstream packages, most notably those published as open source by Jupyter Code of Conduct-adhering
@jupyter-lsp
subproject. Other, uninspectable, proprietary, and variously-well-behaved downstreams certainly exist, however, so this means leaving thepublic
andprotected
method signatures basically unchanged.Below are some sketches of how the architecture would evolve:
As Is
To Be
Out of Scope
With the second connector out of the way, any number of other implementations would be possible, without impairing the ability of the architecture and user experience to be further evolved.
KernelConnector
Co-locating a kernel and a language server has a number of advantages and challenges, but is too divisive to implement here.
An early prototype (predating
jupyterlab-lsp
) showed hand-made LSP messages passed over the high-level Jupyter Widget transport, running in-loop withipykernel
/IPython
.Another prototype PR to
jupyter-lsp
demonstrated a proxy kernel, which reused the entire python-basedLanguageServerManager
to manage multiple language servers, communicating with the frontend over a well-characterized Jupyter kernel WebSocket, using the comm protocol.Other, proprietary implementations have been described in the weekly Jupyter Server call for entirely separate mechanisms.
Multiple Connections
Many languages would benefit from the insights provided by multiple simultaneous Language Servers. This is orthogonal to the proposed work, as it would almost certainly entail breaking changes.
The text was updated successfully, but these errors were encountered: