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
jsonrpc4clj reads and writes from io streams, parsing JSON-RPC according to the LSP spec. It provides tools to allow server implementors to receive, process, and respond to any of the methods defined in the LSP spec, and to send their own requests and notifications to clients.
7
+
jsonrpc4clj reads and writes from io streams, parsing JSON-RPC according to the spec. It provides tools to allow server implementors to receive, process, and respond to requests and notifications, and to send their own requests and notifications to clients.
8
8
9
9
## Usage
10
10
@@ -27,7 +27,7 @@ The returned server will have a core.async `:log-ch`, from which you can read se
27
27
28
28
### Receive messages
29
29
30
-
To receive messages from a client, jsonrpc4clj defines a pair of multimethods, `jsonrpc4clj.server/receive-notification` and `jsonrpc4clj.server/receive-request` that dispatch on the method name (as defined by the LSP spec) of an incoming JSON-RPC message.
30
+
To receive messages from a client, jsonrpc4clj defines a pair of multimethods, `jsonrpc4clj.server/receive-notification` and `jsonrpc4clj.server/receive-request` that dispatch on the method name of an incoming JSON-RPC message.
31
31
32
32
Server implementors should create `defmethod`s for the messages they want to process. (Other methods will be logged and responded to with a generic "Method not found" response.)
33
33
@@ -47,21 +47,21 @@ These `defmethod`s receive 3 arguments, the method name, a "context", and the `p
47
47
(conform-or-log::coercer/location)))
48
48
```
49
49
50
-
ThereturnvalueofrequestswillbeconvertedtocamelCasejsonandreturnedtotheclient.Ifthereturnvaluelookslike `{:error ...}`, itisassumedtoindicateanerrorresponse, andthe `...` partwillbesetasthe `error` ofa [JSON-RPC error object](https://www.jsonrpc.org/specification#error_object).Itisuptoyoutoconformthe `...` object (by giving it a `code`, `message`, and `data`.) Otherwise, theentirereturnvaluewillbesetasthe `result` ofa [JSON-RPC response object](https://www.jsonrpc.org/specification#response_object). (Message ids are handled internally by lsp4clj.)
50
+
ThereturnvalueofrequestswillbeconvertedtocamelCasejsonandreturnedtotheclient.Ifthereturnvaluelookslike `{:error ...}`, itisassumedtoindicateanerrorresponse, andthe `...` partwillbesetasthe `error` ofa [JSON-RPC error object](https://www.jsonrpc.org/specification#error_object).Itisuptoyoutoconformthe `...` object (by giving it a `code`, `message`, and `data`.) Otherwise, theentirereturnvaluewillbesetasthe `result` ofa [JSON-RPC response object](https://www.jsonrpc.org/specification#response_object). (Message ids are handled internally by jsonrpc4clj.)
However, it'spossibletocalculaterequestsinparallel (though not notifications).Ifthelanguageserverwantsarequesttobecalculatedinparallelwithothers, itshouldreturna `java.util.concurrent.CompletableFuture`, possiblycreatedwith `promesa.core/future`, from `lsp4clj.server/receive-request`.lsp4cljwillarrangefortheresultofthisfuturetobereturnedtotheclientwhenitresolves.Inthemeantime, lsp4cljwillcontinuepassingtheclient'smessagestothelanguageserver.ThelanguageservercancontrolthenumberofsimultaneousmessagesbysettingtheparallelismoftheCompletableFutures' executor.
56
+
However, it'spossibletocalculaterequestsinparallel (though not notifications).Iftheserverwantsarequesttobecalculatedinparallelwithothers, itshouldreturna `java.util.concurrent.CompletableFuture`, possiblycreatedwith `promesa.core/future`, from `jsonrpc4clj.server/receive-request`.jsonrpc4cljwillarrangefortheresultofthisfuturetobereturnedtotheclientwhenitresolves.Inthemeantime, jsonrpc4cljwillcontinuepassingtheclient'smessagestotheserver.TheservercancontrolthenumberofsimultaneousmessagesbysettingtheparallelismoftheCompletableFutures' executor.
Butclientscancancelrequeststhatareprocessedinparallel.Inthesecaseslsp4cljwillcancelthefutureandreturnamessagetotheclientacknowledgingthecancellation.BecauseofthedesignofCompletableFuture, cancellationcanmeanoneoftwothings.Iftheexecutorhasn'tstartedthethreadthatiscalculatingthevalueofthefuture (perhaps because the executor's thread pool is full), itwon'tbestarted.Butifthereisalreadyathreadcalculatingthevalue, thethreadwon'tbeinterupted.SeethedocumentationforCompletableFutureforanexplanationofwhythisisso.
62
+
Butclientscancancelrequeststhatareprocessedinparallel.Inthesecasesjsonrpc4cljwillcancelthefutureandreturnamessagetotheclientacknowledgingthecancellation.BecauseofthedesignofCompletableFuture, cancellationcanmeanoneoftwothings.Iftheexecutorhasn'tstartedthethreadthatiscalculatingthevalueofthefuture (perhaps because the executor's thread pool is full), itwon'tbestarted.Butifthereisalreadyathreadcalculatingthevalue, thethreadwon'tbeinterupted.SeethedocumentationforCompletableFutureforanexplanationofwhythisisso.
@@ -156,7 +156,7 @@ Many clients can also communicate over a socket. Typically the client starts a s
156
156
:out sock})))
157
157
```
158
158
159
-
`lsp4clj.io-server/server` acceptsapairofoptions `:in` and `:out`.Thesewillbecoercedtoa `java.io.InputStream` and `java.io.OutputStream` via `clojure.java.io/input-stream` and `clojure.java.io/output-stream`, respectively.Theexampleaboveworksbecausea `java.net.Socket` canbecoercedtobothaninputandoutputstreamviathismechanism.
159
+
`jsonrpc4clj.io-server/server` acceptsapairofoptions `:in` and `:out`.Thesewillbecoercedtoa `java.io.InputStream` and `java.io.OutputStream` via `clojure.java.io/input-stream` and `clojure.java.io/output-stream`, respectively.Theexampleaboveworksbecausea `java.net.Socket` canbecoercedtobothaninputandoutputstreamviathismechanism.
160
160
161
161
Asimilarapproachcanbeusedtoconnectoverpipes.
162
162
@@ -177,11 +177,11 @@ As you are implementing, you may want to trace incoming and outgoing messages. I
177
177
178
178
`:trace-level` canbesetto `"off"` (no tracing), `"messages"` (to show just the message time, method, id and direction), or `"verbose"` (to also show details of the message body).
179
179
180
-
Thetracelevelcanbechangedduringthelifeofaserverbycalling, forexample, `(ls4clj.server/set-trace-level server "messages")`.Thiscanbeusedtorespectatracelevelreceivedatruntime, eitherinan [initialize](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initializeParams) requestora [$/setTrace](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#setTrace)notification.
180
+
Thetracelevelcanbechangedduringthelifeofaserverbycalling, forexample, `(jsonrpc4clj.server/set-trace-level server "messages")`.Thiscanbeusedtorespectatracelevelreceivedatruntimeviaacustomrequestornotification.
181
181
182
182
### Testing
183
183
184
-
Aclientisinmanywayslikeaserver—italsosendsandreceivesrequestsandnotificationsandreceivesresponses.Thatis, LSPusesJSON-RPCasabi-directionalprotocol.Assuch, youmaybeabletousesomeoflsp4clj'stoolstobuildamockclientfortesting.See `integration.client` in `clojure-lsp` foronesuchexample.
184
+
Aclientisinmanywayslikeaserver—italsosendsandreceivesrequestsandnotificationsandreceivesresponses.Thatis, JSON-RPCisabi-directionalprotocol.Assuch, youmaybeabletousesomeofjsonrpc4clj'stoolstobuildamockclientfortesting.See `integration.client` in `clojure-lsp` foronesuchexample.
@@ -191,7 +191,7 @@ You must not print to stdout while a `stdio-server` is running. This will corrup
191
191
192
192
Fromexperience, it'sdismayinglyeasytoleaveinanerrant `prn` or `time` andendupwithanon-responsiveclient.Forthisreason, wehighlyrecommendsupportingcommunicationoversockets (see [other types of servers](#other-types-of-servers)) whichareimmunetothisproblem.However, sincethechoiceofwhethertousesocketsorstdioisultimatelyuptotheclient, youmayhavenochoicebuttosupportboth.
193
193
194
-
lsp4cljprovidesonetooltoavoidaccidentalwritestostdout (or rather to `*out*`, which is usually the same as `System.out`).Toprotectablockofcodefromwritingto `*out*`, wrapitwith `lsp4clj.server/discarding-stdout`.The `receive-notification` and `receive-request` multimethodsarealreadyprotectedthisway, buttasksstartedoutsideofthesemultimethodsorthatruninseparatethreadsneedthisprotectionadded.
194
+
jsonrpc4cljprovidesonetooltoavoidaccidentalwritestostdout (or rather to `*out*`, which is usually the same as `System.out`).Toprotectablockofcodefromwritingto `*out*`, wrapitwith `jsonrpc4clj.server/discarding-stdout`.The `receive-notification` and `receive-request` multimethodsarealreadyprotectedthisway, buttasksstartedoutsideofthesemultimethodsorthatruninseparatethreadsneedthisprotectionadded.
0 commit comments