This is an automated email from the ASF dual-hosted git repository.
Alanxtl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/develop by this push:
new 581b831ae docs(registry): complete Registry Options comments and unit
test cove… (#3653)
581b831ae is described below
commit 581b831aee8bcd3a288248c3998928446cfc56ef
Author: 641-git641 <[email protected]>
AuthorDate: Thu Aug 13 21:56:11 2026 +0800
docs(registry): complete Registry Options comments and unit test cove…
(#3653)
* docs(registry): complete Registry Options comments and unit test coverage
* docs(registry): format imports with imports-formatter
---------
Co-authored-by: 641-git641 <[email protected]>
---
registry/options.go | 42 +++++++++
registry/options_test.go | 226 ++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 237 insertions(+), 31 deletions(-)
diff --git a/registry/options.go b/registry/options.go
index ba309827a..6f8a90390 100644
--- a/registry/options.go
+++ b/registry/options.go
@@ -27,6 +27,8 @@ import (
"dubbo.apache.org/dubbo-go/v3/global"
)
+// Options wraps the registry configuration. ID distinguishes this
+// registry from others when multiple registries are configured.
type Options struct {
Registry *global.RegistryConfig
@@ -39,6 +41,8 @@ func defaultOptions() *Options {
}
}
+// NewOptions builds Options from the defaults and the given options.
+// A registry protocol must be specified, otherwise it panics.
func NewOptions(opts ...Option) *Options {
defOpts := defaultOptions()
for _, opt := range opts {
@@ -55,32 +59,39 @@ func NewOptions(opts ...Option) *Options {
return defOpts
}
+// Option configures the registry options.
type Option func(*Options)
+// WithEtcdV3 uses etcd v3 as the registry backend.
func WithEtcdV3() Option {
return func(opts *Options) {
opts.Registry.Protocol = constant.EtcdV3Key
}
}
+// WithNacos uses Nacos as the registry backend.
func WithNacos() Option {
return func(opts *Options) {
opts.Registry.Protocol = constant.NacosKey
}
}
+// WithPolaris uses Polaris as the registry backend.
func WithPolaris() Option {
return func(opts *Options) {
opts.Registry.Protocol = constant.PolarisKey
}
}
+// WithZookeeper uses ZooKeeper as the registry backend.
func WithZookeeper() Option {
return func(opts *Options) {
opts.Registry.Protocol = constant.ZookeeperKey
}
}
+// WithRegistry sets the registry backend by protocol name,
+// e.g. WithRegistry("zookeeper").
func WithRegistry(r string) Option {
return func(opts *Options) {
opts.Registry.Protocol = r
@@ -95,30 +106,40 @@ func WithID(id string) Option {
}
}
+// WithTimeout sets the timeout of operations against the registry.
func WithTimeout(timeout time.Duration) Option {
return func(opts *Options) {
opts.Registry.Timeout = timeout.String()
}
}
+// WithGroup sets the registry group. It is often used to isolate
+// environments, like dev and prod, that share one registry.
func WithGroup(group string) Option {
return func(opts *Options) {
opts.Registry.Group = group
}
}
+// WithNamespace sets the namespace of the registry. Only some
+// registries support it, e.g. Nacos.
func WithNamespace(namespace string) Option {
return func(opts *Options) {
opts.Registry.Namespace = namespace
}
}
+// WithTTL sets the TTL of registered instances, after which the
+// registry considers them expired.
func WithTTL(ttl time.Duration) Option {
return func(opts *Options) {
opts.Registry.TTL = ttl.String()
}
}
+// WithAddress sets the address of the registry. When the address
+// carries a scheme, like nacos://127.0.0.1:8848, the protocol is
+// derived from it as well.
func WithAddress(address string) Option {
return func(opts *Options) {
if i := strings.Index(address, "://"); i > 0 {
@@ -128,72 +149,93 @@ func WithAddress(address string) Option {
}
}
+// WithUsername sets the username used to authenticate with the registry.
func WithUsername(name string) Option {
return func(opts *Options) {
opts.Registry.Username = name
}
}
+// WithPassword sets the password used to authenticate with the registry.
func WithPassword(password string) Option {
return func(opts *Options) {
opts.Registry.Password = password
}
}
+// WithSimplified enables the simplified registration mode, which
+// registers less metadata to the registry.
func WithSimplified() Option {
return func(opts *Options) {
opts.Registry.Simplified = true
}
}
+// WithPreferred marks the registry as preferred, so it is always
+// used first when subscribing to multiple registries.
func WithPreferred() Option {
return func(opts *Options) {
opts.Registry.Preferred = true
}
}
+// WithZone sets the zone of the registry, usually to isolate
+// traffic by region.
func WithZone(zone string) Option {
return func(opts *Options) {
opts.Registry.Zone = zone
}
}
+// WithWeight sets the weight of the registry, which affects the
+// traffic distribution among registries. It is ignored when a
+// preferred registry is configured.
func WithWeight(weight int64) Option {
return func(opts *Options) {
opts.Registry.Weight = weight
}
}
+// WithParams sets extra params of the registry, which are passed
+// through to the registry implementation.
func WithParams(params map[string]string) Option {
return func(opts *Options) {
opts.Registry.Params = params
}
}
+// WithRegisterServiceAndInterface registers both services and
+// interfaces with the registry.
func WithRegisterServiceAndInterface() Option {
return func(opts *Options) {
opts.Registry.RegistryType = constant.RegistryTypeAll
}
}
+// WithRegisterInterface registers interfaces only.
func WithRegisterInterface() Option {
return func(opts *Options) {
opts.Registry.RegistryType = constant.RegistryTypeInterface
}
}
+// WithRegisterService registers services only.
func WithRegisterService() Option {
return func(opts *Options) {
opts.Registry.RegistryType = constant.RegistryTypeService
}
}
+// WithoutUseAsMetaReport disables the registry being used as the
+// metadata report.
func WithoutUseAsMetaReport() Option {
return func(opts *Options) {
opts.Registry.UseAsMetaReport = "false"
}
}
+// WithoutUseAsConfigCenter disables the registry being used as the
+// config center.
func WithoutUseAsConfigCenter() Option {
return func(opts *Options) {
opts.Registry.UseAsConfigCenter = "false"
diff --git a/registry/options_test.go b/registry/options_test.go
index ece7f6a04..02b6a9095 100644
--- a/registry/options_test.go
+++ b/registry/options_test.go
@@ -28,6 +28,7 @@ import (
import (
"dubbo.apache.org/dubbo-go/v3/common/constant"
+ "dubbo.apache.org/dubbo-go/v3/global"
)
func TestNewOptionsRequireProtocol(t *testing.T) {
@@ -36,54 +37,217 @@ func TestNewOptionsRequireProtocol(t *testing.T) {
})
}
+func testRegistryConfig(protocol string, set ...func(*global.RegistryConfig))
*global.RegistryConfig {
+ cfg := global.DefaultRegistryConfig()
+ cfg.Protocol = protocol
+ for _, f := range set {
+ f(cfg)
+ }
+ return cfg
+}
+
func TestNewOptionsWithHelpers(t *testing.T) {
tests := []struct {
- name string
- opts []Option
- wantProtocol string
- wantID string
- wantTimeout string
- wantAddress string
+ name string
+ opts []Option
+ wantID string
+ want *global.RegistryConfig
}{
{
- name: "zookeeper default id",
- opts: []Option{WithZookeeper()},
- wantProtocol: constant.ZookeeperKey,
- wantID: constant.ZookeeperKey,
+ name: "zookeeper default id",
+ opts: []Option{WithZookeeper()},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey),
+ },
+
+ {
+ name: "etcd with custom id",
+ opts: []Option{WithEtcdV3(), WithID("custom-id")},
+ wantID: "custom-id",
+ want: testRegistryConfig(constant.EtcdV3Key),
+ },
+
+ {
+ name: "nacos protocol",
+ opts: []Option{WithNacos()},
+ wantID: constant.NacosKey,
+ want: testRegistryConfig(constant.NacosKey),
+ },
+
+ {
+ name: "polaris protocol",
+ opts: []Option{WithPolaris()},
+ wantID: constant.PolarisKey,
+ want: testRegistryConfig(constant.PolarisKey),
+ },
+
+ {
+ name: "registry by name",
+ opts: []Option{WithRegistry(constant.ZookeeperKey)},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey),
+ },
+
+ {
+ name: "address overrides protocol",
+ opts: []Option{WithAddress("nacos://127.0.0.1:8848")},
+ wantID: constant.NacosKey,
+ want: testRegistryConfig(constant.NacosKey, func(c
*global.RegistryConfig) {
+ c.Address = "nacos://127.0.0.1:8848"
+ }),
+ },
+
+ {
+ name: "address without scheme",
+ opts: []Option{WithZookeeper(),
WithAddress("127.0.0.1:2181")},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Address = "127.0.0.1:2181"
+ }),
+ },
+
+ {
+ name: "timeout option",
+ opts: []Option{WithZookeeper(), WithTimeout(3 *
time.Second)},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Timeout = "3s"
+ }),
+ },
+
+ {
+ name: "ttl option",
+ opts: []Option{WithZookeeper(), WithTTL(30 *
time.Minute)},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.TTL = "30m0s"
+ }),
+ },
+
+ {
+ name: "group option",
+ opts: []Option{WithZookeeper(), WithGroup("dev")},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Group = "dev"
+ }),
},
+
+ {
+ name: "namespace option",
+ opts: []Option{WithZookeeper(), WithNamespace("ns")},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Namespace = "ns"
+ }),
+ },
+
+ {
+ name: "username and password",
+ opts: []Option{WithZookeeper(), WithUsername("user"),
WithPassword("pass")},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Username = "user"
+ c.Password = "pass"
+ }),
+ },
+
+ {
+ name: "simplified option",
+ opts: []Option{WithZookeeper(), WithSimplified()},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Simplified = true
+ }),
+ },
+
+ {
+ name: "preferred option",
+ opts: []Option{WithZookeeper(), WithPreferred()},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Preferred = true
+ }),
+ },
+
+ {
+ name: "zone option",
+ opts: []Option{WithZookeeper(), WithZone("zone-a")},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Zone = "zone-a"
+ }),
+ },
+
+ {
+ name: "weight option",
+ opts: []Option{WithZookeeper(), WithWeight(100)},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Weight = 100
+ }),
+ },
+
{
- name: "etcd with custom id",
- opts: []Option{WithEtcdV3(),
WithID("custom-id")},
- wantProtocol: constant.EtcdV3Key,
- wantID: "custom-id",
+ name: "params option",
+ opts: []Option{WithZookeeper(),
WithParams(map[string]string{"key1": "value1", "key2": "value2"})},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.Params = map[string]string{"key1": "value1",
"key2": "value2"}
+ }),
},
+
+ {
+ name: "register service and interface",
+ opts: []Option{WithZookeeper(),
WithRegisterServiceAndInterface()},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.RegistryType = constant.RegistryTypeAll
+ }),
+ },
+
{
- name: "address overrides protocol",
- opts:
[]Option{WithAddress("nacos://127.0.0.1:8848")},
- wantProtocol: constant.NacosKey,
- wantID: constant.NacosKey,
- wantAddress: "nacos://127.0.0.1:8848",
+ name: "register interface only",
+ opts: []Option{WithZookeeper(),
WithRegisterInterface()},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.RegistryType = constant.RegistryTypeInterface
+ }),
},
+
+ {
+ name: "register service only",
+ opts: []Option{WithZookeeper(),
WithRegisterService()},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.RegistryType = constant.RegistryTypeService
+ }),
+ },
+
+ {
+ name: "not used as meta report",
+ opts: []Option{WithZookeeper(),
WithoutUseAsMetaReport()},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.UseAsMetaReport = "false"
+ }),
+ },
+
{
- name: "timeout option",
- opts: []Option{WithZookeeper(), WithTimeout(3 *
time.Second)},
- wantProtocol: constant.ZookeeperKey,
- wantID: constant.ZookeeperKey,
- wantTimeout: "3s",
+ name: "not used as config center",
+ opts: []Option{WithZookeeper(),
WithoutUseAsConfigCenter()},
+ wantID: constant.ZookeeperKey,
+ want: testRegistryConfig(constant.ZookeeperKey, func(c
*global.RegistryConfig) {
+ c.UseAsConfigCenter = "false"
+ }),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
options := NewOptions(tt.opts...)
- assert.Equal(t, tt.wantProtocol,
options.Registry.Protocol)
+ assert.Equal(t, tt.want, options.Registry)
assert.Equal(t, tt.wantID, options.ID)
- if tt.wantTimeout != "" {
- assert.Equal(t, tt.wantTimeout,
options.Registry.Timeout)
- }
- if tt.wantAddress != "" {
- assert.Equal(t, tt.wantAddress,
options.Registry.Address)
- }
})
}
}