Skip to content

Spec proposal: support for IProgress<T> #139

@AArnott

Description

@AArnott

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions