feat(rtc): add RPC interceptors - #724
Conversation
Port of livekit/python-sdks#806. An RpcInterceptor wraps every RPC the local participant performs (interceptOutgoing) or handles (interceptIncoming), so telemetry can trace calls in both directions without touching user code. Interceptors run in registration order, the first outermost; errors from the remote side or from the handler flow through the chain unchanged, and a call for an unregistered method reaches the chain with `next` throwing UNSUPPORTED_METHOD, so an interceptor can record that the agent never registered it. RpcInvocationData now carries the invoked `method`, and RpcCallInfo mirrors performRpc's parameters so an interceptor can hand a modified call to `next`. Deliberate deviation from the Python SDK: the Node SDK never enforced the caller's responseTimeout on the handler locally (the caller times out on its side), and promises cannot be cancelled, so the incoming chain is not raced against a deadline here. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 43cfa5d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The FFI layer answers UNSUPPORTED_METHOD for a method nobody registered before the SDK's handler runs, so the callee's incoming interceptor never sees such a call in a real room. The e2e assertion expected it to; the Python equivalent only held in unit tests with fake continuations. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1egoman
left a comment
There was a problem hiding this comment.
Generally makes sense to me, cool feature!
| #### Intercepting RPC calls | ||
|
|
||
| An `RpcInterceptor` wraps every RPC the local participant performs or handles, which is useful for logging, tracing, or attaching metadata to payloads. Each method receives the call and a `next` continuation; return what `next` returns. Interceptors run in the order they were added, the first being outermost, and errors from the remote side or from your handler flow through them unchanged. Implement only the direction you care about. |
There was a problem hiding this comment.
nitpick, but probably too late to change: In other "web framework" contexts usually this is called middleware. I wonder if that maybe would have been a better name for this?
There was a problem hiding this comment.
they are similar but I think there are slight differences. see: https://stackoverflow.com/questions/54863655/whats-the-difference-between-interceptor-vs-middleware-vs-filter-in-nest-js
ours is higher level with less power.. IMO interceptor is right
Port of livekit/python-sdks#806. An RpcInterceptor wraps every RPC the local participant performs (interceptOutgoing) or handles (interceptIncoming), so telemetry can trace calls in both directions without touching user code. Interceptors run in registration order, the first outermost; errors from the remote side or from the handler flow through the chain unchanged, and a call for an unregistered method reaches the chain with
nextthrowing UNSUPPORTED_METHOD, so an interceptor can record that the agent never registered it.RpcInvocationData now carries the invoked
method, and RpcCallInfo mirrors performRpc's parameters so an interceptor can hand a modified call tonext.Deliberate deviation from the Python SDK: the Node SDK never enforced the caller's responseTimeout on the handler locally (the caller times out on its side), and promises cannot be cancelled, so the incoming chain is not raced against a deadline here.