-
Notifications
You must be signed in to change notification settings - Fork 162
Description
The following is a proposal for an extension to the JSON-RPC protocol that serves as a means for a server to provide progress reports on an invoked method to the client, leading to a final result.
In C#, this might be expressed as IProgress<T>
. A server method signature might take this form:
async Task DoSomeHeavyWorkAsync(int units, IProgress<WorkUpdate> progress);
A request might look like this:
{
"jsonrpc": "2.0",
"id": 153,
"method": "someMethodName",
"params": {
"units": 5,
"progress": "some-JSON-token"
}
}
The progress
argument may have any name or position, and may have any valid JSON token as its value. A value of null
is specially recognized as an indication that the client does not want progress updates from the server. This argument may not be recognizable as an IProgress<T>
token from the request, but the JSON-RPC library can offer a means for an application to specify that this argument is used as a progress token during a callback to the client.
For instance, in the above C# method signature, the IProgress<WorkUpdate>
parameter type would signify to the JSON-RPC library that it should reinterpret the second/"progress" argument as a progress token and instantiate an IProgress<WorkUpdate>
instance whose Report
method will send the response message as specified below, carrying that token.
A JSON-RPC client may find it convenient to simply reuse the value from the id
in the request itself, but may choose to avoid this so that multiple progress arguments can be passed in via the same request. This would enable different progress updates or frequencies to be supplied at the client's discretion. The progress token SHOULD be unique to the session so that any progress callbacks from the server can be distinctly routed to the right handler on the client side.
In processing such a message, the server provides updates to the client via a notification sent back to the client. These notifications use the special method name $/progress
. For example:
{
"jsonrpc": "2.0",
"method": "$/progress",
"params": {
"token": "some-JSON-token",
"value": { "some": "status-token" }
}
}
Parameters are (progressToken, value)
, which may be named in a params object or as a params array in that order. progressToken
must match the value of the argument from the request that progress is being reported for. The value
property in this $/progress
message may be set to any json token representing the update from the server. It may be a number, string, bool, object, or even the null
literal.
Implementation notes
It is conceivable that client applications of a JSON-RPC library that supports this feature would expect that progress notifications are raised to the application in order, and possibly all before the outbound RPC call is marked completed. In multi-threaded environments this can introduce special considerations. In .NET for example, the IProgress<T>
interface makes such guarantees hard, and we'll likely need to document that folks use a particular implementation of that interface that guarantees ordering, and also suggest ways to mitigate the chance of their async call completing before the last progress message has been recognized by the client.