Skip to content

Filter registration is a central-list conflict point for concurrent filter PRs #798

Description

@yossiovadia

Motivation

Adding a filter today requires editing the same handful of central lists that every other filter PR also edits:

  • filters/src/lib.rs — a pub mod line and a pub use export
  • filters/src/register.rs — an entry in the shared use crate::{ ... } import block, a register_filters! call, and an entry in the build_ai_registry test's expected = [ ... ] array

Because these are append-heavy shared lists, any two in-flight filter PRs conflict by construction — not on filter logic, but on the registration bookkeeping. And the cost compounds with main's velocity: a filter PR that sits for a couple of weeks has to be rebased through the same 3-4 conflict points every time another filter merges.

Concretely, I hit this repeatedly rebasing three filter PRs (#709, #714, #769) onto a fast-moving main. Every rebase conflict was in register.rs/lib.rs/the test array — never in the actual filter. That's pure friction, and it scales with the number of contributors and the ~71 filters already registered.

This is a contributor-experience issue, not a correctness one — but for a project actively courting outside contributions, "every new filter conflicts with every other new filter" is exactly the kind of papercut worth removing early.

Idea (open to direction)

Move registration from a central list to self-registration, so a filter declares itself in its own module and there is no shared list to conflict on. A few options, in rough order of magic-vs-simplicity:

  1. Distributed slice (inventory or linkme): each filter module does something like register_filter!("jwt_auth", JwtAuthFilter::from_config) locally; build_ai_registry() iterates the collected set. No central list; adding a filter touches only its own files.
  2. Per-category registration files: split the one big register.rs into per-category modules so contention is at least spread out (partial mitigation, no new deps).
  3. Build-time codegen that discovers filter modules (heavier; probably not worth it).

The test's expected = [...] array could likewise be derived from the registry rather than hand-maintained.

Trade-offs I can see: inventory/linkme add a dependency and some indirection, and a central list is trivially greppable. But the conflict tax is real and only grows.

Ask

Is the team open to this direction (and if so, which flavor)? Happy to prototype option 1 behind a small PR if there's appetite. Even option 2 alone would meaningfully cut the contention.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions