Context
Sidecars speak JSON-RPC 2.0 over two transports today: stdio (NDJSON) and
http (POST + SSE). That choice is recorded in
ADR-0001
and stands — the entry barrier for plugin authors is the reason it was made,
and stdio remains the right default.
Two things argue for widening the choice, recorded in
ADR-0002:
- gRPC is now the default RPC stack in most sidecar languages — first-class
in Go, mature in Rust (tonic) and Python (grpcio), and @grpc/grpc-js has
been pure JavaScript with no native build for years.
- The streaming gap was never closed. Bowire's protocols stream heavily, but
JSON-RPC has no stream concept, so the host rebuilds one from notifications
($/stream/data, $/channel/data) plus SidecarSubscriptionHub — with no
flow control and no backpressure. ADR-0001's own "use a native .NET plugin
above ~10k msgs/sec" is that gap stated as a limit.
Scope
Add gRPC as a third ISidecarTransport, selected by "transport": "grpc"
in sidecar.json. JSON-RPC over stdio stays the default — this is
additive, nothing existing changes behaviour.
The host side is cheap: ISidecarTransport already has two implementations
(SidecarJsonRpcTransport, SidecarHttpTransport) and the manifest already
carries a transport field. The cost is in the SDKs.
Blocked by #418
The four language SDKs are already behind the current contract. Adding a
second transport family to SDKs that have not caught up with the first
multiplies a debt that is already due. #418 lands first — this issue should
not start before it closes.
Tasks
Non-goals
- Replacing JSON-RPC. Rejected in ADR-0002: it breaks every existing sidecar and
discards the property that a sidecar can be written in anything emitting JSON
lines — a shell script, an exotic language, a prototype.
- Making gRPC the default.
Context
Sidecars speak JSON-RPC 2.0 over two transports today:
stdio(NDJSON) andhttp(POST + SSE). That choice is recorded inADR-0001
and stands — the entry barrier for plugin authors is the reason it was made,
and stdio remains the right default.
Two things argue for widening the choice, recorded in
ADR-0002:
in Go, mature in Rust (
tonic) and Python (grpcio), and@grpc/grpc-jshasbeen pure JavaScript with no native build for years.
JSON-RPC has no stream concept, so the host rebuilds one from notifications
(
$/stream/data,$/channel/data) plusSidecarSubscriptionHub— with noflow control and no backpressure. ADR-0001's own "use a native .NET plugin
above ~10k msgs/sec" is that gap stated as a limit.
Scope
Add gRPC as a third
ISidecarTransport, selected by"transport": "grpc"in
sidecar.json. JSON-RPC over stdio stays the default — this isadditive, nothing existing changes behaviour.
The host side is cheap:
ISidecarTransportalready has two implementations(
SidecarJsonRpcTransport,SidecarHttpTransport) and the manifest alreadycarries a
transportfield. The cost is in the SDKs.Blocked by #418
The four language SDKs are already behind the current contract. Adding a
second transport family to SDKs that have not caught up with the first
multiplies a debt that is already due. #418 lands first — this issue should
not start before it closes.
Tasks
SidecarGrpcTransport : ISidecarTransportin the host"grpc"accepted inSidecarPluginManifest, discovery guard updated (cf. Sidecar discovery drops HTTP-transport plugins (guard requires executable) #415, which fixed the same class of bug forhttp)run_grpc()alongsiderun()/run_http()), so a plugin'sBowirePluginimplementation is untoucheddocs/architecture/sidecar-plugins.mdwhen it ships, not before; flip ADR-0002 toAcceptedNon-goals
discards the property that a sidecar can be written in anything emitting JSON
lines — a shell script, an exotic language, a prototype.