The JSON-RPC 2.0 specification allows the params member of a request to
be omitted [1]. Before this commit, this library did not allow the
params member to be omitted when sending a request. When the params
argument of the Conn.Call/Conn.DispatchCall or Conn.Notify method was
set to nil, then Request.Params was set to the JSON encoding of nil
which is null.
This commit adds a CallOption named OmitNilParams. If OmitNilParams is
used when sending a request with params set to nil, then the params
member in the JSON encoding of Request is omitted. If the OmitNilParams
option is not used then the previous behavior is maintained. In other
words, the changes in this commit are backwards compatible.
References
[1]: https://www.jsonrpc.org/specification#request_object
This change makes the treatment of params and meta the same, by
assigning a well-known pointer at first to detect if the unmarshaling
process overwrites it with an explicit nil, or it stays the same in
which it means that it was unset from the beginning.
Before, the Call method dispatched the JSON-RPC request and waited
until completion of the request before returning. This made it difficult
to release any locks that need to be released upon dispatch.
Now, the Call method is broken into a DispatchCall and Wait pair.
DispatchCall returns a proxy to the internal call object as soon as the
request is dispatched. When appropriate, the caller can invoke the Wait
method on this proxy to block until the result is ready.
The original Call method is not changed, but now implemented by
these primitives.
The 'result' key MUST be unset according when the error key is set.
This is not what is happening right now. When the error is set,
"result":null is returned in the response payload. This patch is fixing
the issue by adding omitempty for the result field.
NOTE: This is a breaking change to the expected contract of Handler. Please update your implementation to use AsyncHandler if needs be.
We have strict ordering requirements of how we handle FileSystem requests in
LSP. As such relying on the ordering the goroutine scheduler runs requests in
leads to potential out of order mutations to the FS. As such we update the
jsonrpc2 implementation to by default block until Handle returns (note it can
still respond to the request at a later stage). For more simple use cases we
provide the AsyncHandler which will work like the previous implementation.
* Ensure handle is blocking
This makes the MarshalJSON/UnmarshalJSON methods centralize the logic, instead of requiring callers to occasionally munge responses to make them valid to later JSON-marshal.
Previously, we incorrectly interpreted these as neither a request nor a response, and we printed an error for them. This is incorrect behavior per JSON-RPC 2.0 spec; responses can have a null result.
simplify API by using interface{}, rename from transport -> stream
add WebSocket transport in websocket subpackage
do not buffer in ReadObject, rename GetObjectReader/ReadObject -> NextObjectReader
use xtest (jsonrpc2_test) package to allow us to test subpackages that depend on us (in a future change)
factor out vscode-specific transport code and allow pluggable transports
remove Server (unused) and Serve (unnecessary):
The Serve func had nothing specific to JSON-RPC; it was just a loop
around (net.Listener).Accept. It added no value.