Repository: go-kratos/kratos
Pull request #3114 (2023-12-11 18:25:41)

build(deps): bump github.com/aliyun/aliyun-log-go-sdk from 0.1.66 to 0.1.67 in /contrib/log/aliyun
Bumps [github.com/aliyun/aliyun-log-go-sdk](https://github.com/aliyun/aliyun-log-go-sdk) from 0.1.66 to 0.1.67.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/aliyun/aliyun-log-go-sdk/releases">github.com/aliyun/aliyun-log-go-sdk's releases</a>.</em></p>
<blockquote>
<h2>v0.1.67</h2>
<p>Consumer support no-ak credentialProvider
Update comments</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/aliyun/aliyun-log-go-sdk/commit/45109e3f7f98ceb6ffb238b81930dfef01c3ab76"><code>45109e3</code></a> consumer add no-ak, refine no-ak document (<a href="https://redirect.github.com/aliyun/aliyun-log-go-sdk/issues/245">#245</a>)</li>
<li><a href="https://github.com/aliyun/aliyun-log-go-sdk/commit/f81acdabff0a1e62f9242ef88075d3b6e211ad24"><code>f81acda</code></a> init (<a href="https://redirect.github.com/aliyun/aliyun-log-go-sdk/issues/242">#242</a>)</li>
<li>See full diff in <a href="https://github.com/aliyun/aliyun-log-go-sdk/compare/v0.1.66...v0.1.67">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/aliyun/aliyun-log-go-sdk&package-manager=go_modules&previous-version=0.1.66&new-version=0.1.67)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/go-kratos/kratos/pull/3114?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`7e2edec`)](https://app.codecov.io/gh/go-kratos/kratos/commit/7e2edecabf320cfebeb8c24b95263b7395daf3c3?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) 84.40% compared to head [(`a55babf`)](https://app.codecov.io/gh/go-kratos/kratos/pull/3114?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) 84.30%.

> :exclamation: Current head a55babf differs from pull request most recent head 08dd4c5. Consider uploading reports for the commit 08dd4c5 to get more accurate results


:exclamation: Your organization needs to install the [Codecov GitHub app](https://github.com/apps/codecov/installations/select_target) to enable full functionality.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #3114      +/-   ##
==========================================
- Coverage   84.40%   84.30%   -0.11%     
==========================================
  Files          88       88              
  Lines        3983     3983              
==========================================
- Hits         3362     3358       -4     
- Misses        446      448       +2     
- Partials      175      177       +2     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/go-kratos/kratos/pull/3114?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).


Patch:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index a8717450..b28a5a28 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -44,7 +44,7 @@ jobs:
     steps:
       - uses: actions/checkout@v4
       - name: Set up Go
-        uses: actions/setup-go@v4.1.0
+        uses: actions/setup-go@v5.0.0
         with:
           go-version: ${{ matrix.go }}
 
diff --git a/app.go b/app.go
index 88532891..2fa52ec9 100644
--- a/app.go
+++ b/app.go
@@ -30,7 +30,7 @@ type AppInfo interface {
 type App struct {
 	opts     options
 	ctx      context.Context
-	cancel   func()
+	cancel   context.CancelFunc
 	mu       sync.Mutex
 	instance *registry.ServiceInstance
 }
diff --git a/contrib/config/consul/config.go b/contrib/config/consul/config.go
index 0404801b..108f0082 100644
--- a/contrib/config/consul/config.go
+++ b/contrib/config/consul/config.go
@@ -11,7 +11,7 @@ import (
 	"github.com/go-kratos/kratos/v2/config"
 )
 
-// Option is etcd config option.
+// Option is consul config option.
 type Option func(o *options)
 
 type options struct {
diff --git a/contrib/config/consul/watcher.go b/contrib/config/consul/watcher.go
index 5562505c..6a8db3a5 100644
--- a/contrib/config/consul/watcher.go
+++ b/contrib/config/consul/watcher.go
@@ -2,6 +2,8 @@ package consul
 
 import (
 	"context"
+	"path/filepath"
+	"strings"
 
 	"github.com/hashicorp/consul/api"
 	"github.com/hashicorp/consul/api/watch"
@@ -10,12 +12,12 @@ import (
 )
 
 type watcher struct {
-	source *source
-	ch     chan interface{}
-	wp     *watch.Plan
-
-	ctx    context.Context
-	cancel context.CancelFunc
+	source          *source
+	ch              chan []*config.KeyValue
+	wp              *watch.Plan
+	fileModifyIndex map[string]uint64
+	ctx             context.Context
+	cancel          context.CancelFunc
 }
 
 func (w *watcher) handle(_ uint64, data interface{}) {
@@ -23,22 +25,47 @@ func (w *watcher) handle(_ uint64, data interface{}) {
 		return
 	}
 
-	_, ok := data.(api.KVPairs)
+	kv, ok := data.(api.KVPairs)
 	if !ok {
 		return
 	}
 
-	w.ch <- struct{}{}
+	pathPrefix := w.source.options.path
+	if !strings.HasSuffix(w.source.options.path, "/") {
+		pathPrefix = pathPrefix + "/"
+	}
+	kvs := make([]*config.KeyValue, 0, len(kv))
+	for _, item := range kv {
+		if index, ok := w.fileModifyIndex[item.Key]; ok && item.ModifyIndex == index {
+			continue
+		}
+		k := strings.TrimPrefix(item.Key, pathPrefix)
+		if k == "" {
+			continue
+		}
+		kvs = append(kvs, &config.KeyValue{
+			Key:    k,
+			Value:  item.Value,
+			Format: strings.TrimPrefix(filepath.Ext(k), "."),
+		})
+		w.fileModifyIndex[item.Key] = item.ModifyIndex
+	}
+
+	if len(kvs) == 0 {
+		return
+	}
+
+	w.ch <- kvs
 }
 
 func newWatcher(s *source) (*watcher, error) {
 	ctx, cancel := context.WithCancel(context.Background())
 	w := &watcher{
-		source: s,
-		ch:     make(chan interface{}),
-
-		ctx:    ctx,
-		cancel: cancel,
+		source:          s,
+		ch:              make(chan []*config.KeyValue),
+		fileModifyIndex: make(map[string]uint64),
+		ctx:             ctx,
+		cancel:          cancel,
 	}
 
 	wp, err := watch.Parse(map[string]interface{}{"type": "keyprefix", "prefix": s.options.path})
@@ -62,8 +89,8 @@ func newWatcher(s *source) (*watcher, error) {
 
 func (w *watcher) Next() ([]*config.KeyValue, error) {
 	select {
-	case <-w.ch:
-		return w.source.Load()
+	case kv := <-w.ch:
+		return kv, nil
 	case <-w.ctx.Done():
 		return nil, w.ctx.Err()
 	}
diff --git a/contrib/log/aliyun/go.mod b/contrib/log/aliyun/go.mod
index 822341a5..965919f4 100644
--- a/contrib/log/aliyun/go.mod
+++ b/contrib/log/aliyun/go.mod
@@ -3,7 +3,7 @@ module github.com/go-kratos/kratos/contrib/log/aliyun/v2
 go 1.19
 
 require (
-	github.com/aliyun/aliyun-log-go-sdk v0.1.66
+	github.com/aliyun/aliyun-log-go-sdk v0.1.67
 	github.com/go-kratos/kratos/v2 v2.7.2
 	google.golang.org/protobuf v1.31.0
 )
diff --git a/contrib/log/aliyun/go.sum b/contrib/log/aliyun/go.sum
index b921ec4c..b4300ff2 100644
--- a/contrib/log/aliyun/go.sum
+++ b/contrib/log/aliyun/go.sum
@@ -40,8 +40,8 @@ github.com/alibabacloud-go/tea-utils/v2 v2.0.1 h1:K6kwgo+UiYx+/kr6CO0PN5ACZDzE3n
 github.com/alibabacloud-go/tea-utils/v2 v2.0.1/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4=
 github.com/alibabacloud-go/tea-xml v1.1.2 h1:oLxa7JUXm2EDFzMg+7oRsYc+kutgCVwm+bZlhhmvW5M=
 github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
-github.com/aliyun/aliyun-log-go-sdk v0.1.66 h1:my4x9WLaHgkf5AUgefX+/6KTlcuAPvlgWOT8Aroi9sI=
-github.com/aliyun/aliyun-log-go-sdk v0.1.66/go.mod h1:FSKcIjukUy+LeUKhRk13PCO+9gPMTfGsYhFBHQbDqmM=
+github.com/aliyun/aliyun-log-go-sdk v0.1.67 h1:/V3ZGhGSRud7Q0nY54zdnDOBrf1rMhJdHd+lXD5h028=
+github.com/aliyun/aliyun-log-go-sdk v0.1.67/go.mod h1:FSKcIjukUy+LeUKhRk13PCO+9gPMTfGsYhFBHQbDqmM=
 github.com/aliyun/credentials-go v1.1.2 h1:qU1vwGIBb3UJ8BwunHDRFtAhS6jnQLnde/yk0+Ih2GY=
 github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
diff --git a/contrib/polaris/go.mod b/contrib/polaris/go.mod
index 7dd7c735..46225dca 100644
--- a/contrib/polaris/go.mod
+++ b/contrib/polaris/go.mod
@@ -16,7 +16,7 @@ require (
 	github.com/dlclark/regexp2 v1.7.0 // indirect
 	github.com/go-playground/form/v4 v4.2.0 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
-	github.com/gorilla/mux v1.8.0 // indirect
+	github.com/gorilla/mux v1.8.1 // indirect
 	github.com/hashicorp/errwrap v1.0.0 // indirect
 	github.com/hashicorp/go-multierror v1.1.1 // indirect
 	github.com/imdario/mergo v0.3.16 // indirect
diff --git a/contrib/polaris/go.sum b/contrib/polaris/go.sum
index c457f9a0..69b19318 100644
--- a/contrib/polaris/go.sum
+++ b/contrib/polaris/go.sum
@@ -159,8 +159,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
+github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
 github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
diff --git a/contrib/registry/etcd/go.mod b/contrib/registry/etcd/go.mod
index 4e02ca5b..ecac7c4c 100644
--- a/contrib/registry/etcd/go.mod
+++ b/contrib/registry/etcd/go.mod
@@ -4,7 +4,7 @@ go 1.19
 
 require (
 	github.com/go-kratos/kratos/v2 v2.7.2
-	go.etcd.io/etcd/client/v3 v3.5.10
+	go.etcd.io/etcd/client/v3 v3.5.11
 	google.golang.org/grpc v1.59.0
 )
 
@@ -13,8 +13,8 @@ require (
 	github.com/coreos/go-systemd/v22 v22.3.2 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
-	go.etcd.io/etcd/api/v3 v3.5.10 // indirect
-	go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect
+	go.etcd.io/etcd/api/v3 v3.5.11 // indirect
+	go.etcd.io/etcd/client/pkg/v3 v3.5.11 // indirect
 	go.uber.org/atomic v1.7.0 // indirect
 	go.uber.org/multierr v1.6.0 // indirect
 	go.uber.org/zap v1.17.0 // indirect
diff --git a/contrib/registry/etcd/go.sum b/contrib/registry/etcd/go.sum
index 460bf8b8..b4f18ce1 100644
--- a/contrib/registry/etcd/go.sum
+++ b/contrib/registry/etcd/go.sum
@@ -22,15 +22,15 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k=
-go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI=
-go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0=
-go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U=
-go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao=
-go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc=
+go.etcd.io/etcd/api/v3 v3.5.11 h1:B54KwXbWDHyD3XYAwprxNzTe7vlhR69LuBgZnMVvS7E=
+go.etcd.io/etcd/api/v3 v3.5.11/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4=
+go.etcd.io/etcd/client/pkg/v3 v3.5.11 h1:bT2xVspdiCj2910T0V+/KHcVKjkUrCZVtk8J2JF2z1A=
+go.etcd.io/etcd/client/pkg/v3 v3.5.11/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4=
+go.etcd.io/etcd/client/v3 v3.5.11 h1:ajWtgoNSZJ1gmS8k+icvPtqsqEav+iUorF7b0qozgUU=
+go.etcd.io/etcd/client/v3 v3.5.11/go.mod h1:a6xQUEqFJ8vztO1agJh/KQKOMfFI8og52ZconzcDJwE=
 go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
diff --git a/contrib/registry/eureka/eureka.go b/contrib/registry/eureka/eureka.go
index a7759dee..530b638c 100644
--- a/contrib/registry/eureka/eureka.go
+++ b/contrib/registry/eureka/eureka.go
@@ -58,9 +58,9 @@ func (e *API) broadcast() {
 	for _, subscriber := range e.subscribers {
 		go subscriber.callBack()
 	}
-	defer e.lock.Unlock()
 	e.lock.Lock()
 	e.allInstances = instances
+	e.lock.Unlock()
 }
 
 func (e *API) cacheAllInstances() map[string][]Instance {
@@ -106,12 +106,12 @@ func (e *API) Deregister(ctx context.Context, endpoints []Endpoint) error {
 
 func (e *API) Subscribe(serverName string, fn func()) error {
 	e.lock.Lock()
-	defer e.lock.Unlock()
 	appID := e.ToAppID(serverName)
 	e.subscribers[appID] = &subscriber{
 		appID:    appID,
 		callBack: fn,
 	}
+	e.lock.Unlock()
 	go e.broadcast()
 	return nil
 }
@@ -128,8 +128,8 @@ func (e *API) GetService(ctx context.Context, serverName string) []Instance {
 
 func (e *API) Unsubscribe(serverName string) {
 	e.lock.Lock()
-	defer e.lock.Unlock()
 	delete(e.subscribers, e.ToAppID(serverName))
+	e.lock.Unlock()
 }
 
 func (e *API) ToAppID(serverName string) string {
diff --git a/contrib/registry/eureka/register.go b/contrib/registry/eureka/register.go
index 242ec910..f7226ce2 100644
--- a/contrib/registry/eureka/register.go
+++ b/contrib/registry/eureka/register.go
@@ -54,7 +54,11 @@ func New(eurekaUrls []string, opts ...Option) (*Registry, error) {
 		o(r)
 	}
 
-	client := NewClient(eurekaUrls, WithHeartbeatInterval(r.heartbeatInterval), WithClientContext(r.ctx), WithNamespace(r.eurekaPath))
+	client := NewClient(eurekaUrls,
+		WithHeartbeatInterval(r.heartbeatInterval),
+		WithClientContext(r.ctx),
+		WithNamespace(r.eurekaPath),
+	)
 	r.api = NewAPI(r.ctx, client, r.refreshInterval)
 	return r, nil
 }
diff --git a/contrib/registry/nacos/go.mod b/contrib/registry/nacos/go.mod
index c6e5e1c9..19e95ce0 100644
--- a/contrib/registry/nacos/go.mod
+++ b/contrib/registry/nacos/go.mod
@@ -9,7 +9,7 @@ require (
 
 require (
 	github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 // indirect
-	github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect
+	github.com/buger/jsonparser v1.1.1 // indirect
 	github.com/go-errors/errors v1.0.1 // indirect
 	github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
 	github.com/json-iterator/go v1.1.6 // indirect
diff --git a/contrib/registry/polaris/registry.go b/contrib/registry/polaris/registry.go
index d9b87150..e968fe38 100644
--- a/contrib/registry/polaris/registry.go
+++ b/contrib/registry/polaris/registry.go
@@ -376,7 +376,7 @@ func (w *Watcher) Next() ([]*registry.ServiceInstance, error) {
 							if serviceInstance.ID == instance.GetId() {
 								// remove equal
 								if len(w.ServiceInstances) <= 1 {
-									w.ServiceInstances = w.ServiceInstances[0:0]
+									w.ServiceInstances = w.ServiceInstances[:0]
 									continue
 								}
 								w.ServiceInstances = append(w.ServiceInstances[:i], w.ServiceInstances[i+1:]...)
diff --git a/go.mod b/go.mod
index 4280a65a..33874fec 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/go-playground/form/v4 v4.2.0
 	github.com/golang-jwt/jwt/v5 v5.1.0
 	github.com/google/uuid v1.3.0
-	github.com/gorilla/mux v1.8.0
+	github.com/gorilla/mux v1.8.1
 	github.com/imdario/mergo v0.3.16
 	go.opentelemetry.io/otel v1.16.0
 	go.opentelemetry.io/otel/sdk v1.16.0
diff --git a/go.sum b/go.sum
index fee7466d..340d04fb 100644
--- a/go.sum
+++ b/go.sum
@@ -33,8 +33,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
+github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
 github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
 github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
 github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
diff --git a/selector/filter/version.go b/selector/filter/version.go
index 21f8518a..a5374470 100644
--- a/selector/filter/version.go
+++ b/selector/filter/version.go
@@ -9,7 +9,7 @@ import (
 // Version is version filter.
 func Version(version string) selector.NodeFilter {
 	return func(_ context.Context, nodes []selector.Node) []selector.Node {
-		newNodes := make([]selector.Node, 0)
+		newNodes := make([]selector.Node, 0, len(nodes))
 		for _, n := range nodes {
 			if n.Version() == version {
 				newNodes = append(newNodes, n)
diff --git a/transport/grpc/client.go b/transport/grpc/client.go
index d3c24617..edc57d3e 100644
--- a/transport/grpc/client.go
+++ b/transport/grpc/client.go
@@ -39,7 +39,7 @@ func WithEndpoint(endpoint string) ClientOption {
 	}
 }
 
-// WithSubset with client disocvery subset size.
+// WithSubset with client discovery subset size.
 // zero value means subset filter disabled
 func WithSubset(size int) ClientOption {
 	return func(o *clientOptions) {
diff --git a/transport/grpc/resolver/direct/builder.go b/transport/grpc/resolver/direct/builder.go
index ebbd22d7..a81b77af 100644
--- a/transport/grpc/resolver/direct/builder.go
+++ b/transport/grpc/resolver/direct/builder.go
@@ -6,6 +6,8 @@ import (
 	"google.golang.org/grpc/resolver"
 )
 
+const name = "direct"
+
 func init() {
 	resolver.Register(NewBuilder())
 }
@@ -35,5 +37,5 @@ func (d *directBuilder) Build(target resolver.Target, cc resolver.ClientConn, _
 }
 
 func (d *directBuilder) Scheme() string {
-	return "direct"
+	return name
 }
diff --git a/transport/http/client.go b/transport/http/client.go
index 7784a1c2..2d013ffa 100644
--- a/transport/http/client.go
+++ b/transport/http/client.go
@@ -56,7 +56,7 @@ type clientOptions struct {
 	subsetSize   int
 }
 
-// WithSubset with client disocvery subset size.
+// WithSubset with client discovery subset size.
 // zero value means subset filter disabled
 func WithSubset(size int) ClientOption {
 	return func(o *clientOptions) {
diff --git a/transport/http/resolver.go b/transport/http/resolver.go
index bcbf8f3b..e0db0cb6 100644
--- a/transport/http/resolver.go
+++ b/transport/http/resolver.go
@@ -56,7 +56,7 @@ type resolver struct {
 func newResolver(ctx context.Context, discovery registry.Discovery, target *Target,
 	rebalancer selector.Rebalancer, block, insecure bool, subsetSize int,
 ) (*resolver, error) {
-	// this is new resovler
+	// this is new resolver
 	watcher, err := discovery.Watch(ctx, target.Endpoint)
 	if err != nil {
 		return nil, err
diff --git a/transport/http/server.go b/transport/http/server.go
index 9958a08a..c967e4a1 100644
--- a/transport/http/server.go
+++ b/transport/http/server.go
@@ -134,7 +134,7 @@ func Listener(lis net.Listener) ServerOption {
 	}
 }
 
-// PathPrefix with mux's PathPrefix, router will replaced by a subrouter that start with prefix.
+// PathPrefix with mux's PathPrefix, router will be replaced by a subrouter that start with prefix.
 func PathPrefix(prefix string) ServerOption {
 	return func(s *Server) {
 		s.router = s.router.PathPrefix(prefix).Subrouter()


Test patch:
diff --git a/transport/grpc/resolver/discovery/builder_test.go b/transport/grpc/resolver/discovery/builder_test.go
index e216a544..64051051 100644
--- a/transport/grpc/resolver/discovery/builder_test.go
+++ b/transport/grpc/resolver/discovery/builder_test.go
@@ -38,6 +38,14 @@ func TestDisableDebugLog(t *testing.T) {
 	}
 }
 
+func TestPrintDebugLog(t *testing.T) {
+	o := &builder{}
+	PrintDebugLog(true)(o)
+	if !o.debugLog {
+		t.Errorf("expected PrintdebugLog true, got %v", o.debugLog)
+	}
+}
+
 type mockDiscovery struct{}
 
 func (m *mockDiscovery) GetService(_ context.Context, _ string) ([]*registry.ServiceInstance, error) {