Description
Our OpenRPC contracts currently support fire-and-forget notifications sent from the backend to the frontend, but not the other way around. While we can use requests instead of events, the lack of symmetry between frontend and backend capabilities is unexpected.
I took a look at adding event support in the code generator, which was straightforward to implement. However, our messaging infrastructure needs some adjustments to support notifications.
On the backend side
The backend needs to distinguish between requests and notifications so it knows it doesn’t have to respond to the message. For instance, here is the place in Ark where we respond with either a handler result or an error to all comm messages:
https://github.com/posit-dev/ark/blob/944e309017f87e365c62302d57075ee3789b62b8/crates/amalthea/src/socket/shell.rs#L195-L207
In the OpenRPC spec, it’s the presence of an id
field that makes this distinction. However, we currently purposefully omit that field:
The "id" field is not used. Because the JSON-RPC messages are being delivered as comm_msg Jupyter messages, each message already has an ID and a parent ID. This makes the JSON-RPC ID redundant.
From https://github.com/posit-dev/positron/tree/main/positron/comms#openrpcjson-rpc-deviations
I propose that we restore the id
field in the spec to make it possible to distinguish between notifications and requests.
On the frontend side
The base comm is responsible for constructing our OpenRPC messages.
-
We could add a new method
).notify()
to complementperformRpc()
(see
This method would not add anid
field. -
).performRpc()
would generate anid
and pass it to the lower-levelperformRpcWithBuffers()
(see
This method would gain an optionalmessageId
argument for that purpose.