Skip to content

#22: Custom LSP integration for the Monaco editor (Python & QASM) - #156

Merged
Jooshua merged 28 commits into
developmentfrom
hiwi/22-custom-lsp-setup
Jun 30, 2026
Merged

#22: Custom LSP integration for the Monaco editor (Python & QASM)#156
Jooshua merged 28 commits into
developmentfrom
hiwi/22-custom-lsp-setup

Conversation

@NicKIT01

Copy link
Copy Markdown
Collaborator

Summary

Adds full Language Server Protocol support to the monaco-react code editor from suren-atoyan.
Python and QASM files now get real IDE features (completion, hover,
diagnostics, ...) backed by embedded pylsp / qasmlsp binaries, bridged
to the browser over WebSockets.

  • The new backend LSP module manages one operating system process per editor session. It acts as a proxy and forwards incoming JSON-RPC messages to the language server binaries via the stdio bridge.
  • New frontend LSP layer (JsonRpcTransport, LSPClient,
    LSPClientManager) wires Monaco's language providers to these sessions,
    with debounced open/change/close lifecycle and reconnect handling.
  • Docker images build and bundle both language servers; compose files and
    CI updated accordingly.

Backend (edu.kit.quak.*.lsp)

  • core.lsp: domain model (LspLanguageId, LspServerDefinition, LspSessionId)
  • application.lsp: LspSessionService orchestrates session lifecycle via ports (incoming ports: LspSessionServicePort; outgoing ports: LspSessionFactoryPort, LspSessionPort, LspServerRegistryPort, LspClientConnectionPort)
  • infrastructure.lsp.out.process: ProcessLspSessionAdapter: one process per session, stdio JSON-RPC via StdioJsonRpcBridge, isolated per-session workspace directory; DefaultLspServerRegistry
  • infrastructure.lsp.in.websocket: LspWebSocketHandler routes /lsp/{language} traffic to/from sessions; LspWebSocketExceptionHandler; WebSocketConfig
  • infrastructure.lsp.config: LspProperties (quak.lsp.*) and LspServerStartupValidator (logs whether each configured server binary is reachable on startup)

Frontend

  • lsp/JsonRpcTransport.ts: WebSocket-based JSON-RPC transport with reconnect/idle handling
  • lsp/LSPClient.ts: per-language client; registers Monaco providers (completion, hover, diagnostics, ...) and manages document open/change/close with debounced change notifications
  • lsp/LSPClientManager.ts: singleton managing one LSPClient per language, tracks active documents per editor group, debounced hide/dispose, reconnect backoff
  • hooks/editor/useLSPSetup.ts (new) and updates to useEditorModelManager.ts, useEditorLanguage.ts, QLPEditor.tsx wire the editor's model lifecycle into the LSP layer

Lifecycle & capacity management

  • quak.lsp.process.termination-timeout-ms (default 2000ms): Destroy/terminate lsp session - applied to the LSP process and any child processes
  • quak.lsp.limits.max-processes (default 40) / max-processes-per-user (default 4): caps total and per-user concurrent LSP processes per backend instance (may be reset based on load tests and real world numbers)
  • quak.lsp.websocket.session-idle-timeout-ms (default 15 min): idle WebSocket sessions are closed; the frontend automatically restores the connection on the next change
  • Sessions are cleaned up consistently on normal close, client disconnect and server crash, releasing the corresponding capacity slot

Languages

  • Python via pylsp (backend/lsp/servers/python)
  • QASM via qasmlsp (backend/lsp/servers/qasm)
  • Adding a new language requires no backend code changes — see backend/lsp/README.md

Deployment

  • backend/Dockerfile builds both language servers in dedicated stages
  • docker-compose.dev.yaml / docker-compose.prod.yaml: production mounts an isolated tmp-filesystem for per-session workspaces
  • CI (test_and_build.yml) builds and bundles the LSP servers

Out of scope / possible follow-ups

  • Metrics/observability for LSP process count and latency
  • Load testing under concurrent multi-user sessions
  • Possibly process warm-up/pooling to increase performance

NicKIT01 added 25 commits May 16, 2026 16:03
…anguages and language servers is a deployment decision not the responsibility of core.
- add global and per-user process limits
- terminate LSP process trees reliably
- clean up sessions on crashes and application shutdown
- dispose LSP clients when leaving a project
@NicKIT01
NicKIT01 requested a review from Jooshua June 10, 2026 12:03

@Jooshua Jooshua left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments

Comment thread backend/src/main/resources/application.yaml
Comment thread frontend/src/views/text-editor-view/utils/editorUtils.ts
Comment thread frontend/src/views/text-editor-view/components/core/QLPEditor.tsx
Comment thread frontend/src/lsp/JsonRpcTransport.ts Outdated
@sonarqubecloud

Copy link
Copy Markdown

@Jooshua Jooshua left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now :)

@Jooshua
Jooshua merged commit 123e23f into development Jun 30, 2026
5 checks passed
@Jooshua
Jooshua deleted the hiwi/22-custom-lsp-setup branch June 30, 2026 09:50
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

Successfully merging this pull request may close these issues.

2 participants