You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ha...@apache.org on 2023/11/01 12:45:36 UTC

(skywalking-banyandb) branch bump-req updated (593f3e51 -> dc7f418d)

This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a change to branch bump-req
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git


 discard 593f3e51 Bump go and several tools
     new dc7f418d Bump go and several tools

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (593f3e51)
            \
             N -- N -- N   refs/heads/bump-req (dc7f418d)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .github/workflows/ci.yml             | 4 ++--
 .github/workflows/e2e.storage.yml    | 2 +-
 .github/workflows/publish-docker.yml | 2 +-
 .github/workflows/test.yml           | 2 +-
 docs/installation.md                 | 2 +-
 docs/installation/binaries.md        | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)


(skywalking-banyandb) 01/01: Bump go and several tools

Posted by ha...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch bump-req
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git

commit dc7f418d3637260a111422e01cfa7558b5551d77
Author: Gao Hongtao <ha...@gmail.com>
AuthorDate: Wed Nov 1 12:37:44 2023 +0000

    Bump go and several tools
    
    Signed-off-by: Gao Hongtao <ha...@gmail.com>
---
 .github/workflows/ci.yml                        |  4 +-
 .github/workflows/e2e.storage.yml               |  2 +-
 .github/workflows/publish-docker.yml            |  2 +-
 .github/workflows/test.yml                      |  2 +-
 .golangci.yml                                   |  6 +-
 CHANGES.md                                      |  6 ++
 CONTRIBUTING.md                                 |  4 +-
 Makefile                                        |  7 ++
 api/Makefile                                    |  1 +
 banyand/Dockerfile                              |  4 +-
 banyand/Makefile                                |  1 +
 banyand/metadata/schema/checker_test.go         | 60 ++++++++--------
 banyand/query/processor_topn.go                 |  6 +-
 banyand/stream/metadata_test.go                 | 78 ++++++++++-----------
 banyand/stream/stream_suite_test.go             | 30 ++++----
 bydbctl/Dockerfile                              |  2 +-
 bydbctl/Makefile                                |  1 +
 bydbctl/internal/cmd/group_test.go              |  4 +-
 bydbctl/internal/cmd/index_rule.go              |  2 +-
 bydbctl/internal/cmd/index_rule_binding.go      |  2 +-
 bydbctl/internal/cmd/index_rule_binding_test.go |  2 +-
 bydbctl/internal/cmd/index_rule_test.go         |  2 +-
 bydbctl/internal/cmd/measure.go                 |  2 +-
 bydbctl/internal/cmd/measure_test.go            |  4 +-
 bydbctl/internal/cmd/property_test.go           |  2 +-
 bydbctl/internal/cmd/root.go                    |  2 +
 bydbctl/internal/cmd/stream.go                  |  2 +-
 bydbctl/internal/cmd/stream_test.go             |  4 +-
 dist/LICENSE                                    | 24 +++----
 docs/installation.md                            |  4 +-
 docs/installation/binaries.md                   |  4 +-
 go.mod                                          | 26 +++----
 go.sum                                          | 58 +++++++++-------
 pkg/Makefile                                    |  1 +
 pkg/convert/string.go                           | 18 ++---
 pkg/flow/streaming/sliding_window_test.go       | 54 +++++++--------
 pkg/flow/streaming/streaming_test.go            | 92 ++++++++++++-------------
 pkg/fs/local_file_system.go                     |  9 ++-
 pkg/Makefile => scripts/build/vendor.mk         | 12 ++--
 scripts/build/version.mk                        | 14 ++--
 scripts/ci/check/version_test.go                |  2 +-
 test/Makefile                                   |  1 +
 test/stress/cases/istio/istio_suite_test.go     | 52 +++++++-------
 ui/Makefile                                     |  5 ++
 ui/package-lock.json                            |  2 +-
 ui/package.json                                 |  2 +-
 46 files changed, 331 insertions(+), 293 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 27509f8f..8663ca24 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -52,7 +52,7 @@ jobs:
             ${{ runner.os }}-check-tool-
       - uses: actions/setup-node@v3
         with:
-          node-version: 18.16
+          node-version: 20.9
           cache: 'npm'
           cache-dependency-path: ui/package-lock.json
       - name: Install Go
@@ -100,7 +100,7 @@ jobs:
             ${{ runner.os }}-build-tool-
       - uses: actions/setup-node@v3
         with:
-          node-version: 18.16
+          node-version: 20.9
           cache: 'npm'
           cache-dependency-path: ui/package-lock.json
       - name: Install Go
diff --git a/.github/workflows/e2e.storage.yml b/.github/workflows/e2e.storage.yml
index 35428b9c..0446bb17 100644
--- a/.github/workflows/e2e.storage.yml
+++ b/.github/workflows/e2e.storage.yml
@@ -74,7 +74,7 @@ jobs:
             ${{ runner.os }}-build-tool-
       - uses: actions/setup-node@v3
         with:
-          node-version: 18.16
+          node-version: 20.9
           cache: 'npm'
           cache-dependency-path: ui/package-lock.json
       - name: Install Go
diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml
index 1024d5bb..5e1a256f 100644
--- a/.github/workflows/publish-docker.yml
+++ b/.github/workflows/publish-docker.yml
@@ -61,7 +61,7 @@ jobs:
             ${{ runner.os }}-build-tool-
       - uses: actions/setup-node@v3
         with:
-          node-version: 18.16
+          node-version: 20.9
           cache: 'npm'
           cache-dependency-path: ui/package-lock.json
       - name: Install Go
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 31b83480..926d979a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -60,7 +60,7 @@ jobs:
             ${{ runner.os }}-test-tool-
       - uses: actions/setup-node@v3
         with:
-          node-version: 18.16
+          node-version: 20.9
           cache: 'npm'
           cache-dependency-path: ui/package-lock.json
       - name: Install Go
diff --git a/.golangci.yml b/.golangci.yml
index 6c86d559..494da9b0 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -83,7 +83,7 @@ linters-settings:
   misspell:
     locale: US
   unused:
-    go: "1.20"
+    go: "1.21"
     check-exported: false
   unparam:
     check-exported: false
@@ -144,10 +144,10 @@ linters-settings:
     #   all          - for all comments.
     scope: toplevel
   staticcheck:
-    go: "1.20"
+    go: "1.21"
     checks: ["all", "-ST1000", "-ST1016", "-ST1020", "-ST1021", "-ST1022"]
   stylecheck:
-    go: "1.20"
+    go: "1.21"
   exhaustive:
     check:
       - switch
diff --git a/CHANGES.md b/CHANGES.md
index 1db2102c..062bd70d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,6 +13,12 @@ Release Notes.
 
 - Fix the bug that property merge new tags failed.
 
+
+### Chores
+
+- Bump go to 1.21.
+- Bump several tools.
+
 ## 0.5.0
 
 ### Features
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b4c429cc..fcae5d0b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -41,8 +41,8 @@ Once we've discussed your changes and you've got your code ready, make sure that
 
 Users who want to build a binary from sources have to set up:
 
-* Go 1.20
-* Node 18.16
+* Go 1.21
+* Node 20.9
 * Git >= 2.30
 * Linux, macOS or Windows+WSL2
 * GNU make
diff --git a/Makefile b/Makefile
index 6c5fb937..37ba8a3e 100644
--- a/Makefile
+++ b/Makefile
@@ -81,6 +81,12 @@ lint: TARGET=lint
 lint: PROJECTS:=api $(PROJECTS) pkg scripts/ci/check test
 lint: default ## Run the linters on all projects
 
+##@ Vendor update
+
+vendor-update: TARGET=vendor-update
+vendor-update: PROJECTS:=$(PROJECTS) pkg test
+vendor-update: default ## Run the linters on all projects
+
 ##@ Code style targets
 tidy:
 	go mod tidy
@@ -186,3 +192,4 @@ release-assembly: release-binary release-sign ## Generate release package
 .PHONY: test test-race test-coverage test-ci
 .PHONY: license-check license-fix license-dep
 .PHONY: release release-binary release-source release-sign release-assembly
+.PHONY: vendor-update
diff --git a/api/Makefile b/api/Makefile
index bd8747e0..22fb2ef3 100644
--- a/api/Makefile
+++ b/api/Makefile
@@ -21,6 +21,7 @@ NAME := api
 include ../scripts/build/version.mk
 include ../scripts/build/base.mk
 include ../scripts/build/lint-api.mk
+include ../scripts/build/vendor.mk
 include ../scripts/build/help.mk
 
 proto_dir := $(root_dir)/api/proto
diff --git a/banyand/Dockerfile b/banyand/Dockerfile
index 5b03fb27..9b964b29 100644
--- a/banyand/Dockerfile
+++ b/banyand/Dockerfile
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM golang:1.20 AS dev
+FROM golang:1.21 AS dev
 WORKDIR /app
 ENV GOOS="linux"
 ENV CGO_ENABLED=0
@@ -27,7 +27,7 @@ EXPOSE 2345
 
 ENTRYPOINT ["air"]
 
-FROM golang:1.20 AS base
+FROM golang:1.21 AS base
 
 ENV GOPATH "/go"
 ENV GO111MODULE "on"
diff --git a/banyand/Makefile b/banyand/Makefile
index 376ac0c8..ca3f7604 100644
--- a/banyand/Makefile
+++ b/banyand/Makefile
@@ -33,4 +33,5 @@ include ../scripts/build/build.mk
 include ../scripts/build/test.mk
 include ../scripts/build/lint.mk
 include ../scripts/build/docker.mk
+include ../scripts/build/vendor.mk
 include ../scripts/build/help.mk
diff --git a/banyand/metadata/schema/checker_test.go b/banyand/metadata/schema/checker_test.go
index d15f814d..06164ec9 100644
--- a/banyand/metadata/schema/checker_test.go
+++ b/banyand/metadata/schema/checker_test.go
@@ -21,7 +21,7 @@ import (
 	"time"
 
 	"github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
+	"github.com/onsi/gomega"
 	"github.com/onsi/gomega/gleak"
 	"google.golang.org/protobuf/encoding/protojson"
 	"google.golang.org/protobuf/types/known/timestamppb"
@@ -33,22 +33,22 @@ import (
 func loadStream() *databasev1.Stream {
 	s := &databasev1.Stream{}
 	// preload stream
-	Expect(protojson.Unmarshal([]byte(streamJSON), s)).To(Succeed())
+	gomega.Expect(protojson.Unmarshal([]byte(streamJSON), s)).To(gomega.Succeed())
 	return s
 }
 
 func loadIndexRuleBinding() *databasev1.IndexRuleBinding {
 	irb := &databasev1.IndexRuleBinding{}
 	// preload index rule binding
-	Expect(protojson.Unmarshal([]byte(indexRuleBindingJSON), irb)).To(Succeed())
+	gomega.Expect(protojson.Unmarshal([]byte(indexRuleBindingJSON), irb)).To(gomega.Succeed())
 	return irb
 }
 
 func loadIndexRule() *databasev1.IndexRule {
 	ir := &databasev1.IndexRule{}
 	data, err := indexRuleStore.ReadFile(indexRuleDir + "/db.instance.json")
-	Expect(err).NotTo(HaveOccurred())
-	Expect(protojson.Unmarshal(data, ir)).To(Succeed())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+	gomega.Expect(protojson.Unmarshal(data, ir)).To(gomega.Succeed())
 	return ir
 }
 
@@ -65,59 +65,59 @@ var _ = ginkgo.Describe("Utils", func() {
 		})
 
 		ginkgo.AfterEach(func() {
-			Eventually(gleak.Goroutines, flags.EventuallyTimeout).ShouldNot(gleak.HaveLeaked(goods))
+			gomega.Eventually(gleak.Goroutines, flags.EventuallyTimeout).ShouldNot(gleak.HaveLeaked(goods))
 		})
 
 		ginkgo.It("should be equal if nothing changed", func() {
-			Expect(checker(s, s)).Should(BeTrue())
+			gomega.Expect(checker(s, s)).Should(gomega.BeTrue())
 		})
 
 		ginkgo.It("should not be equal if metadata.name changed", func() {
 			newS := loadStream()
 			newS.Metadata.Name = "new-name"
-			Expect(checker(s, newS)).Should(BeFalse())
+			gomega.Expect(checker(s, newS)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if metadata.group changed", func() {
 			newS := loadStream()
 			newS.GetMetadata().Group = "new-group"
-			Expect(checker(s, newS)).Should(BeFalse())
+			gomega.Expect(checker(s, newS)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if entity changed", func() {
 			newS := loadStream()
 			newS.GetEntity().TagNames = []string{"new-entity-tag"}
-			Expect(checker(s, newS)).Should(BeFalse())
+			gomega.Expect(checker(s, newS)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if tag name changed", func() {
 			newS := loadStream()
 			newS.GetTagFamilies()[0].Tags[0].Name = "binary-tag"
-			Expect(checker(s, newS)).Should(BeFalse())
+			gomega.Expect(checker(s, newS)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if tag type changed", func() {
 			newS := loadStream()
 			newS.GetTagFamilies()[0].Tags[0].Type = databasev1.TagType_TAG_TYPE_STRING
-			Expect(checker(s, newS)).Should(BeFalse())
+			gomega.Expect(checker(s, newS)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should be equal if UpdatedAt changed", func() {
 			newS := loadStream()
 			newS.UpdatedAt = timestamppb.Now()
-			Expect(checker(s, newS)).Should(BeTrue())
+			gomega.Expect(checker(s, newS)).Should(gomega.BeTrue())
 		})
 
 		ginkgo.It("should be equal if metadata.mod_revision changed", func() {
 			newS := loadStream()
 			newS.Metadata.ModRevision = 10000
-			Expect(checker(s, newS)).Should(BeTrue())
+			gomega.Expect(checker(s, newS)).Should(gomega.BeTrue())
 		})
 
 		ginkgo.It("should be equal if metadata.create_revision changed", func() {
 			newS := loadStream()
 			newS.Metadata.CreateRevision = 10000
-			Expect(checker(s, newS)).Should(BeTrue())
+			gomega.Expect(checker(s, newS)).Should(gomega.BeTrue())
 		})
 	})
 
@@ -133,47 +133,47 @@ var _ = ginkgo.Describe("Utils", func() {
 		})
 
 		ginkgo.AfterEach(func() {
-			Eventually(gleak.Goroutines, flags.EventuallyTimeout).ShouldNot(gleak.HaveLeaked(goods))
+			gomega.Eventually(gleak.Goroutines, flags.EventuallyTimeout).ShouldNot(gleak.HaveLeaked(goods))
 		})
 
 		ginkgo.It("should be equal if nothing changed", func() {
-			Expect(checker(irb, irb)).Should(BeTrue())
+			gomega.Expect(checker(irb, irb)).Should(gomega.BeTrue())
 		})
 
 		ginkgo.It("should not be equal if metadata.name changed", func() {
 			newIrb := loadIndexRuleBinding()
 			newIrb.Metadata.Name = "new-name"
-			Expect(checker(irb, newIrb)).Should(BeFalse())
+			gomega.Expect(checker(irb, newIrb)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if metadata.group changed", func() {
 			newIrb := loadIndexRuleBinding()
 			newIrb.GetMetadata().Group = "new-group"
-			Expect(checker(irb, newIrb)).Should(BeFalse())
+			gomega.Expect(checker(irb, newIrb)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if rules changed", func() {
 			newIrb := loadIndexRuleBinding()
 			newIrb.Rules = []string{}
-			Expect(checker(irb, newIrb)).Should(BeFalse())
+			gomega.Expect(checker(irb, newIrb)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if beginAt changed", func() {
 			newIrb := loadIndexRuleBinding()
 			newIrb.BeginAt = timestamppb.New(time.Now())
-			Expect(checker(irb, newIrb)).Should(BeFalse())
+			gomega.Expect(checker(irb, newIrb)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if expireAt changed", func() {
 			newIrb := loadIndexRuleBinding()
 			newIrb.ExpireAt = timestamppb.New(time.Now())
-			Expect(checker(irb, newIrb)).Should(BeFalse())
+			gomega.Expect(checker(irb, newIrb)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should be equal if UpdatedAtNanoseconds changed", func() {
 			newIrb := loadIndexRuleBinding()
 			newIrb.UpdatedAt = timestamppb.Now()
-			Expect(checker(irb, newIrb)).Should(BeTrue())
+			gomega.Expect(checker(irb, newIrb)).Should(gomega.BeTrue())
 		})
 	})
 
@@ -188,41 +188,41 @@ var _ = ginkgo.Describe("Utils", func() {
 		})
 
 		ginkgo.AfterEach(func() {
-			Eventually(gleak.Goroutines, flags.EventuallyTimeout).ShouldNot(gleak.HaveLeaked(goods))
+			gomega.Eventually(gleak.Goroutines, flags.EventuallyTimeout).ShouldNot(gleak.HaveLeaked(goods))
 		})
 
 		ginkgo.It("should be equal if nothing changed", func() {
-			Expect(checker(ir, ir)).Should(BeTrue())
+			gomega.Expect(checker(ir, ir)).Should(gomega.BeTrue())
 		})
 
 		ginkgo.It("should not be equal if metadata.name changed", func() {
 			newIr := loadIndexRule()
 			newIr.Metadata.Name = "new-name"
-			Expect(checker(ir, newIr)).Should(BeFalse())
+			gomega.Expect(checker(ir, newIr)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if metadata.id changed", func() {
 			newIr := loadIndexRule()
 			newIr.Metadata.Id = 1000
-			Expect(checker(ir, newIr)).Should(BeTrue())
+			gomega.Expect(checker(ir, newIr)).Should(gomega.BeTrue())
 		})
 
 		ginkgo.It("should not be equal if metadata.group changed", func() {
 			newIr := loadIndexRule()
 			newIr.GetMetadata().Group = "new-group"
-			Expect(checker(ir, newIr)).Should(BeFalse())
+			gomega.Expect(checker(ir, newIr)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should not be equal if rules changed", func() {
 			newIr := loadIndexRule()
 			newIr.Tags = []string{"new-tag"}
-			Expect(checker(ir, newIr)).Should(BeFalse())
+			gomega.Expect(checker(ir, newIr)).Should(gomega.BeFalse())
 		})
 
 		ginkgo.It("should be equal if UpdatedAtNanoseconds changed", func() {
 			newIr := loadIndexRule()
 			newIr.UpdatedAt = timestamppb.Now()
-			Expect(checker(ir, newIr)).Should(BeTrue())
+			gomega.Expect(checker(ir, newIr)).Should(gomega.BeTrue())
 		})
 	})
 })
diff --git a/banyand/query/processor_topn.go b/banyand/query/processor_topn.go
index 48743d9d..081361e9 100644
--- a/banyand/query/processor_topn.go
+++ b/banyand/query/processor_topn.go
@@ -397,17 +397,15 @@ func (naggr *postNonAggregationProcessor) Put(entityValues tsdb.EntityValues, va
 				return -1
 			} else if a.(*nonAggregatorItem).val == b.(*nonAggregatorItem).val {
 				return 0
-			} else {
-				return 1
 			}
+			return 1
 		}
 		if a.(*nonAggregatorItem).val < b.(*nonAggregatorItem).val {
 			return 1
 		} else if a.(*nonAggregatorItem).val == b.(*nonAggregatorItem).val {
 			return 0
-		} else {
-			return -1
 		}
+		return -1
 	}, false)
 	naggr.timelines[timestampMillis] = timeline
 	heap.Push(timeline, &nonAggregatorItem{val: val, key: key, values: entityValues})
diff --git a/banyand/stream/metadata_test.go b/banyand/stream/metadata_test.go
index f0133ea5..af4e1694 100644
--- a/banyand/stream/metadata_test.go
+++ b/banyand/stream/metadata_test.go
@@ -20,8 +20,8 @@ package stream
 import (
 	"context"
 
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
+	g "github.com/onsi/ginkgo/v2"
+	"github.com/onsi/gomega"
 	"github.com/onsi/gomega/gleak"
 
 	commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
@@ -29,104 +29,104 @@ import (
 	"github.com/apache/skywalking-banyandb/pkg/test/flags"
 )
 
-var _ = Describe("Metadata", func() {
+var _ = g.Describe("Metadata", func() {
 	var svcs *services
 	var deferFn func()
 	var goods []gleak.Goroutine
 
-	BeforeEach(func() {
+	g.BeforeEach(func() {
 		goods = gleak.Goroutines()
 		svcs, deferFn = setUp()
-		Eventually(func() bool {
+		gomega.Eventually(func() bool {
 			_, ok := svcs.stream.schemaRepo.LoadGroup("default")
 			return ok
-		}).WithTimeout(flags.EventuallyTimeout).Should(BeTrue())
+		}).WithTimeout(flags.EventuallyTimeout).Should(gomega.BeTrue())
 	})
 
-	AfterEach(func() {
+	g.AfterEach(func() {
 		deferFn()
-		Eventually(gleak.Goroutines, flags.EventuallyTimeout).ShouldNot(gleak.HaveLeaked(goods))
+		gomega.Eventually(gleak.Goroutines, flags.EventuallyTimeout).ShouldNot(gleak.HaveLeaked(goods))
 	})
 
-	Context("Manage group", func() {
-		It("should close the group", func() {
+	g.Context("Manage group", func() {
+		g.It("should close the group", func() {
 			deleted, err := svcs.metadataService.GroupRegistry().DeleteGroup(context.TODO(), "default")
-			Expect(err).ShouldNot(HaveOccurred())
-			Expect(deleted).Should(BeTrue())
-			Eventually(func() bool {
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			gomega.Expect(deleted).Should(gomega.BeTrue())
+			gomega.Eventually(func() bool {
 				_, ok := svcs.stream.schemaRepo.LoadGroup("default")
 				return ok
-			}).WithTimeout(flags.EventuallyTimeout).Should(BeFalse())
+			}).WithTimeout(flags.EventuallyTimeout).Should(gomega.BeFalse())
 		})
 
-		It("should add shards", func() {
+		g.It("should add shards", func() {
 			groupSchema, err := svcs.metadataService.GroupRegistry().GetGroup(context.TODO(), "default")
-			Expect(err).ShouldNot(HaveOccurred())
-			Expect(groupSchema).ShouldNot(BeNil())
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			gomega.Expect(groupSchema).ShouldNot(gomega.BeNil())
 			groupSchema.ResourceOpts.ShardNum = 4
 
-			Expect(svcs.metadataService.GroupRegistry().UpdateGroup(context.TODO(), groupSchema)).Should(Succeed())
+			gomega.Expect(svcs.metadataService.GroupRegistry().UpdateGroup(context.TODO(), groupSchema)).Should(gomega.Succeed())
 
-			Eventually(func() bool {
+			gomega.Eventually(func() bool {
 				group, ok := svcs.stream.schemaRepo.LoadGroup("default")
 				if !ok {
 					return false
 				}
 				return group.GetSchema().GetResourceOpts().GetShardNum() == 4
-			}).WithTimeout(flags.EventuallyTimeout).Should(BeTrue())
+			}).WithTimeout(flags.EventuallyTimeout).Should(gomega.BeTrue())
 		})
 	})
 
-	Context("Manage stream", func() {
-		It("should pass smoke test", func() {
-			Eventually(func() bool {
+	g.Context("Manage stream", func() {
+		g.It("should pass smoke test", func() {
+			gomega.Eventually(func() bool {
 				_, ok := svcs.stream.schemaRepo.loadStream(&commonv1.Metadata{
 					Name:  "sw",
 					Group: "default",
 				})
 				return ok
-			}).WithTimeout(flags.EventuallyTimeout).Should(BeTrue())
+			}).WithTimeout(flags.EventuallyTimeout).Should(gomega.BeTrue())
 		})
-		It("should close the stream", func() {
+		g.It("should close the stream", func() {
 			deleted, err := svcs.metadataService.StreamRegistry().DeleteStream(context.TODO(), &commonv1.Metadata{
 				Name:  "sw",
 				Group: "default",
 			})
-			Expect(err).ShouldNot(HaveOccurred())
-			Expect(deleted).Should(BeTrue())
-			Eventually(func() bool {
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			gomega.Expect(deleted).Should(gomega.BeTrue())
+			gomega.Eventually(func() bool {
 				_, ok := svcs.stream.schemaRepo.loadStream(&commonv1.Metadata{
 					Name:  "sw",
 					Group: "default",
 				})
 				return ok
-			}).WithTimeout(flags.EventuallyTimeout).Should(BeFalse())
+			}).WithTimeout(flags.EventuallyTimeout).Should(gomega.BeFalse())
 		})
 
-		Context("Update a stream", func() {
+		g.Context("Update a stream", func() {
 			var streamSchema *databasev1.Stream
 
-			BeforeEach(func() {
+			g.BeforeEach(func() {
 				var err error
 				streamSchema, err = svcs.metadataService.StreamRegistry().GetStream(context.TODO(), &commonv1.Metadata{
 					Name:  "sw",
 					Group: "default",
 				})
 
-				Expect(err).ShouldNot(HaveOccurred())
-				Expect(streamSchema).ShouldNot(BeNil())
+				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+				gomega.Expect(streamSchema).ShouldNot(gomega.BeNil())
 			})
 
-			It("should update a new stream", func() {
-				// Remove the first tag from the entity
+			g.It("should update a new stream", func() {
+				// Remove the first tag from the entg.Ity
 				streamSchema.Entity.TagNames = streamSchema.Entity.TagNames[1:]
 				entitySize := len(streamSchema.Entity.TagNames)
 
 				modRevision, err := svcs.metadataService.StreamRegistry().UpdateStream(context.TODO(), streamSchema)
-				Expect(modRevision).ShouldNot(BeZero())
-				Expect(err).ShouldNot(HaveOccurred())
+				gomega.Expect(modRevision).ShouldNot(gomega.BeZero())
+				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
 
-				Eventually(func() bool {
+				gomega.Eventually(func() bool {
 					val, ok := svcs.stream.schemaRepo.loadStream(&commonv1.Metadata{
 						Name:  "sw",
 						Group: "default",
@@ -136,7 +136,7 @@ var _ = Describe("Metadata", func() {
 					}
 
 					return len(val.schema.GetEntity().TagNames) == entitySize
-				}).WithTimeout(flags.EventuallyTimeout).Should(BeTrue())
+				}).WithTimeout(flags.EventuallyTimeout).Should(gomega.BeTrue())
 			})
 		})
 	})
diff --git a/banyand/stream/stream_suite_test.go b/banyand/stream/stream_suite_test.go
index 82cb06b0..750135d0 100644
--- a/banyand/stream/stream_suite_test.go
+++ b/banyand/stream/stream_suite_test.go
@@ -21,8 +21,8 @@ import (
 	"context"
 	"testing"
 
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
+	g "github.com/onsi/ginkgo/v2"
+	"github.com/onsi/gomega"
 	"go.uber.org/mock/gomock"
 
 	"github.com/apache/skywalking-banyandb/banyand/metadata"
@@ -34,15 +34,15 @@ import (
 )
 
 func TestStream(t *testing.T) {
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "Stream Suite")
+	gomega.RegisterFailHandler(g.Fail)
+	g.RunSpecs(t, "Stream Suite")
 }
 
-var _ = BeforeSuite(func() {
-	Expect(logger.Init(logger.Logging{
+var _ = g.BeforeSuite(func() {
+	gomega.Expect(logger.Init(logger.Logging{
 		Env:   "dev",
 		Level: flags.LogLevel,
-	})).To(Succeed())
+	})).To(gomega.Succeed())
 })
 
 type preloadStreamService struct {
@@ -63,29 +63,29 @@ type services struct {
 }
 
 func setUp() (*services, func()) {
-	ctrl := gomock.NewController(GinkgoT())
-	Expect(ctrl).ShouldNot(BeNil())
+	ctrl := gomock.NewController(g.GinkgoT())
+	gomega.Expect(ctrl).ShouldNot(gomega.BeNil())
 	// Init Pipeline
 	pipeline := queue.Local()
 
 	// Init Metadata Service
 	metadataService, err := metadata.NewService(context.TODO())
-	Expect(err).NotTo(HaveOccurred())
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 
 	// Init Stream Service
 	streamService, err := NewService(context.TODO(), metadataService, pipeline)
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	preloadStreamSvc := &preloadStreamService{metaSvc: metadataService}
 	var flags []string
 	metaPath, metaDeferFunc, err := test.NewSpace()
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	flags = append(flags, "--metadata-root-path="+metaPath)
 	rootPath, deferFunc, err := test.NewSpace()
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	flags = append(flags, "--stream-root-path="+rootPath)
 	listenClientURL, listenPeerURL, err := test.NewEtcdListenUrls()
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	flags = append(flags, "--etcd-listen-client-url="+listenClientURL, "--etcd-listen-peer-url="+listenPeerURL)
 	moduleDeferFunc := test.SetupModules(
 		flags,
diff --git a/bydbctl/Dockerfile b/bydbctl/Dockerfile
index 3270ae15..e681d074 100644
--- a/bydbctl/Dockerfile
+++ b/bydbctl/Dockerfile
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM golang:1.20 AS base
+FROM golang:1.21 AS base
 
 ENV GOPATH "/go"
 ENV GO111MODULE "on"
diff --git a/bydbctl/Makefile b/bydbctl/Makefile
index 093f6586..721922f4 100644
--- a/bydbctl/Makefile
+++ b/bydbctl/Makefile
@@ -53,4 +53,5 @@ release: $(BUILDS)
 include ../scripts/build/docker.mk
 include ../scripts/build/test.mk
 include ../scripts/build/lint.mk
+include ../scripts/build/vendor.mk
 include ../scripts/build/help.mk
diff --git a/bydbctl/internal/cmd/group_test.go b/bydbctl/internal/cmd/group_test.go
index c600a165..5ab047a0 100644
--- a/bydbctl/internal/cmd/group_test.go
+++ b/bydbctl/internal/cmd/group_test.go
@@ -31,13 +31,15 @@ import (
 	"github.com/apache/skywalking-banyandb/pkg/test/setup"
 )
 
+const httpSchema = "http://"
+
 var _ = Describe("Group", func() {
 	var addr string
 	var deferFunc func()
 	var rootCmd *cobra.Command
 	BeforeEach(func() {
 		_, addr, deferFunc = setup.EmptyStandalone()
-		addr = "http://" + addr
+		addr = httpSchema + addr
 		// extracting the operation of creating group
 		rootCmd = &cobra.Command{Use: "root"}
 		cmd.RootCmdFlags(rootCmd)
diff --git a/bydbctl/internal/cmd/index_rule.go b/bydbctl/internal/cmd/index_rule.go
index 1989ef3f..fe2227c9 100644
--- a/bydbctl/internal/cmd/index_rule.go
+++ b/bydbctl/internal/cmd/index_rule.go
@@ -30,7 +30,7 @@ import (
 
 const indexRuleSchemaPath = "/api/v1/index-rule/schema"
 
-var indexRuleSchemaPathWithParams = indexRuleSchemaPath + "/{group}/{name}"
+var indexRuleSchemaPathWithParams = indexRuleSchemaPath + pathTemp
 
 func newIndexRuleCmd() *cobra.Command {
 	indexRuleCmd := &cobra.Command{
diff --git a/bydbctl/internal/cmd/index_rule_binding.go b/bydbctl/internal/cmd/index_rule_binding.go
index a9bf2a5d..57fb17df 100644
--- a/bydbctl/internal/cmd/index_rule_binding.go
+++ b/bydbctl/internal/cmd/index_rule_binding.go
@@ -30,7 +30,7 @@ import (
 
 const indexRuleBindingSchemaPath = "/api/v1/index-rule-binding/schema"
 
-var indexRuleBindingSchemaPathWithParams = indexRuleBindingSchemaPath + "/{group}/{name}"
+var indexRuleBindingSchemaPathWithParams = indexRuleBindingSchemaPath + pathTemp
 
 func newIndexRuleBindingCmd() *cobra.Command {
 	indexRuleBindingCmd := &cobra.Command{
diff --git a/bydbctl/internal/cmd/index_rule_binding_test.go b/bydbctl/internal/cmd/index_rule_binding_test.go
index 8d681475..1c447ad4 100644
--- a/bydbctl/internal/cmd/index_rule_binding_test.go
+++ b/bydbctl/internal/cmd/index_rule_binding_test.go
@@ -38,7 +38,7 @@ var _ = Describe("IndexRuleBindingSchema Operation", func() {
 	var rootCmd *cobra.Command
 	BeforeEach(func() {
 		_, addr, deferFunc = setup.EmptyStandalone()
-		addr = "http://" + addr
+		addr = httpSchema + addr
 		// extracting the operation of creating indexRuleBinding schema
 		rootCmd = &cobra.Command{Use: "root"}
 		cmd.RootCmdFlags(rootCmd)
diff --git a/bydbctl/internal/cmd/index_rule_test.go b/bydbctl/internal/cmd/index_rule_test.go
index 2aae1aef..1f99bf25 100644
--- a/bydbctl/internal/cmd/index_rule_test.go
+++ b/bydbctl/internal/cmd/index_rule_test.go
@@ -38,7 +38,7 @@ var _ = Describe("IndexRuleSchema Operation", func() {
 	var rootCmd *cobra.Command
 	BeforeEach(func() {
 		_, addr, deferFunc = setup.EmptyStandalone()
-		addr = "http://" + addr
+		addr = httpSchema + addr
 		// extracting the operation of creating indexRule schema
 		rootCmd = &cobra.Command{Use: "root"}
 		cmd.RootCmdFlags(rootCmd)
diff --git a/bydbctl/internal/cmd/measure.go b/bydbctl/internal/cmd/measure.go
index 4be794e4..9c3f76aa 100644
--- a/bydbctl/internal/cmd/measure.go
+++ b/bydbctl/internal/cmd/measure.go
@@ -30,7 +30,7 @@ import (
 
 const measureSchemaPath = "/api/v1/measure/schema"
 
-var measureSchemaPathWithParams = measureSchemaPath + "/{group}/{name}"
+var measureSchemaPathWithParams = measureSchemaPath + pathTemp
 
 func newMeasureCmd() *cobra.Command {
 	measureCmd := &cobra.Command{
diff --git a/bydbctl/internal/cmd/measure_test.go b/bydbctl/internal/cmd/measure_test.go
index 8df93f2b..1f538526 100644
--- a/bydbctl/internal/cmd/measure_test.go
+++ b/bydbctl/internal/cmd/measure_test.go
@@ -45,7 +45,7 @@ var _ = Describe("Measure Schema Operation", func() {
 	var rootCmd *cobra.Command
 	BeforeEach(func() {
 		_, addr, deferFunc = setup.EmptyStandalone()
-		addr = "http://" + addr
+		addr = httpSchema + addr
 		// extracting the operation of creating measure schema
 		rootCmd = &cobra.Command{Use: "root"}
 		cmd.RootCmdFlags(rootCmd)
@@ -201,7 +201,7 @@ var _ = Describe("Measure Data Query", func() {
 		interval = 1 * time.Millisecond
 		endStr = now.Add(5 * time.Minute).Format(time.RFC3339)
 		grpcAddr, addr, deferFunc = setup.Standalone()
-		addr = "http://" + addr
+		addr = httpSchema + addr
 		rootCmd = &cobra.Command{Use: "root"}
 		cmd.RootCmdFlags(rootCmd)
 	})
diff --git a/bydbctl/internal/cmd/property_test.go b/bydbctl/internal/cmd/property_test.go
index ee2eb81d..2ad70ab2 100644
--- a/bydbctl/internal/cmd/property_test.go
+++ b/bydbctl/internal/cmd/property_test.go
@@ -101,7 +101,7 @@ ttl: 30m
 	helpers.UnmarshalYAML([]byte(p2YAML), p2Proto)
 	BeforeEach(func() {
 		_, addr, deferFunc = setup.EmptyStandalone()
-		addr = "http://" + addr
+		addr = httpSchema + addr
 		// extracting the operation of creating property schema
 		rootCmd = &cobra.Command{Use: "root"}
 		cmd.RootCmdFlags(rootCmd)
diff --git a/bydbctl/internal/cmd/root.go b/bydbctl/internal/cmd/root.go
index c7956d8c..3750c49e 100644
--- a/bydbctl/internal/cmd/root.go
+++ b/bydbctl/internal/cmd/root.go
@@ -29,6 +29,8 @@ import (
 	"github.com/apache/skywalking-banyandb/pkg/version"
 )
 
+const pathTemp = "/{group}/{name}"
+
 var (
 	filePath string
 	name     string
diff --git a/bydbctl/internal/cmd/stream.go b/bydbctl/internal/cmd/stream.go
index 803cb05d..59d6cd7f 100644
--- a/bydbctl/internal/cmd/stream.go
+++ b/bydbctl/internal/cmd/stream.go
@@ -31,7 +31,7 @@ import (
 
 const streamSchemaPath = "/api/v1/stream/schema"
 
-var streamSchemaPathWithParams = streamSchemaPath + "/{group}/{name}"
+var streamSchemaPathWithParams = streamSchemaPath + pathTemp
 
 func getPath(path string) string {
 	return viper.GetString("addr") + path
diff --git a/bydbctl/internal/cmd/stream_test.go b/bydbctl/internal/cmd/stream_test.go
index 3618b9fb..a46034c9 100644
--- a/bydbctl/internal/cmd/stream_test.go
+++ b/bydbctl/internal/cmd/stream_test.go
@@ -45,7 +45,7 @@ var _ = Describe("Stream Schema Operation", func() {
 	var rootCmd *cobra.Command
 	BeforeEach(func() {
 		_, addr, deferFunc = setup.EmptyStandalone()
-		addr = "http://" + addr
+		addr = httpSchema + addr
 		// extracting the operation of creating stream schema
 		rootCmd = &cobra.Command{Use: "root"}
 		cmd.RootCmdFlags(rootCmd)
@@ -202,7 +202,7 @@ var _ = Describe("Stream Data Query", func() {
 		interval = 500 * time.Millisecond
 		endStr = now.Add(1 * time.Hour).Format(time.RFC3339)
 		grpcAddr, addr, deferFunc = setup.Standalone()
-		addr = "http://" + addr
+		addr = httpSchema + addr
 		rootCmd = &cobra.Command{Use: "root"}
 		cmd.RootCmdFlags(rootCmd)
 	})
diff --git a/dist/LICENSE b/dist/LICENSE
index f479b15f..2f080859 100644
--- a/dist/LICENSE
+++ b/dist/LICENSE
@@ -185,13 +185,13 @@ Apache-2.0 licenses
     github.com/coreos/go-systemd/v22 v22.5.0 Apache-2.0
     github.com/dgraph-io/ristretto v0.1.1 Apache-2.0
     github.com/envoyproxy/protoc-gen-validate v0.10.1 Apache-2.0
-    github.com/go-logr/logr v1.2.4 Apache-2.0
+    github.com/go-logr/logr v1.3.0 Apache-2.0
     github.com/go-logr/stdr v1.2.2 Apache-2.0
     github.com/golang/glog v1.1.0 Apache-2.0
     github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da Apache-2.0
     github.com/google/btree v1.1.2 Apache-2.0
     github.com/google/flatbuffers v1.12.1 Apache-2.0
-    github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6 Apache-2.0
+    github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b Apache-2.0
     github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 Apache-2.0
     github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 Apache-2.0
     github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.5 Apache-2.0
@@ -232,7 +232,7 @@ Apache-2.0 licenses
     go.opentelemetry.io/otel/sdk v1.16.0 Apache-2.0
     go.opentelemetry.io/otel/trace v1.16.0 Apache-2.0
     go.opentelemetry.io/proto/otlp v0.20.0 Apache-2.0
-    go.uber.org/mock v0.2.0 Apache-2.0
+    go.uber.org/mock v0.3.0 Apache-2.0
     google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 Apache-2.0
     google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 Apache-2.0
     google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 Apache-2.0
@@ -271,7 +271,7 @@ BSD-3-Clause licenses
     github.com/gogo/protobuf v1.3.2 BSD-3-Clause
     github.com/golang/protobuf v1.5.3 BSD-3-Clause
     github.com/golang/snappy v0.0.3 BSD-3-Clause
-    github.com/google/go-cmp v0.5.9 BSD-3-Clause
+    github.com/google/go-cmp v0.6.0 BSD-3-Clause
     github.com/google/uuid v1.3.0 BSD-3-Clause
     github.com/grpc-ecosystem/grpc-gateway v1.16.0 BSD-3-Clause
     github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 BSD-3-Clause
@@ -281,14 +281,14 @@ BSD-3-Clause licenses
     github.com/spf13/pflag v1.0.5 BSD-3-Clause
     github.com/tklauser/go-sysconf v0.3.11 BSD-3-Clause
     github.com/xhit/go-str2duration/v2 v2.1.0 BSD-3-Clause
-    golang.org/x/crypto v0.11.0 BSD-3-Clause
+    golang.org/x/crypto v0.14.0 BSD-3-Clause
     golang.org/x/exp v0.0.0-20220602145555-4a0574d9293f BSD-3-Clause
-    golang.org/x/mod v0.12.0 BSD-3-Clause
-    golang.org/x/net v0.12.0 BSD-3-Clause
-    golang.org/x/sys v0.10.0 BSD-3-Clause
-    golang.org/x/text v0.11.0 BSD-3-Clause
+    golang.org/x/mod v0.13.0 BSD-3-Clause
+    golang.org/x/net v0.17.0 BSD-3-Clause
+    golang.org/x/sys v0.13.0 BSD-3-Clause
+    golang.org/x/text v0.13.0 BSD-3-Clause
     golang.org/x/time v0.3.0 BSD-3-Clause
-    golang.org/x/tools v0.11.1 BSD-3-Clause
+    golang.org/x/tools v0.14.0 BSD-3-Clause
     google.golang.org/protobuf v1.31.0 BSD-3-Clause
 
 ========================================================================
@@ -332,8 +332,8 @@ MIT licenses
     github.com/mattn/go-colorable v0.1.13 MIT
     github.com/mattn/go-isatty v0.0.19 MIT
     github.com/mitchellh/mapstructure v1.5.0 MIT
-    github.com/onsi/ginkgo/v2 v2.11.0 MIT
-    github.com/onsi/gomega v1.27.10 MIT
+    github.com/onsi/ginkgo/v2 v2.13.0 MIT
+    github.com/onsi/gomega v1.29.0 MIT
     github.com/pelletier/go-toml/v2 v2.0.8 MIT
     github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c MIT
     github.com/robfig/cron/v3 v3.0.1 MIT
diff --git a/docs/installation.md b/docs/installation.md
index a8d9e542..8799cc68 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -15,8 +15,8 @@ Get binaries from the [download](https://skywalking.apache.org/downloads/).
 
 Users who want to build a binary from sources have to set up:
 
-* Go 1.20
-* Node 18.16
+* Go 1.21
+* Node 20.9
 * Git >= 2.30
 * Linux, macOS or Windows+WSL2
 * GNU make
diff --git a/docs/installation/binaries.md b/docs/installation/binaries.md
index 697eecc9..58a64cfc 100644
--- a/docs/installation/binaries.md
+++ b/docs/installation/binaries.md
@@ -12,8 +12,8 @@ Get binaries from the [download](https://skywalking.apache.org/downloads/).
 
 Users who want to build a binary from sources have to set up:
 
-* Go 1.20
-* Node 18.16
+* Go 1.21
+* Node 20.9
 * Git >= 2.30
 * Linux, macOS or Windows+WSL2
 * GNU make
diff --git a/go.mod b/go.mod
index 1dcf2b57..ed666ac6 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/apache/skywalking-banyandb
 
-go 1.20
+go 1.21
 
 require (
 	github.com/RoaringBitmap/roaring v1.3.0
@@ -12,7 +12,7 @@ require (
 	github.com/envoyproxy/protoc-gen-validate v0.10.1
 	github.com/go-chi/chi/v5 v5.0.8
 	github.com/go-resty/resty/v2 v2.7.0
-	github.com/google/go-cmp v0.5.9
+	github.com/google/go-cmp v0.6.0
 	github.com/google/uuid v1.3.0
 	github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0
 	github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.5
@@ -21,8 +21,8 @@ require (
 	github.com/hashicorp/golang-lru/v2 v2.0.4
 	github.com/kkdai/maglev v0.2.0
 	github.com/oklog/run v1.1.0
-	github.com/onsi/ginkgo/v2 v2.11.0
-	github.com/onsi/gomega v1.27.10
+	github.com/onsi/ginkgo/v2 v2.13.0
+	github.com/onsi/gomega v1.29.0
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/client_golang v1.16.0
 	github.com/rs/zerolog v1.29.1
@@ -34,10 +34,10 @@ require (
 	github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04
 	go.etcd.io/etcd/client/v3 v3.5.9
 	go.etcd.io/etcd/server/v3 v3.5.9
-	go.uber.org/mock v0.2.0
+	go.uber.org/mock v0.3.0
 	go.uber.org/multierr v1.11.0
 	golang.org/x/exp v0.0.0-20220602145555-4a0574d9293f
-	golang.org/x/mod v0.12.0
+	golang.org/x/mod v0.13.0
 	google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130
 	google.golang.org/grpc v1.56.2
@@ -68,7 +68,7 @@ require (
 	github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect
 	github.com/dustin/go-humanize v1.0.1
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
-	github.com/go-logr/logr v1.2.4 // indirect
+	github.com/go-logr/logr v1.3.0 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-ole/go-ole v1.2.6 // indirect
 	github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
@@ -80,7 +80,7 @@ require (
 	github.com/golang/snappy v0.0.3
 	github.com/google/btree v1.1.2 // indirect
 	github.com/google/flatbuffers v1.12.1 // indirect
-	github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6 // indirect
+	github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect
 	github.com/gorilla/websocket v1.5.0 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
 	github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
@@ -138,12 +138,12 @@ require (
 	go.opentelemetry.io/proto/otlp v0.20.0 // indirect
 	go.uber.org/atomic v1.11.0 // indirect
 	go.uber.org/zap v1.24.0
-	golang.org/x/crypto v0.11.0 // indirect
-	golang.org/x/net v0.12.0 // indirect
-	golang.org/x/sys v0.10.0 // indirect
-	golang.org/x/text v0.11.0 // indirect
+	golang.org/x/crypto v0.14.0 // indirect
+	golang.org/x/net v0.17.0 // indirect
+	golang.org/x/sys v0.13.0 // indirect
+	golang.org/x/text v0.13.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
-	golang.org/x/tools v0.11.1 // indirect
+	golang.org/x/tools v0.14.0 // indirect
 	google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
diff --git a/go.sum b/go.sum
index 29be62ee..0e4e1387 100644
--- a/go.sum
+++ b/go.sum
@@ -25,7 +25,9 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
 cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
 cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
+cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
 cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
+cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
@@ -91,7 +93,9 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
+github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA=
+github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
 github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@@ -128,6 +132,7 @@ github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byA
 github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
 github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
 github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
+github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
@@ -140,8 +145,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
 github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
-github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
+github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
@@ -209,8 +214,9 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-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/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -225,8 +231,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
 github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6 h1:ZgoomqkdjGbQ3+qQXCkvYMCDvGDNg2k5JJDjjdTB6jY=
-github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
+github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0=
+github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
@@ -282,9 +288,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353 h1:X/79QL0b4YJVO5+OsPH9rF2u428CIrGL/jLmPsoOQQ4=
 github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353/go.mod h1:N0SVk0uhy+E1PZ3C9ctsPRlvOPAFPkCNlcPBDkt0N3U=
 github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
@@ -314,10 +322,10 @@ github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
 github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
 github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
 github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
-github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
-github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
-github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
-github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
+github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
+github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
+github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
+github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
@@ -344,6 +352,7 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
 github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
 github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
 github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
@@ -473,8 +482,9 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
 go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
 go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
 go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
-go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU=
-go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM=
+go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
+go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
+go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
 go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
 go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
 go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
@@ -489,8 +499,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
-golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -530,8 +540,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
-golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
+golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -568,8 +578,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
-golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -580,6 +590,7 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
+golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -642,8 +653,8 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -653,8 +664,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
-golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -712,8 +723,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
-golang.org/x/tools v0.11.1 h1:ojD5zOW8+7dOGzdnNgersm8aPfcDjhMp12UfG93NIMc=
-golang.org/x/tools v0.11.1/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
+golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
+golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -831,6 +842,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
 gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/pkg/Makefile b/pkg/Makefile
index 043bc210..bc53ec1b 100644
--- a/pkg/Makefile
+++ b/pkg/Makefile
@@ -22,4 +22,5 @@ include ../scripts/build/base.mk
 include ../scripts/build/generate_go.mk
 include ../scripts/build/test.mk
 include ../scripts/build/lint.mk
+include ../scripts/build/vendor.mk
 include ../scripts/build/help.mk
diff --git a/pkg/convert/string.go b/pkg/convert/string.go
index 5a24db8d..d57c40a1 100644
--- a/pkg/convert/string.go
+++ b/pkg/convert/string.go
@@ -18,21 +18,23 @@
 package convert
 
 import (
-	"reflect"
 	"unsafe"
 )
 
 // StringToBytes converts string to bytes.
+// It work well until the referenced memory won’t be changed.
 func StringToBytes(s string) (b []byte) {
-	bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
-	sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
-	bh.Data = sh.Data
-	bh.Cap = sh.Len
-	bh.Len = sh.Len
-	return b
+	if s == "" {
+		return nil
+	}
+	return unsafe.Slice(unsafe.StringData(s), len(s))
 }
 
 // BytesToString converts bytes to string.
+// It work well until the referenced memory won’t be changed.
 func BytesToString(b []byte) string {
-	return *(*string)(unsafe.Pointer(&b))
+	if len(b) == 0 {
+		return ""
+	}
+	return unsafe.String(unsafe.SliceData(b), len(b))
 }
diff --git a/pkg/flow/streaming/sliding_window_test.go b/pkg/flow/streaming/sliding_window_test.go
index 83f98879..2a3366b0 100644
--- a/pkg/flow/streaming/sliding_window_test.go
+++ b/pkg/flow/streaming/sliding_window_test.go
@@ -21,8 +21,8 @@ import (
 	"context"
 	"time"
 
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
+	g "github.com/onsi/ginkgo/v2"
+	"github.com/onsi/gomega"
 
 	"github.com/apache/skywalking-banyandb/pkg/flow"
 	"github.com/apache/skywalking-banyandb/pkg/test/flags"
@@ -53,7 +53,7 @@ func (i *intSumAggregator) Dirty() bool {
 	return i.dirty
 }
 
-var _ = Describe("Sliding Window", func() {
+var _ = g.Describe("Sliding Window", func() {
 	var (
 		baseTS         time.Time
 		snk            *slice
@@ -65,46 +65,46 @@ var _ = Describe("Sliding Window", func() {
 		}
 	)
 
-	BeforeEach(func() {
+	g.BeforeEach(func() {
 		baseTS = time.Now()
 	})
 
-	JustBeforeEach(func() {
+	g.JustBeforeEach(func() {
 		snk = newSlice()
 
 		slidingWindows = NewTumblingTimeWindows(time.Second * 15).(*tumblingTimeWindows)
 		slidingWindows.aggregationFactory = aggrFactory
 		slidingWindows.windowCount = 2
 
-		Expect(slidingWindows.Setup(context.TODO())).Should(Succeed())
-		Expect(snk.Setup(context.TODO())).Should(Succeed())
+		gomega.Expect(slidingWindows.Setup(context.TODO())).Should(gomega.Succeed())
+		gomega.Expect(snk.Setup(context.TODO())).Should(gomega.Succeed())
 		slidingWindows.Exec(snk)
 		for _, r := range input {
 			slidingWindows.In() <- r
 		}
 	})
 
-	AfterEach(func() {
+	g.AfterEach(func() {
 		close(slidingWindows.in)
-		Expect(slidingWindows.Teardown(context.TODO())).Should(Succeed())
+		gomega.Expect(slidingWindows.Teardown(context.TODO())).Should(gomega.Succeed())
 	})
 
-	When("input a single element", func() {
-		BeforeEach(func() {
+	g.When("input a single element", func() {
+		g.BeforeEach(func() {
 			input = []flow.StreamRecord{
 				flow.NewStreamRecord(1, baseTS.UnixMilli()),
 			}
 		})
 
-		It("Should not trigger", func() {
-			Eventually(func(g Gomega) {
-				g.Expect(snk.Value()).Should(BeEmpty())
-			}).WithTimeout(flags.EventuallyTimeout).Should(Succeed())
+		g.It("Should not trigger", func() {
+			gomega.Eventually(func(g gomega.Gomega) {
+				g.Expect(snk.Value()).Should(gomega.BeEmpty())
+			}).WithTimeout(flags.EventuallyTimeout).Should(gomega.Succeed())
 		})
 	})
 
-	When("input two elements within the same bucket", func() {
-		BeforeEach(func() {
+	g.When("input two elements within the same bucket", func() {
+		g.BeforeEach(func() {
 			baseTS = time.Unix(baseTS.Unix()-baseTS.Unix()%15, 0)
 			input = []flow.StreamRecord{
 				flow.NewStreamRecord(1, baseTS.UnixMilli()),
@@ -112,15 +112,15 @@ var _ = Describe("Sliding Window", func() {
 			}
 		})
 
-		It("Should not trigger", func() {
-			Eventually(func(g Gomega) {
-				g.Expect(snk.Value()).Should(BeEmpty())
-			}).WithTimeout(flags.EventuallyTimeout).Should(Succeed())
+		g.It("Should not trigger", func() {
+			gomega.Eventually(func(g gomega.Gomega) {
+				g.Expect(snk.Value()).Should(gomega.BeEmpty())
+			}).WithTimeout(flags.EventuallyTimeout).Should(gomega.Succeed())
 		})
 	})
 
-	When("input two elements within adjacent buckets", func() {
-		BeforeEach(func() {
+	g.When("input two elements within adjacent buckets", func() {
+		g.BeforeEach(func() {
 			baseTS = time.Unix(baseTS.Unix()-baseTS.Unix()%15+14, 0)
 			input = []flow.StreamRecord{
 				flow.NewStreamRecord(1, baseTS.UnixMilli()),
@@ -128,10 +128,10 @@ var _ = Describe("Sliding Window", func() {
 			}
 		})
 
-		It("Should trigger once due to the expiry", func() {
-			Eventually(func(g Gomega) {
-				g.Expect(snk.Value()).Should(HaveLen(1))
-			}).WithTimeout(flags.EventuallyTimeout).Should(Succeed())
+		g.It("Should trigger once due to the expiry", func() {
+			gomega.Eventually(func(g gomega.Gomega) {
+				g.Expect(snk.Value()).Should(gomega.HaveLen(1))
+			}).WithTimeout(flags.EventuallyTimeout).Should(gomega.Succeed())
 		})
 	})
 })
diff --git a/pkg/flow/streaming/streaming_test.go b/pkg/flow/streaming/streaming_test.go
index 437af1ec..a2a7057b 100644
--- a/pkg/flow/streaming/streaming_test.go
+++ b/pkg/flow/streaming/streaming_test.go
@@ -22,8 +22,8 @@ import (
 	"sync"
 	"time"
 
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
+	g "github.com/onsi/ginkgo/v2"
+	"github.com/onsi/gomega"
 
 	"github.com/apache/skywalking-banyandb/pkg/flow"
 	"github.com/apache/skywalking-banyandb/pkg/test/flags"
@@ -40,81 +40,81 @@ func numberRange(begin, count int) []int {
 	return result
 }
 
-var _ = Describe("Streaming", func() {
+var _ = g.Describe("Streaming", func() {
 	var (
 		f     flow.Flow
 		snk   *slice
 		errCh <-chan error
 	)
 
-	AfterEach(func() {
-		Expect(f.Close()).Should(Succeed())
-		Consistently(errCh).ShouldNot(Receive())
+	g.AfterEach(func() {
+		gomega.Expect(f.Close()).Should(gomega.Succeed())
+		gomega.Consistently(errCh).ShouldNot(gomega.Receive())
 	})
 
-	Context("With Filter operator", func() {
+	g.Context("With Filter operator", func() {
 		var (
 			filter flow.UnaryFunc[bool]
 
 			input = flowTest.NewSlice(numberRange(0, 10))
 		)
 
-		JustBeforeEach(func() {
+		g.JustBeforeEach(func() {
 			snk = newSlice()
 			f = New(input).
 				Filter(filter).
 				To(snk)
 			errCh = f.Open()
-			Expect(errCh).ShouldNot(BeNil())
+			gomega.Expect(errCh).ShouldNot(gomega.BeNil())
 		})
 
-		When("Given a odd filter", func() {
-			BeforeEach(func() {
+		g.When("Given a odd filter", func() {
+			g.BeforeEach(func() {
 				filter = func(ctx context.Context, i interface{}) bool {
 					return i.(int)%2 == 0
 				}
 			})
 
-			It("Should filter odd number", func() {
-				Eventually(func(g Gomega) {
-					g.Expect(snk.Value()).Should(Equal([]interface{}{
+			g.It("Should filter odd number", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(snk.Value()).Should(gomega.Equal([]interface{}{
 						flow.NewStreamRecordWithoutTS(0),
 						flow.NewStreamRecordWithoutTS(2),
 						flow.NewStreamRecordWithoutTS(4),
 						flow.NewStreamRecordWithoutTS(6),
 						flow.NewStreamRecordWithoutTS(8),
 					}))
-				}, flags.EventuallyTimeout).Should(Succeed())
+				}, flags.EventuallyTimeout).Should(gomega.Succeed())
 			})
 		})
 	})
 
-	Context("With Mapper operator", func() {
+	g.Context("With Mapper operator", func() {
 		var (
 			mapper flow.UnaryFunc[any]
 
 			input = flowTest.NewSlice(numberRange(0, 10))
 		)
 
-		JustBeforeEach(func() {
+		g.JustBeforeEach(func() {
 			snk = newSlice()
 			f = New(input).
 				Map(mapper).
 				To(snk)
 			errCh = f.Open()
-			Expect(errCh).ShouldNot(BeNil())
+			gomega.Expect(errCh).ShouldNot(gomega.BeNil())
 		})
 
-		When("given a multiplier", func() {
-			BeforeEach(func() {
+		g.When("given a multiplier", func() {
+			g.BeforeEach(func() {
 				mapper = func(ctx context.Context, i interface{}) interface{} {
 					return i.(int) * 2
 				}
 			})
 
-			It("Should multiply by 2", func() {
-				Eventually(func(g Gomega) {
-					g.Expect(snk.Value()).Should(Equal([]interface{}{
+			g.It("Should multiply by 2", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(snk.Value()).Should(gomega.Equal([]interface{}{
 						flow.NewStreamRecordWithoutTS(0),
 						flow.NewStreamRecordWithoutTS(2),
 						flow.NewStreamRecordWithoutTS(4),
@@ -126,12 +126,12 @@ var _ = Describe("Streaming", func() {
 						flow.NewStreamRecordWithoutTS(16),
 						flow.NewStreamRecordWithoutTS(18),
 					}))
-				}, flags.EventuallyTimeout).Should(Succeed())
+				}, flags.EventuallyTimeout).Should(gomega.Succeed())
 			})
 		})
 	})
 
-	Context("With TopN operator order by ASC", func() {
+	g.Context("With TopN operator order by ASC", func() {
 		type record struct {
 			service  string
 			instance string
@@ -140,7 +140,7 @@ var _ = Describe("Streaming", func() {
 
 		var input []flow.StreamRecord
 
-		JustBeforeEach(func() {
+		g.JustBeforeEach(func() {
 			snk = newSlice()
 
 			f = New(flowTest.NewSlice(input)).
@@ -157,11 +157,11 @@ var _ = Describe("Streaming", func() {
 				To(snk)
 
 			errCh = f.Open()
-			Expect(errCh).ShouldNot(BeNil())
+			gomega.Expect(errCh).ShouldNot(gomega.BeNil())
 		})
 
-		When("Bottom3", func() {
-			BeforeEach(func() {
+		g.When("Bottom3", func() {
+			g.BeforeEach(func() {
 				input = []flow.StreamRecord{
 					flow.NewStreamRecord(&record{"e2e-service-provider", "instance-001", 10000}, 1000),
 					flow.NewStreamRecord(&record{"e2e-service-consumer", "instance-001", 9900}, 2000),
@@ -174,27 +174,27 @@ var _ = Describe("Streaming", func() {
 				}
 			})
 
-			It("Should take bottom 3 elements", func() {
-				Eventually(func(g Gomega) {
-					g.Expect(len(snk.Value())).Should(BeNumerically(">=", 1))
+			g.It("Should take bottom 3 elements", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(len(snk.Value())).Should(gomega.BeNumerically(">=", 1))
 					// e2e-service-consumer Group
-					g.Expect(snk.Value()[0].(flow.StreamRecord).Data().(map[string][]*Tuple2)["e2e-service-consumer"]).Should(BeEquivalentTo([]*Tuple2{
+					g.Expect(snk.Value()[0].(flow.StreamRecord).Data().(map[string][]*Tuple2)["e2e-service-consumer"]).Should(gomega.BeEquivalentTo([]*Tuple2{
 						{int64(9500), flow.NewStreamRecord(flow.Data{"e2e-service-consumer", int64(9500)}, 7000)},
 						{int64(9600), flow.NewStreamRecord(flow.Data{"e2e-service-consumer", int64(9600)}, 6000)},
 						{int64(9700), flow.NewStreamRecord(flow.Data{"e2e-service-consumer", int64(9700)}, 4000)},
 					}))
 					// e2e-service-provider Group
-					g.Expect(snk.Value()[0].(flow.StreamRecord).Data().(map[string][]*Tuple2)["e2e-service-provider"]).Should(BeEquivalentTo([]*Tuple2{
+					g.Expect(snk.Value()[0].(flow.StreamRecord).Data().(map[string][]*Tuple2)["e2e-service-provider"]).Should(gomega.BeEquivalentTo([]*Tuple2{
 						{int64(9700), flow.NewStreamRecord(flow.Data{"e2e-service-provider", int64(9700)}, 5000)},
 						{int64(9800), flow.NewStreamRecord(flow.Data{"e2e-service-provider", int64(9800)}, 3000)},
 						{int64(10000), flow.NewStreamRecord(flow.Data{"e2e-service-provider", int64(10000)}, 1000)},
 					}))
-				}).WithTimeout(flags.EventuallyTimeout).Should(Succeed())
+				}).WithTimeout(flags.EventuallyTimeout).Should(gomega.Succeed())
 			})
 		})
 	})
 
-	Context("With TopN operator order by DESC", func() {
+	g.Context("With TopN operator order by DESC", func() {
 		type record struct {
 			service  string
 			instance string
@@ -203,7 +203,7 @@ var _ = Describe("Streaming", func() {
 
 		var input []flow.StreamRecord
 
-		JustBeforeEach(func() {
+		g.JustBeforeEach(func() {
 			snk = newSlice()
 
 			f = New(flowTest.NewSlice(input)).
@@ -220,11 +220,11 @@ var _ = Describe("Streaming", func() {
 				To(snk)
 
 			errCh = f.Open()
-			Expect(errCh).ShouldNot(BeNil())
+			gomega.Expect(errCh).ShouldNot(gomega.BeNil())
 		})
 
-		When("Top3", func() {
-			BeforeEach(func() {
+		g.When("Top3", func() {
+			g.BeforeEach(func() {
 				input = []flow.StreamRecord{
 					flow.NewStreamRecord(&record{"e2e-service-provider", "instance-001", 10000}, 1000),
 					flow.NewStreamRecord(&record{"e2e-service-consumer", "instance-001", 9900}, 2000),
@@ -237,22 +237,22 @@ var _ = Describe("Streaming", func() {
 				}
 			})
 
-			It("Should take top 3 elements", func() {
-				Eventually(func(g Gomega) {
-					g.Expect(len(snk.Value())).Should(BeNumerically(">=", 1))
+			g.It("Should take top 3 elements", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(len(snk.Value())).Should(gomega.BeNumerically(">=", 1))
 					// e2e-service-consumer Group
-					g.Expect(snk.Value()[0].(flow.StreamRecord).Data().(map[string][]*Tuple2)["e2e-service-consumer"]).Should(BeEquivalentTo([]*Tuple2{
+					g.Expect(snk.Value()[0].(flow.StreamRecord).Data().(map[string][]*Tuple2)["e2e-service-consumer"]).Should(gomega.BeEquivalentTo([]*Tuple2{
 						{int64(9900), flow.NewStreamRecord(flow.Data{"e2e-service-consumer", int64(9900)}, 2000)},
 						{int64(9700), flow.NewStreamRecord(flow.Data{"e2e-service-consumer", int64(9700)}, 4000)},
 						{int64(9600), flow.NewStreamRecord(flow.Data{"e2e-service-consumer", int64(9600)}, 6000)},
 					}))
 					// e2e-service-provider Group
-					g.Expect(snk.Value()[0].(flow.StreamRecord).Data().(map[string][]*Tuple2)["e2e-service-provider"]).Should(BeEquivalentTo([]*Tuple2{
+					g.Expect(snk.Value()[0].(flow.StreamRecord).Data().(map[string][]*Tuple2)["e2e-service-provider"]).Should(gomega.BeEquivalentTo([]*Tuple2{
 						{int64(10000), flow.NewStreamRecord(flow.Data{"e2e-service-provider", int64(10000)}, 1000)},
 						{int64(9800), flow.NewStreamRecord(flow.Data{"e2e-service-provider", int64(9800)}, 3000)},
 						{int64(9700), flow.NewStreamRecord(flow.Data{"e2e-service-provider", int64(9700)}, 5000)},
 					}))
-				}).WithTimeout(flags.EventuallyTimeout).Should(Succeed())
+				}).WithTimeout(flags.EventuallyTimeout).Should(gomega.Succeed())
 			})
 		})
 	})
diff --git a/pkg/fs/local_file_system.go b/pkg/fs/local_file_system.go
index 3a5b89c3..76df0b1f 100644
--- a/pkg/fs/local_file_system.go
+++ b/pkg/fs/local_file_system.go
@@ -253,11 +253,10 @@ func (file *LocalFile) Size() (int64, error) {
 				Code:    permissionError,
 				Message: fmt.Sprintf("There is not enough permission, file name: %s, error message: %s", file.file.Name(), err),
 			}
-		} else {
-			return -1, &FileSystemError{
-				Code:    otherError,
-				Message: fmt.Sprintf("Get file size error, file name: %s, error message: %s", file.file.Name(), err),
-			}
+		}
+		return -1, &FileSystemError{
+			Code:    otherError,
+			Message: fmt.Sprintf("Get file size error, file name: %s, error message: %s", file.file.Name(), err),
 		}
 	}
 	return fileInfo.Size(), nil
diff --git a/pkg/Makefile b/scripts/build/vendor.mk
similarity index 81%
copy from pkg/Makefile
copy to scripts/build/vendor.mk
index 043bc210..5b72c4d6 100644
--- a/pkg/Makefile
+++ b/scripts/build/vendor.mk
@@ -16,10 +16,10 @@
 # under the License.
 #
 
-NAME := pkg
 
-include ../scripts/build/base.mk
-include ../scripts/build/generate_go.mk
-include ../scripts/build/test.mk
-include ../scripts/build/lint.mk
-include ../scripts/build/help.mk
+##@ Vendor update
+
+.PHONY: vendor-update
+vendor-update: ## Update vendors
+	go get -u -d ./...
+	go mod tidy -compat=1.21
diff --git a/scripts/build/version.mk b/scripts/build/version.mk
index 8f212fbd..9f0e32c6 100644
--- a/scripts/build/version.mk
+++ b/scripts/build/version.mk
@@ -16,17 +16,17 @@
 # under the License.
 #
 
-BUF_VERSION := v1.23.1
+BUF_VERSION := v1.27.2
 PROTOC_GEN_GO_VERSION := v1.31.0
 PROTOC_GEN_GO_GRPC_VERSION := v1.3.0
 PROTOC_GEN_DOC_VERSION := v1.5.1
-GRPC_GATEWAY_VERSION := v2.16.0
+GRPC_GATEWAY_VERSION := v2.18.0
 PROTOC_GEN_VALIDATE_VERSION := v1.0.2
 
-GOLANGCI_LINT_VERSION := v1.53.3
-REVIVE_VERSION := v1.3.2
-LICENSE_EYE_VERSION := 5dfa68f93380a5e57259faaf95088b7f133b5778
+GOLANGCI_LINT_VERSION := v1.55.1
+REVIVE_VERSION := v1.3.4
+LICENSE_EYE_VERSION := a790ab8dd23a7f861c18bd6aaa9b012e3a234bce
 
-MOCKGEN_VERSION := v0.2.0
+MOCKGEN_VERSION := v0.3.0
 
-GINKGO_VERSION := v2.11.0
\ No newline at end of file
+GINKGO_VERSION := v2.13.0
\ No newline at end of file
diff --git a/scripts/ci/check/version_test.go b/scripts/ci/check/version_test.go
index 3085dd5d..680e6798 100644
--- a/scripts/ci/check/version_test.go
+++ b/scripts/ci/check/version_test.go
@@ -31,7 +31,7 @@ import (
 )
 
 const (
-	GoVersion = "1.20"
+	GoVersion = "1.21"
 	CPUType   = 8
 )
 
diff --git a/test/Makefile b/test/Makefile
index 25db9470..8840363f 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -22,4 +22,5 @@ include ../scripts/build/base.mk
 include ../scripts/build/generate_go.mk
 include ../scripts/build/test.mk
 include ../scripts/build/lint.mk
+include ../scripts/build/vendor.mk
 include ../scripts/build/help.mk
diff --git a/test/stress/cases/istio/istio_suite_test.go b/test/stress/cases/istio/istio_suite_test.go
index b6ac0957..9b3d4cb0 100644
--- a/test/stress/cases/istio/istio_suite_test.go
+++ b/test/stress/cases/istio/istio_suite_test.go
@@ -30,8 +30,8 @@ import (
 	"time"
 
 	"github.com/dustin/go-humanize"
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
+	g "github.com/onsi/ginkgo/v2"
+	"github.com/onsi/gomega"
 	"github.com/pkg/errors"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials/insecure"
@@ -50,8 +50,8 @@ import (
 )
 
 func TestIstio(t *testing.T) {
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "Istio Suite", Label("integration", "slow"))
+	gomega.RegisterFailHandler(g.Fail)
+	g.RunSpecs(t, "Istio Suite", g.Label("integration", "slow"))
 }
 
 var (
@@ -59,69 +59,69 @@ var (
 	heapProfileFile *os.File
 )
 
-var _ = BeforeSuite(func() {
+var _ = g.BeforeSuite(func() {
 	// Create CPU profile file
 	var err error
 	cpuProfileFile, err = os.Create("cpu.prof")
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 
 	// Start CPU profiling
 	err = pprof.StartCPUProfile(cpuProfileFile)
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 
 	// Create heap profile file
 	heapProfileFile, err = os.Create("heap.prof")
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 })
 
-var _ = AfterSuite(func() {
+var _ = g.AfterSuite(func() {
 	// Stop CPU profiling
 	pprof.StopCPUProfile()
 
 	// Write heap profile
 	err := pprof.WriteHeapProfile(heapProfileFile)
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 
 	// Close profile files
 	err = cpuProfileFile.Close()
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	err = heapProfileFile.Close()
-	Expect(err).NotTo(HaveOccurred())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 })
 
-var _ = Describe("Istio", func() {
-	BeforeEach(func() {
-		Expect(logger.Init(logger.Logging{
+var _ = g.Describe("Istio", func() {
+	g.BeforeEach(func() {
+		gomega.Expect(logger.Init(logger.Logging{
 			Env:   "dev",
 			Level: flags.LogLevel,
-		})).To(Succeed())
+		})).To(gomega.Succeed())
 	})
-	It("should pass", func() {
+	g.It("should pass", func() {
 		path, deferFn, err := test.NewSpace()
-		Expect(err).NotTo(HaveOccurred())
-		DeferCleanup(func() {
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
+		g.DeferCleanup(func() {
 			printDiskUsage(path+"/measure", 5, 0)
 			deferFn()
 		})
 		var ports []int
 		ports, err = test.AllocateFreePorts(4)
-		Expect(err).NotTo(HaveOccurred())
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 		addr, _, closerServerFunc := setup.ClosableStandaloneWithSchemaLoaders(
 			path, ports,
 			[]setup.SchemaLoader{&preloadService{name: "oap"}},
 			"--logging-level", "info")
-		DeferCleanup(closerServerFunc)
-		Eventually(helpers.HealthCheck(addr, 10*time.Second, 10*time.Second, grpc.WithTransportCredentials(insecure.NewCredentials())),
-			flags.EventuallyTimeout).Should(Succeed())
+		g.DeferCleanup(closerServerFunc)
+		gomega.Eventually(helpers.HealthCheck(addr, 10*time.Second, 10*time.Second, grpc.WithTransportCredentials(insecure.NewCredentials())),
+			flags.EventuallyTimeout).Should(gomega.Succeed())
 		bc := &clientCounter{}
 		conn, err := grpchelper.Conn(addr, 10*time.Second, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithStatsHandler(bc))
-		Expect(err).NotTo(HaveOccurred())
-		DeferCleanup(func() {
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
+		g.DeferCleanup(func() {
 			conn.Close()
 		})
 		startTime := time.Now()
 		writtenCount, err := ReadAndWriteFromFile(extractData(), conn)
-		Expect(err).To(Succeed())
+		gomega.Expect(err).To(gomega.Succeed())
 		endTime := time.Now()
 
 		fmt.Printf("written %d items in %s\n", writtenCount, endTime.Sub(startTime).String())
diff --git a/ui/Makefile b/ui/Makefile
index 3bac6cda..aed91b15 100644
--- a/ui/Makefile
+++ b/ui/Makefile
@@ -81,6 +81,11 @@ license-check: $(LICENSE_EYE) ## Check license header
 license-fix: $(LICENSE_EYE) ## Fix license header issues
 	$(LICENSE_EYE) header fix
 
+.PHONY: license-dep
 license-dep:$(LICENSE_EYE)
 	@rm -rf licenses
 	$(LICENSE_EYE) dep resolve -o ui-licenses -s LICENSE.tpl
+
+.PHONY: vendor-update
+vendor-update:
+	npm update
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 7c82ac7d..4fb2d787 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -29,7 +29,7 @@
         "vite": "^3.2.7"
       },
       "engines": {
-        "node": "18.16"
+        "node": "20.9"
       }
     },
     "node_modules/@antfu/utils": {
diff --git a/ui/package.json b/ui/package.json
index c07a2e30..bb27e70d 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -2,7 +2,7 @@
   "name": "ui",
   "version": "0.1.0",
   "engines": {
-    "node": "18.16"
+    "node": "20.9"
   },
   "scripts": {
     "dev": "vite",