Geo: Derive REGISTRY_CLASSES from REPLICATOR_CLASSES

What does this MR do and why?

Geo::Secondary::RegistryConsistencyWorker::REGISTRY_CLASSES was a second hand-maintained list that duplicated Gitlab::Geo::REPLICATOR_CLASSES: every new replicator had to be added to both, in sorted order, and kept in sync.

This derives the registry list from the replicator list instead, so REPLICATOR_CLASSES is the single source of truth. Each replicator already knows its own registry via .registry_class, so:

  • Gitlab::Geo.registry_classes returns REPLICATOR_CLASSES.map(&:registry_class).
  • The worker's REGISTRY_CLASSES constant is now Gitlab::Geo.registry_classes.freeze.
  • The blob replicator generator no longer patches the worker constant, so there is one fewer hand-edited framework file per new replicator.
  • A new conformance spec loops REPLICATOR_CLASSES and asserts every replicator resolves a Geo::BaseRegistry subclass and has a registry factory, so a mis-wired or half-added replicator fails loudly.

This is a developer-facing refactor with no behavior or API change.

Why not full auto-discovery?

Removing REPLICATOR_CLASSES entirely (for example Replicator.subclasses or a Dir.glob) was explored in #227693 (closed) and rejected: .subclasses returns a partial list under eager_load = false (dev/console), and the explicit list gives eager-load safety plus easy missing-class detection. Keeping the list and deriving from it removes the duplication without that risk.

Verification

  • The derived list is byte-identical to the previous constant: same 44 classes, same order, confirmed in a fresh eager_load = false process.
  • Because the list value and order are unchanged, the GeoRegistryClass GraphQL enum (which iterates it) is unchanged, so no schema regeneration is needed.
  • bundle exec rspec ee/spec/lib/gitlab/geo/every_replicator_has_registry_spec.rb ee/spec/workers/geo/secondary/registry_consistency_worker_spec.rb ee/spec/lib/generators/geo/blob_replicator_generator_spec.rb gives 71 examples, 0 failures.
  • RuboCop clean on all changed files.

Part of the SSF boilerplate reduction in #589925 (closed) (epic &20933).

🤖 Generated with Claude Code

Merge request reports

Loading