Skip to content

Commit 85d1a8a

Browse files
Complete pending request promise on default executor
1 parent fe73a2c commit 85d1a8a

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

src/lsp4clj/server.clj

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
;; client. This cannot be `(-> (p/deferred) (p/catch))` because that returns
9696
;; a promise which, when cancelled, does nothing because there's no
9797
;; exception handler chained onto it. Instead, we must cancel the
98-
;; `(p/deffered)` promise itself.
98+
;; `(p/deferred)` promise itself.
9999
(p/catch p CancellationException
100100
(fn [_]
101101
(protocols.endpoint/send-notification server "$/cancelRequest" {:id id})))
@@ -351,9 +351,16 @@
351351
(if-let [{:keys [p started] :as req} (get pending-requests id)]
352352
(do
353353
(trace this trace/received-response req resp started now)
354-
(if error
355-
(p/reject! p (ex-info "Received error response" resp))
356-
(p/resolve! p result)))
354+
;; Note that we are called from the server's pipeline, a core.async
355+
;; go-loop, and therefore must not block. Callbacks of the pending
356+
;; request's promise will be executed in the completing thread,
357+
;; which should not be our thread. This is very easy for users to
358+
;; miss, therefore we complete the promise on the default executor.
359+
(p/thread-call :default
360+
(fn []
361+
(if error
362+
(p/reject! p (ex-info "Received error response" resp))
363+
(p/resolve! p result)))))
357364
(trace this trace/received-unmatched-response resp now)))
358365
(catch Throwable e
359366
(log-error-receiving this e resp))))

0 commit comments

Comments
 (0)