Skip to content

Commit 9c27bac

Browse files
committed
Handle inlay hint requests asynchronously
Inlay hints on Dockerfiles need to fetch data so it can take some time before the result can be returned. This means that everything else gets blocked because all JSON-RPC messages are being handled synchronously at the moment. To alleviate this problem, we will check for inlay hint requests and then handle them in a goroutine asynchronously so that other messages can continue to be processed. Other messages may be changed to be handled asynchronously in the future but only inlay hint requests will be done this way for the time being. We want to be careful about introducing drastic changes to how messages are being handled as it is critical for the operation of the language server. Signed-off-by: Remy Suen <remy.suen@docker.com>
1 parent 549e358 commit 9c27bac

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ All notable changes to the Docker Language Server will be documented in this fil
1515

1616
### Fixed
1717

18+
- Dockerfile
19+
- textDocument/inlayHint
20+
- handle inlay hints asynchronously so that it does not block other LSP messages when trying to fetch image data ([#467](https://github.com/docker/docker-language-server/issues/467))
1821
- Compose
1922
- textDocument/documentLink
2023
- return document links for files referenced in the short-form `volumes` attribute of a service object ([#460](https://github.com/docker/docker-language-server/issues/460))

internal/tliron/glsp/server/handler.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,34 @@ import (
66
"fmt"
77

88
"github.com/docker/docker-language-server/internal/tliron/glsp"
9+
"github.com/docker/docker-language-server/internal/tliron/glsp/protocol"
910
"github.com/sourcegraph/jsonrpc2"
1011
)
1112

13+
// AsynchronousRequestHandler will selectively process some JSON-RPC
14+
// messages asynchronously.
15+
type AsynchronousRequestHandler struct {
16+
handler jsonrpc2.Handler
17+
}
18+
19+
func asynchronousRequest(req *jsonrpc2.Request) bool {
20+
// handle textDocument/inlayHint requests asynchronously
21+
return !req.Notif && req.Method == protocol.MethodTextDocumentInlayHint
22+
}
23+
24+
func (h *AsynchronousRequestHandler) Handle(ctx contextpkg.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) {
25+
if asynchronousRequest(req) {
26+
go h.handler.Handle(ctx, conn, req)
27+
} else {
28+
// handle notifications synchronously so that the document changes do not overlap each other
29+
h.handler.Handle(ctx, conn, req)
30+
}
31+
}
32+
1233
// See: https://github.com/sourcegraph/go-langserver/blob/master/langserver/handler.go#L206
1334

1435
func (self *Server) newHandler() jsonrpc2.Handler {
15-
return jsonrpc2.HandlerWithError(self.handle)
36+
return &AsynchronousRequestHandler{handler: jsonrpc2.HandlerWithError(self.handle)}
1637
}
1738

1839
func (self *Server) handle(context contextpkg.Context, connection *jsonrpc2.Conn, request *jsonrpc2.Request) (any, error) {

0 commit comments

Comments
 (0)