Skip to content

xds: add support for HTTP filter state retention, as specified in A83#8924

Merged
easwars merged 22 commits into
grpc:masterfrom
easwars:a83_filter_state_retention
Mar 18, 2026
Merged

xds: add support for HTTP filter state retention, as specified in A83#8924
easwars merged 22 commits into
grpc:masterfrom
easwars:a83_filter_state_retention

Conversation

@easwars

@easwars easwars commented Feb 20, 2026

Copy link
Copy Markdown
Contributor

How the API looked before this change?

  • We had a single interface, Filter, that was responsible for functionality like config parsing and optionally for building client and server interceptors (or filter instances).
  • We had a registry of Filters keyed by the supported type_urls.

How the API looks after this change?

  • We will have an interface, Builder, that contains functionality for config parsing and other things like "what are the supported type_urls?", "Are filters produced by this builder supposed to be terminal?",
  • Two optional interfaces that the Builder can implement that provide the functionality to create filter instances for the client and server, ClientFilterBuilder and ServerFilterBuilder respectively.
  • The ClientFilterBuilder and ServerFilterBuilder create ClientFilter and ServerFilter respectively.
  • The ClientFilter and ServerFilter interface contains functionality to build client and server interceptors.
  • The methods to create filter instances and interceptors will return cleanup functions that callers need to invoke when the filter/interceptor is no longer required.
  • We will have a registry of Builderss keyed by the supported type_urls.

Why is this change required?

  • As part of gRFC A83 and moving forward on a bunch of other gRFCs, we will start having HTTP filters that need to maintain a bunch of state, and this state needs to be retained across resource updates. For example, the filter might contain a gRPC channel to an external service, and we don't want to recreate this channel for resource updates that doesn't change any properties associated with the service that is being connected to.

How will this be used?

  • The xDS name resolver and the xDS enabled grpc server (entities that create HTTP filters on the client and server side) will create new Filter instances only when the filter names in the xDS resources change. Otherwise, they will only create new interceptors using the updated filter configuration from the existing Filter. This will allow Filter instances to share state across interceptors and across state updates.

The changes here and inspired by similar changes made for Java and described here: https://github.com/grpc/proposal/blob/master/A83-xds-gcp-authn-filter.md#java

RELEASE NOTES: None

@easwars easwars added Type: Feature New features or improvements in behavior Area: xDS Includes everything xDS related, including LB policies used with xDS. labels Feb 20, 2026
@easwars easwars added this to the 1.80 Release milestone Feb 20, 2026
@easwars

easwars commented Feb 20, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and well-executed refactoring to support stateful HTTP filters, as outlined in gRFC A83. The core change is the introduction of a Builder and Filter pattern, which separates filter configuration and instantiation from interceptor creation. This enables the caching and reuse of filter instances across configuration updates, which is crucial for filters that need to maintain state.

The changes are consistently applied across both client-side and server-side filter handling. The client resolver and server listener wrapper now manage the lifecycle of filter instances, including caching and cleanup, which prevents resource leaks. The addition of new end-to-end tests to verify this state retention behavior is a great addition.

Overall, the implementation appears solid and aligns well with the design goals. I have one minor suggestion for improving maintainability.

Comment thread internal/xds/server/filter_chain_manager.go Outdated
@easwars

easwars commented Feb 20, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements HTTP filter state retention as specified in gRFC A83. It introduces a new Builder interface and separates the filter instance lifecycle from the interceptor lifecycle, allowing filters to maintain state across configuration updates. The changes correctly implement reference counting for server-side filters which can be shared across multiple filter chains. My review identified a few issues related to resource cleanup and potential memory leaks in the server-side implementation, specifically regarding the management of the filter instance map and the stopping of pending configuration managers.

Comment thread internal/xds/server/listener_wrapper.go Outdated
Comment thread internal/xds/server/listener_wrapper.go
Comment thread internal/xds/server/filter_chain_manager.go Outdated
@codecov

codecov Bot commented Feb 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.64602% with 46 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.07%. Comparing base (f967422) to head (62eb102).
⚠️ Report is 7 commits behind head on master.

Files with missing lines Patch % Lines
internal/xds/server/filter_chain_manager.go 76.92% 13 Missing and 5 partials ⚠️
internal/xds/resolver/xds_resolver.go 78.57% 11 Missing and 4 partials ⚠️
internal/xds/server/listener_wrapper.go 76.59% 7 Missing and 4 partials ⚠️
internal/xds/httpfilter/router/router.go 87.50% 1 Missing ⚠️
...nternal/xds/xdsclient/xdsresource/unmarshal_lds.go 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8924      +/-   ##
==========================================
- Coverage   83.13%   83.07%   -0.06%     
==========================================
  Files         411      411              
  Lines       32704    32892     +188     
==========================================
+ Hits        27187    27326     +139     
- Misses       4140     4179      +39     
- Partials     1377     1387      +10     
Files with missing lines Coverage Δ
internal/resolver/config_selector.go 100.00% <ø> (ø)
internal/xds/httpfilter/fault/fault.go 72.79% <100.00%> (+0.82%) ⬆️
internal/xds/httpfilter/httpfilter.go 100.00% <100.00%> (ø)
internal/xds/httpfilter/rbac/rbac.go 62.66% <100.00%> (+2.10%) ⬆️
internal/xds/resolver/serviceconfig.go 90.32% <100.00%> (+3.92%) ⬆️
internal/xds/server/routing.go 85.00% <100.00%> (-0.19%) ⬇️
internal/xds/httpfilter/router/router.go 46.15% <87.50%> (+7.91%) ⬆️
...nternal/xds/xdsclient/xdsresource/unmarshal_lds.go 93.41% <66.66%> (+0.03%) ⬆️
internal/xds/server/listener_wrapper.go 78.09% <76.59%> (-1.32%) ⬇️
internal/xds/resolver/xds_resolver.go 88.30% <78.57%> (-3.58%) ⬇️
... and 1 more

... and 33 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@easwars

easwars commented Feb 21, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and well-executed refactoring to support stateful HTTP filters, aligning with gRFC A83. The core of the change is the new set of httpfilter interfaces (Builder, ClientFilter, ServerFilter) which separate filter configuration parsing from interceptor creation and state management. This is a solid design that enables filter state retention across resource updates.

The changes are consistently applied across the client-side resolver and server-side listener logic, with corresponding updates to all existing filter implementations. The addition of cleanup functions to the new interfaces is crucial for proper resource management of stateful filters.

I'm particularly impressed by the new end-to-end tests (TestXDSResolverHTTPFilters_FilterInstanceRetained and the new test/xds/xds_server_filter_state_retention_test.go file) which thoroughly validate the new state retention and lifecycle management behavior. These tests provide strong confidence in the correctness of this complex change.

I have one suggestion for a minor performance improvement in the server-side filter cleanup logic. Overall, this is an excellent contribution.

Comment thread internal/xds/server/listener_wrapper.go Outdated
@easwars

easwars commented Feb 24, 2026

Copy link
Copy Markdown
Contributor Author

@Pranjali-2501

@easwars easwars requested review from arjan-bal and removed request for dfawley February 25, 2026 00:25
@easwars easwars assigned arjan-bal and unassigned dfawley Feb 25, 2026
Comment thread internal/xds/httpfilter/httpfilter.go
Comment thread internal/xds/httpfilter/httpfilter.go Outdated
Comment thread internal/xds/httpfilter/httpfilter.go Outdated
Comment thread internal/xds/httpfilter/fault/fault.go Outdated
Comment thread internal/xds/httpfilter/fault/fault.go Outdated
Comment thread internal/xds/resolver/xds_resolver.go Outdated
Comment thread internal/xds/resolver/xds_resolver.go Outdated
Comment thread internal/xds/resolver/xds_resolver.go
Comment thread internal/xds/server/filter_chain_manager.go Outdated
Comment thread internal/xds/server/filter_chain_manager.go Outdated
Comment thread internal/xds/server/filter_chain_manager.go Outdated
@arjan-bal arjan-bal assigned easwars and unassigned arjan-bal Mar 2, 2026
@mbissa mbissa modified the milestones: 1.80 Release, 1.81 Release Mar 6, 2026
@easwars

easwars commented Mar 15, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review again and apologies for the delay in getting back. I think I've addressed all your comments. PTAL.

@easwars easwars assigned arjan-bal and unassigned easwars Mar 15, 2026

// IsRouterFilter returns true iff a HTTP filter is a Router filter.
func IsRouterFilter(b httpfilter.Filter) bool {
func IsRouterFilter(b httpfilter.Builder) bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The godoc needs to be updated to mention filter builders instead of filters.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread internal/xds/resolver/xds_resolver.go
Comment thread internal/xds/resolver/xds_resolver.go
@arjan-bal

Copy link
Copy Markdown
Contributor

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and well-executed refactoring of the HTTP filter API to support stateful filters, as specified in gRFC A83. The core change from a stateless Filter interface to a stateful Builder/Filter pattern is implemented consistently for both client and server sides. The new design allows filter instances to be retained across configuration updates, enabling state preservation. The introduction of Close() methods on filters and interceptors, along with reference counting for server-side filters, ensures proper resource lifecycle management. The changes are accompanied by thorough tests, including new end-to-end tests that validate the state retention and cleanup logic. The implementation appears robust and correct.

@arjan-bal arjan-bal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor comments, otherwise LGTM!

@arjan-bal arjan-bal assigned easwars and unassigned arjan-bal Mar 17, 2026
@easwars easwars merged commit 12e91dd into grpc:master Mar 18, 2026
14 checks passed
@easwars easwars deleted the a83_filter_state_retention branch March 18, 2026 07:46
goingforstudying-ctrl added a commit to goingforstudying-ctrl/grpc-go that referenced this pull request Jun 21, 2026
…grpc#8924)

#### How the API looked before this change?
- We had a single interface, `Filter`, that was responsible for
functionality like config parsing and optionally for building client and
server interceptors (or filter instances).
- We had a registry of `Filter`s keyed by the supported type_urls.

#### How the API looks after this change?
- We will have an interface, `Builder`, that contains functionality for
config parsing and other things like "what are the supported
type_urls?", "Are filters produced by this builder supposed to be
terminal?",
- Two optional interfaces that the `Builder` can implement that provide
the functionality to create filter instances for the client and server,
`ClientFilterBuilder` and `ServerFilterBuilder` respectively.
- The `ClientFilterBuilder` and `ServerFilterBuilder` create
`ClientFilter` and `ServerFilter` respectively.
- The `ClientFilter` and `ServerFilter` interface contains functionality
to build client and server interceptors.
- The methods to create filter instances and interceptors will return
cleanup functions that callers need to invoke when the
filter/interceptor is no longer required.
- We will have a registry of `Builders`s keyed by the supported
type_urls.

#### Why is this change required?
- As part of gRFC A83 and moving forward on a bunch of other gRFCs, we
will start having HTTP filters that need to maintain a bunch of state,
and this state needs to be retained across resource updates. For
example, the filter might contain a gRPC channel to an external service,
and we don't want to recreate this channel for resource updates that
doesn't change any properties associated with the service that is being
connected to.

#### How will this be used?
- The xDS name resolver and the xDS enabled grpc server (entities that
create HTTP filters on the client and server side) will create new
`Filter` instances only when the filter names in the xDS resources
change. Otherwise, they will only create new interceptors using the
updated filter configuration from the existing `Filter`. This will allow
`Filter` instances to share state across interceptors and across state
updates.

The changes here and inspired by similar changes made for Java and
described here:
https://github.com/grpc/proposal/blob/master/A83-xds-gcp-authn-filter.md#java

RELEASE NOTES: None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: xDS Includes everything xDS related, including LB policies used with xDS. Type: Feature New features or improvements in behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants