Skip to content

refactor: extract reusable building blocks from K8s and Nacos discovery#13201

Merged
nic-6443 merged 11 commits into
apache:masterfrom
nic-6443:refactor/discovery-extract-building-blocks
Apr 14, 2026
Merged

refactor: extract reusable building blocks from K8s and Nacos discovery#13201
nic-6443 merged 11 commits into
apache:masterfrom
nic-6443:refactor/discovery-extract-building-blocks

Conversation

@nic-6443

@nic-6443 nic-6443 commented Apr 11, 2026

Copy link
Copy Markdown
Member

Summary

Refactor Kubernetes and Nacos service discovery modules to extract reusable building blocks. This makes the discovery modules more composable — external consumers can create custom discovery handles, reuse endpoint processing callbacks, and build on top of the Nacos HTTP client without duplicating internal logic.

Kubernetes

Extract kubernetes/core.lua (~750 lines) from init.lua:

  • get_apiserver(), setup_namespace_selector(), setup_label_selector()
  • create_endpoint_callbacks(options) — parameterized informer callbacks with key_prefix and duplicate_port_number support
  • create_handle(conf, options) — creates a fully configured informer handle
  • start_fetch(handle) — starts the list/watch loop with stop support
  • resolve_nodes() — LRU-cached node resolution from shared dict

Refactored init.lua to use core.lua (875→265 lines, behavior unchanged).

Enhanced informer_factory.lua:

  • Graceful stop support (informer.stop flag checked at 4 points)
  • ssl_server_name for HTTPS connections
  • Configurable ssl_verify (reads from apiserver.ssl_verify)

Nacos

Extract nacos/client.lua (~360 lines) from init.lua:

  • request(), get_token_param(), get_signed_param()
  • build_base_uri() — URL parsing with embedded credential support
  • fetch_from_host() — fetch instances with key_builder and preserve_metadata options
  • get_nacos_services(filter) — scan APISIX config for nacos references

Redesign nacos/init.lua with multi-instance registry abstraction:

  • create_registry(conf, options) / start_registry(reg) / stop_registry(id)
  • Each registry identified by id (currently hardcoded to "default")
  • Dict keys use {id}/{ns}/{group}/{svc} format for future multi-instance support
  • Self-rescheduling timer with stop flag (prevents overlap and supports graceful shutdown)
  • Deferred shared dict access (no longer errors at module load time)

No behavior change for existing users.

Code line change analysis

Total: +1379 / -973 (net +406)

The net increase comes from extracting shared code into new files:

File +/- Explanation
kubernetes/core.lua +752 (new) Shared building blocks extracted from init.lua
kubernetes/init.lua -617 (net) Gutted — now a thin wrapper over core.lua
kubernetes/informer_factory.lua +26 Stop support, ssl_server_name, ssl_verify
nacos/client.lua +365 (new) HTTP client extracted from init.lua
nacos/init.lua -115 (net) Multi-instance registry rewrite, simpler than before
test files +3 Shared dict config, updated test patterns

Why the net is positive: core.lua (+752) and client.lua (+365) are new files that contain code previously inlined in init.lua. The corresponding init.lua deletions (-617 and -115) don't fully offset because the new files also add proper doc comments, validation, and the multi-instance registry API that didn't exist before. The actual duplicated logic is reduced — the "new" code is mostly moved code plus ~150 lines of new API surface (registry lifecycle, deferred dict access, stop-flag handling).

Copilot AI review requested due to automatic review settings April 11, 2026 03:48
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. enhancement New feature or request labels Apr 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors APISIX service discovery by extracting reusable core logic from the Kubernetes and Nacos discovery implementations into standalone modules, enabling external consumers to reuse the underlying primitives while keeping existing discovery module APIs stable.

Changes:

  • Added reusable Kubernetes discovery building blocks (apisix/discovery/kubernetes/core.lua) and refactored the Kubernetes discovery init module to use them.
  • Added a reusable Nacos HTTP client module (apisix/discovery/nacos/client.lua) and refactored the Nacos discovery init module to use it.
  • Enhanced Kubernetes informer factory to support graceful stop and configurable TLS behavior (ssl_verify, ssl_server_name), and extended the Kubernetes discovery schema with ssl_verify.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
apisix/discovery/nacos/init.lua Refactored to use the extracted Nacos client for service scanning and instance fetching.
apisix/discovery/nacos/client.lua New reusable Nacos HTTP client and discovery primitives (auth, signing, URL building, fetching).
apisix/discovery/kubernetes/schema.lua Adds service.ssl_verify to schema (single + multi mode).
apisix/discovery/kubernetes/init.lua Refactored to use new kubernetes.core helpers for handle creation, fetch lifecycle, and node resolution.
apisix/discovery/kubernetes/informer_factory.lua Adds stop-flag checks and makes TLS verification + SNI configurable via apiserver settings.
apisix/discovery/kubernetes/core.lua New reusable Kubernetes discovery core (config parsing, callbacks, handle factory, lifecycle, node resolution, dict helpers).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apisix/discovery/kubernetes/init.lua
Comment thread apisix/discovery/kubernetes/init.lua
Comment thread apisix/discovery/kubernetes/schema.lua
Comment thread apisix/discovery/kubernetes/schema.lua
Comment thread apisix/discovery/kubernetes/core.lua
Comment thread apisix/discovery/nacos/client.lua Outdated
Comment thread apisix/discovery/nacos/client.lua Outdated
Comment thread apisix/discovery/nacos/client.lua
Extract kubernetes/core.lua and nacos/client.lua as composable building
blocks from the existing init.lua modules.

kubernetes/core.lua provides:
- Config parsing (get_apiserver, setup_namespace_selector, etc.)
- Parameterized endpoint callbacks via create_endpoint_callbacks()
  with key_prefix for multi-registry dict isolation and
  duplicate_port_number for flexible port key storage
- Handle factory (create_handle) and lifecycle (start_fetch)
- Node resolution with LRU cache (resolve_nodes)
- Dict helpers (dump_endpoints_from_dict)

nacos/client.lua provides:
- Stateless HTTP client primitives (request, get_token_param)
- HMAC-SHA1 signing (get_signed_param)
- URL building (build_base_uri)
- Instance fetching (fetch_from_host) with configurable key_builder,
  preserve_metadata, and timeout
- Service scanning (get_nacos_services) with optional filter

informer_factory.lua enhancements:
- Graceful stop support (informer.stop flag) checked in watch() and
  list_watch() loops
- Configurable ssl_verify (from apiserver config, default false)
- ssl_server_name support for HTTPS connections

schema.lua:
- Add ssl_verify option to service config for both single and
  multiple mode

Both init.lua modules are refactored to use the new building blocks
with no behavior change for existing users.
@nic-6443
nic-6443 force-pushed the refactor/discovery-extract-building-blocks branch from 3e59d07 to a73d7b4 Compare April 13, 2026 04:25
- nacos2.t TEST 5: use 'default/public/DEFAULT_GROUP/svc' key format
- Fix error log format: 'err:' without space (matching original)
- Add nacos-stream shared dict to test framework for stream tests
- Make dict name subsystem-aware (nacos vs nacos-stream)
- Restore original error log format in client.lua
- Add get_nodes(key, metadata) for shared dict access with optional metadata filter
- Move match_metadata logic into apisix layer for reuse by downstream consumers
- Refactor nodes() to use get_nodes() internally
The error log format changed from 'error: status = N' to 'err:status = N'
when client.lua was refactored to use 'get_url:<path> err:<err>' format.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Refactors APISIX Kubernetes and Nacos discovery modules by extracting reusable core/client building blocks, enabling more composable discovery handles and shared logic for endpoint processing and registry fetching.

Changes:

  • Extract Kubernetes discovery building blocks into apisix/discovery/kubernetes/core.lua and refactor kubernetes/init.lua to use them.
  • Extract Nacos HTTP/client primitives into apisix/discovery/nacos/client.lua and redesign nacos/init.lua around a registry abstraction with stream support.
  • Update tests and test Nginx config to reflect new Nacos dict keys and add nacos-stream shared dict.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
t/discovery/nacos2.t Updates expected log output and dump key format for refactored Nacos discovery.
t/APISIX.pm Adds lua_shared_dict nacos-stream for stream subsystem tests.
apisix/discovery/nacos/init.lua Introduces registry abstraction and refactors periodic fetch/cleanup logic.
apisix/discovery/nacos/client.lua Adds reusable Nacos HTTP client, auth/signing, URL parsing, fetch and config scanning.
apisix/discovery/kubernetes/schema.lua Adjusts Kubernetes discovery schema content (description removal only).
apisix/discovery/kubernetes/init.lua Refactors to use extracted Kubernetes core helpers/handle factory.
apisix/discovery/kubernetes/informer_factory.lua Adds stop checks and supports ssl_server_name/ssl_verify wiring.
apisix/discovery/kubernetes/core.lua New extracted Kubernetes discovery core: callbacks, handle creation, fetch lifecycle, node resolution, dump helpers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apisix/discovery/nacos/client.lua
Comment thread apisix/discovery/nacos/client.lua
Comment thread apisix/discovery/nacos/client.lua
Comment thread apisix/discovery/nacos/init.lua
Comment thread apisix/discovery/nacos/init.lua
Comment thread apisix/discovery/kubernetes/core.lua
- Add nil guard in build_base_uri for malformed URLs without protocol
- Add id validation and auto-stop in create_registry
- Fix resolve_nodes doc comment to include endpoint_port return value
The original nacos nodes() had a 5-second wait loop for the initial
fetch to complete. The refactored version returned nil immediately
before data was populated, causing 503 errors in tests.

Add fetch_done flag to registries and restore the wait loop in the
standard nodes() interface.
Add info-level log after dict:set loop completes so operators and
tests can reliably detect when nacos nodes are stored.
membphis
membphis previously approved these changes Apr 13, 2026
Revert the fetch_done flag and wait loop. The standard APISIX discovery
interface returns nil when data is not yet available; callers handle retry
at the proxy layer.
@nic-6443
nic-6443 requested a review from membphis April 14, 2026 04:16
@nic-6443
nic-6443 merged commit 5962e73 into apache:master Apr 14, 2026
19 checks passed
@nic-6443
nic-6443 deleted the refactor/discovery-extract-building-blocks branch April 14, 2026 04:29
nic-6443 added a commit to nic-6443/apisix that referenced this pull request Apr 16, 2026
Following the pattern established by PR apache#13201 (Nacos + K8s refactor),
refactor the Consul discovery module to support multi-instance registry
API while preserving all existing behavior.

Changes:
- Create client.lua: extracted HTTP/protocol primitives (blocking query
  watchers, service fetching, URL parsing, sort helpers, service scanner)
- Refactor init.lua: add create_registry/start_registry/stop_registry/
  get_registry/get_nodes multi-instance registry API
- Move mutable module state (skip_service_map, dump_params, consul_services,
  default_service) into per-registry reg object
- Shared dict keys now use registry ID prefix ("default/service_name")
  for multi-instance isolation
- all_nodes/dump_data/show_dump_file strip prefix for backward compat
- Add metadata filtering support via get_nodes(key, metadata)
- Preserve privileged-agent-only gating for write operations
- No schema changes, all existing tests should pass
wistefan pushed a commit to wistefan/apisix that referenced this pull request Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants