Skip to content

Call interceptors#1218

Merged
mtdowling merged 7 commits into
mainfrom
call-interceptors
May 28, 2026
Merged

Call interceptors#1218
mtdowling merged 7 commits into
mainfrom
call-interceptors

Conversation

@mtdowling
Copy link
Copy Markdown
Member

Replaces #1211, Closes #1197

Instead of a separate CallDecorator abstraction, unify call interception
into ClientInterceptors using a new interceptCall hook and
interceptCalls boolean method. If interceptCalls returns true, then
the interceptors is used in a chain of middleware-style interceptors
that can completely intercept control flow of the call. This can be
used for things like caching, hedging, etc.

A tradeoff of making this an interceptor hook vs a dedicated abstraction
is that the Client, if needed, is not generic and instead stashed in
Context. The cost for making calls is essentially the same when nothing
intercepts. The cost of actually intercepting is essentially the same
(one pre-resolves the chain in a nested call stack, this is iterative).
The advantages are that there's a single abstraction and composition
is the same as before.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

timocov and others added 7 commits May 24, 2026 22:14
Fixes #1197

Co-Authored-By: Michael Dowling <michael@mtdowling.com>
…ow access in call decorators"

This reverts commit 72dc964.
CallDecorator can compose in onion order via CallDecorator.chain, and
plugins register them additively with addCallDecorator so multiple
plugins can layer behavior without clobbering each other.

Decorators receive a ClientCallView, a read-only handle to the resolved
call (input, operation, merged context, endpoint resolver, type registry,
auth scheme resolver and schemes, identity resolvers). The view is
implemented by the existing package-private ClientCall, so no extra
allocation per call.

Override merging and modifyBeforeCall now happen up-front in buildCall,
so RequestOverrideConfig stops leaking into the public decorator surface
and decorators see the same effective context as interceptors.
Instead of a separate CallDecorator abstraction, unify call interception
into ClientInterceptors using a new interceptCall hook and
interceptCalls boolean method. If interceptCalls returns true, then
the interceptors is used in a chain of middleware-style interceptors
that can completely intercept control flow of the call. This can be
used for things like caching, hedging, etc.

A tradeoff of making this an interceptor hook vs a dedicated abstraction
is that the Client, if needed, is not generic and instead stashed in
Context. The cost for making calls is essentially the same when nothing
intercepts. The cost of actually intercepting is essentially the same
(one pre-resolves the chain in a nested call stack, this is iterative).
The advantages are that there's a single abstraction and composition
is the same as before.
@mtdowling mtdowling merged commit b118079 into main May 28, 2026
6 checks passed
@mtdowling mtdowling deleted the call-interceptors branch May 28, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Overriding Client.call method

3 participants