feat(registry): add Custom Discoverer interface (#767)#4130
Open
btlqql wants to merge 1 commit into
Open
Conversation
Resolve higress-group#767. Add a standard Discoverer interface so users can plug custom registration centers (e.g. xDS or HTTP watch based) into Higress through the existing Reconciler/Cache pipeline, instead of having to add a dedicated watcher package per registry type. The interface mirrors the Prometheus discovery.Discoverer contract: type Discoverer interface { Run(ctx context.Context, up chan<- []*TargetGroup) } A TargetGroup carries a list of labeled targets (the "__instance__" label holds "host:port", optional labels include "protocol" and "hostname") and shared group labels (the "job"/"__service__" label names the service). Implementations are registered by registry type via RegisterDiscoverer (the standard Go factory-registration pattern, like database/sql.Register) and built from the full McpBridge RegistryConfig, so they can reuse fields such as Domain, Port, Protocol and Metadata. The reconciler now falls back to a registered discoverer for any registry type that is not one of the built-in ones (nacos/zookeeper/consul/eureka/static/dns); an adapter watcher converts every discovery snapshot into ingress.ServiceWrapper entries stored in the shared memory cache, reconciling additions and removals on each update. Native TargetGroup/LabelSet types are used instead of importing github.com/prometheus/prometheus so the core registry package does not pull in the heavyweight Prometheus module as a direct dependency; the structure and semantics match Prometheus' targetgroup.Group/model.LabelSet exactly. This reuses the existing service-discovery pipeline (no new push mechanism) and is complementary to MCP-based discovery: an MCP-over-xDS discoverer can be registered the same way, as mentioned in the issue discussion. Signed-off-by: btlqql <2977859784@qq.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does
Resolves #767 by adding a standard Custom Discoverer interface so users can plug custom registration centers (e.g. xDS or HTTP watch based) into Higress through the existing service-discovery pipeline, instead of adding a dedicated watcher package for every new registry type.
The interface mirrors the Prometheus
discovery.Discoverercontract requested in the issue:A discoverer reports the full current snapshot of target groups on every update (not a delta), exactly like Prometheus discoverers.
How it is wired
registry.RegisterDiscoverer(type, factory)registers aDiscovererFactoryunder a registry type (standard Go factory pattern, likedatabase/sql.Register). The factory receives the fullMcpBridgeRegistryConfigplus the resolvedAuthOption, so custom discoverers can reuse existing fields such asDomain,Port,ProtocolandMetadata.Reconciler.generateWatcherFromRegistryConfignow falls back to a registered discoverer for any registry type that is not one of the built-in ones (nacos/nacos2/nacos3/zookeeper/consul/static/dns/eureka). An adapter watcher (registry/custom) runs the discoverer and converts every snapshot intoingress.ServiceWrapperentries in the shared memory cache, reconciling additions and removals on each update and cleaning up onStop()— identical lifecycle to the built-in watchers.RegistryConfig.type.Why native types instead of
github.com/prometheus/prometheusThe issue's example uses Prometheus'
targetgroup.Group/model.LabelSet. Those modules are already indirect dependencies, but promoting the very largeprometheus/prometheusmodule to a direct dependency of the coreregistrypackage would add significant weight and version risk for no semantic gain. The introducedTargetGroup/LabelSettypes mirror the Prometheus structure and semantics exactly, keeping the registry package self-contained.Relationship to MCP
As discussed in the issue, MCP-based discovery remains supported and is complementary: an MCP-over-xDS discoverer can be registered through this same interface. This change reuses the existing Reconciler/Cache/push pipeline rather than introducing a new push mechanism.
Changes
registry/discoverer.go—Discovererinterface,TargetGroup/LabelSettypes, label constants, and theRegisterDiscoverer/LookupDiscovererFactoryfactory registry.registry/custom/watcher.go— adapter that bridges aDiscovererto theWatcherinterface, including theTargetGroup→ServiceEntry/ServiceWrapperconversion (host:port + protocol parsing, IPv4/IPv6, default-HTTP fallback, snapshot reconciliation).registry/reconcile/reconcile.go— dispatch unknown registry types to a registered discoverer factory.registry/discoverer_test.go,registry/custom/watcher_test.go— unit tests for registration (duplicate/invalid panics, lookup), conversion edge cases (invalid instances, service-name resolution, IPv6, protocol fallback) and the adapter lifecycle (add/update/remove/stop) including-race.Verification
go build ./registry/... ./pkg/ingress/config/... ./pkg/bootstrap/...— passes (downstream consumers of the reconciler build cleanly).go test ./registry/ ./registry/custom/— passes, includinggo test -race -count=3.go vet ./registry ./registry/custom ./registry/reconcile— clean.gofmt— clean for all added/changed files.go.mod/go.sum— unchanged (no new dependencies introduced).Pre-existing failures in
registry/nacosandregistry/nacos/v2(Test_generateServiceEntry_Weight,Test_generateServiceEntry_WeightFieldSet) are unrelated to this change and reproduce on the unmodified base commit.Notes / assumptions
customtype constant is also exported). They are responsible for providing unique service host names via thejob/__service__group label orSource, since the cache is keyed by host.