mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-08 01:58:34 +08:00
Compare commits
260 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3439c3eb45 | ||
|
|
7109b2062a | ||
|
|
7b6aa2175f | ||
|
|
1e89b8b94a | ||
|
|
c258d03a01 | ||
|
|
99eccffe03 | ||
|
|
b71a123d25 | ||
|
|
ce762358af | ||
|
|
af64f2acba | ||
|
|
9b0e5cf032 | ||
|
|
e9d920a785 | ||
|
|
9942454811 | ||
|
|
731178a97f | ||
|
|
8ee392a682 | ||
|
|
511516a61b | ||
|
|
9ac5d66dc6 | ||
|
|
2989fbc666 | ||
|
|
17ac58a731 | ||
|
|
5b77d45a27 | ||
|
|
45bda55716 | ||
|
|
b8e28d227d | ||
|
|
52aa31324c | ||
|
|
e0fe0d7169 | ||
|
|
7afa1e7ce4 | ||
|
|
5d3e4dd038 | ||
|
|
b2ef076597 | ||
|
|
5ba7c4ed35 | ||
|
|
eaed10538d | ||
|
|
b948c62413 | ||
|
|
3e96bcc979 | ||
|
|
20592fb236 | ||
|
|
adf2be6506 | ||
|
|
07727e7f25 | ||
|
|
da601d2a3c | ||
|
|
18493d5cf5 | ||
|
|
1403bfdc68 | ||
|
|
d20b332e63 | ||
|
|
4cdeea5ddd | ||
|
|
49c6a5382c | ||
|
|
58e4673081 | ||
|
|
195022a8f0 | ||
|
|
507fe62027 | ||
|
|
1a2c21205d | ||
|
|
cbb79dae8c | ||
|
|
607c9ef40c | ||
|
|
fafec35bdc | ||
|
|
59e1b0b5b7 | ||
|
|
ce302c1555 | ||
|
|
feffbf90d2 | ||
|
|
a5008ea509 | ||
|
|
eef2d5b1a8 | ||
|
|
4cc6e015d4 | ||
|
|
1f2645dea0 | ||
|
|
1e5c49a463 | ||
|
|
428526aa22 | ||
|
|
b92f17b138 | ||
|
|
3394ac86f6 | ||
|
|
f49951e900 | ||
|
|
0a89b23240 | ||
|
|
37b163613b | ||
|
|
276a8628d2 | ||
|
|
22a7ac0ec6 | ||
|
|
1a37f6d56b | ||
|
|
171f218328 | ||
|
|
476c7a181c | ||
|
|
9a34fb61fa | ||
|
|
92f4b48a3c | ||
|
|
151ade0215 | ||
|
|
a48f7ae170 | ||
|
|
bc3b1bf61c | ||
|
|
efd9367c1f | ||
|
|
1ebb31e868 | ||
|
|
29c9132e55 | ||
|
|
3741fcdd78 | ||
|
|
78c479ce9b | ||
|
|
e4a85ab92e | ||
|
|
08ae6b5fcc | ||
|
|
6878de25ff | ||
|
|
ccc993bbb3 | ||
|
|
f288f698e3 | ||
|
|
3203119153 | ||
|
|
442bd23583 | ||
|
|
bafa5bd4c9 | ||
|
|
15a6a995f6 | ||
|
|
7be311320c | ||
|
|
aa5cd951a1 | ||
|
|
c33d6a0f49 | ||
|
|
15cf0c5147 | ||
|
|
601687d8d2 | ||
|
|
679d248c59 | ||
|
|
9b76d75e0a | ||
|
|
898e129326 | ||
|
|
d25c4053b8 | ||
|
|
df05e7c12c | ||
|
|
88ce11a361 | ||
|
|
9191c8dcfd | ||
|
|
a12444e3ca | ||
|
|
e4adb9fc56 | ||
|
|
df5da9c2b5 | ||
|
|
eee6ed91ca | ||
|
|
719b71c3f2 | ||
|
|
8ca120b841 | ||
|
|
a78b6e51b0 | ||
|
|
b1255dba6f | ||
|
|
245e96645f | ||
|
|
24a0782cb5 | ||
|
|
49e3059719 | ||
|
|
1cfb9f6881 | ||
|
|
2f6940253d | ||
|
|
9ff5731c7d | ||
|
|
7d13bdcf4c | ||
|
|
aaa8f4335d | ||
|
|
8b16216e01 | ||
|
|
85c8cca094 | ||
|
|
7cee398df1 | ||
|
|
2637854a12 | ||
|
|
1398a069d3 | ||
|
|
7380684b9e | ||
|
|
94563fb4f2 | ||
|
|
58f4afd3f0 | ||
|
|
7c37e444a2 | ||
|
|
0bfb5f6012 | ||
|
|
750af91c5a | ||
|
|
12e3fb7655 | ||
|
|
f3e5a53fc5 | ||
|
|
b856b396da | ||
|
|
b33c58807a | ||
|
|
27d737bbaf | ||
|
|
2c50d7e1f8 | ||
|
|
19fe1423d6 | ||
|
|
d91470e59e | ||
|
|
a42d3248e1 | ||
|
|
fb1b16186a | ||
|
|
c19fa9f5c3 | ||
|
|
9a26b11614 | ||
|
|
3df5f89cb0 | ||
|
|
e1ea30b04c | ||
|
|
8942bb7594 | ||
|
|
40806f9162 | ||
|
|
844fa8c999 | ||
|
|
282798371d | ||
|
|
122d024df4 | ||
|
|
9d7ef929e1 | ||
|
|
af766513f6 | ||
|
|
852b801e90 | ||
|
|
d490a5b4bf | ||
|
|
efaa538238 | ||
|
|
f21d7ce05b | ||
|
|
b8257facf2 | ||
|
|
bc47935600 | ||
|
|
f26ce204ce | ||
|
|
cb2bc2b41b | ||
|
|
4bc2dc86a0 | ||
|
|
02e2170601 | ||
|
|
cefdd25ef7 | ||
|
|
7451d89a22 | ||
|
|
902eea8e2c | ||
|
|
1be0dcf51e | ||
|
|
d095fb9bd3 | ||
|
|
318db122b8 | ||
|
|
022241cc14 | ||
|
|
debb00c83d | ||
|
|
d7134a6cc9 | ||
|
|
4bc8737c60 | ||
|
|
e70ee327f1 | ||
|
|
f3175d2964 | ||
|
|
7878293c46 | ||
|
|
7f10c98321 | ||
|
|
a0373a348a | ||
|
|
607fa69624 | ||
|
|
71bd07bcf7 | ||
|
|
a3006b7116 | ||
|
|
76b2d67c6a | ||
|
|
d84348b7a2 | ||
|
|
1df958f444 | ||
|
|
882cffaa96 | ||
|
|
60a802d3c8 | ||
|
|
71d75a1f9b | ||
|
|
a98aad0034 | ||
|
|
f9a49c60e4 | ||
|
|
a9d845b99e | ||
|
|
98c19386e3 | ||
|
|
95b0fb5a9b | ||
|
|
77578e08ed | ||
|
|
974d369019 | ||
|
|
9b075d7706 | ||
|
|
c3932022c9 | ||
|
|
a592cfc8b4 | ||
|
|
b3e525609c | ||
|
|
6677260b0f | ||
|
|
62cffb0105 | ||
|
|
dcb6d5b709 | ||
|
|
1f1fdcb1fe | ||
|
|
c22a2853b5 | ||
|
|
5bca28764b | ||
|
|
9b9a303a09 | ||
|
|
9cb6c0be2f | ||
|
|
09880e8e6c | ||
|
|
6476b1dbcf | ||
|
|
4312bfd030 | ||
|
|
41dfbba33a | ||
|
|
613b6a716e | ||
|
|
26c3983d93 | ||
|
|
fd22dc281a | ||
|
|
c835f4b0dc | ||
|
|
d6de935b88 | ||
|
|
b737011048 | ||
|
|
dc2c4d0f7f | ||
|
|
94c3f114eb | ||
|
|
1ff0d5d47d | ||
|
|
82c019181e | ||
|
|
64b76b723f | ||
|
|
ce8187d28e | ||
|
|
642a77a497 | ||
|
|
2dea67cc20 | ||
|
|
dd62691438 | ||
|
|
8e8b551b6f | ||
|
|
c6d951adb8 | ||
|
|
cfd748f50d | ||
|
|
2b5c2f7303 | ||
|
|
8cb49595e7 | ||
|
|
b43dcdf9aa | ||
|
|
bb4446e5af | ||
|
|
88b731d1f0 | ||
|
|
54fe82756a | ||
|
|
cd272e8c94 | ||
|
|
661b803d12 | ||
|
|
57f0d028bc | ||
|
|
abdf993efd | ||
|
|
8ed2717c3f | ||
|
|
3d0ad8b65d | ||
|
|
984f50e978 | ||
|
|
e23f923c21 | ||
|
|
40f0aef6b8 | ||
|
|
92996cba9d | ||
|
|
ddd4dcc942 | ||
|
|
71a0203ce2 | ||
|
|
c72a19d174 | ||
|
|
6ff30e8f9e | ||
|
|
781df9d0b3 | ||
|
|
d1d32eb1f9 | ||
|
|
363d214500 | ||
|
|
0a908c2e52 | ||
|
|
69a5ff5518 | ||
|
|
9af220e211 | ||
|
|
e469e89d83 | ||
|
|
fc6fe6e3bd | ||
|
|
0ca9a76ab8 | ||
|
|
07bca45376 | ||
|
|
a85b06d965 | ||
|
|
615544ee71 | ||
|
|
ce0a0b964e | ||
|
|
81ce0a3efe | ||
|
|
fb62c77bf7 | ||
|
|
778da323bd | ||
|
|
b08fba5074 | ||
|
|
98530564b5 | ||
|
|
ea4c2227da | ||
|
|
6c0a234ad6 | ||
|
|
8797703c09 |
8
.env
8
.env
@ -5,11 +5,11 @@ IMAGE_ARCH=amd64
|
||||
OS_NAME=ubuntu22.04
|
||||
|
||||
# for services.builder.image in docker-compose.yml
|
||||
DATE_VERSION=20250915-2b2a11a
|
||||
LATEST_DATE_VERSION=20250915-2b2a11a
|
||||
DATE_VERSION=20251011-78b266a
|
||||
LATEST_DATE_VERSION=20251011-78b266a
|
||||
# for services.gpubuilder.image in docker-compose.yml
|
||||
GPU_DATE_VERSION=20250915-2b2a11a
|
||||
LATEST_GPU_DATE_VERSION=20250915-2b2a11a
|
||||
GPU_DATE_VERSION=20251011-78b266a
|
||||
LATEST_GPU_DATE_VERSION=20251011-78b266a
|
||||
|
||||
# for other services in docker-compose.yml
|
||||
MINIO_ADDRESS=minio:9000
|
||||
|
||||
3
.github/workflows/mac.yaml
vendored
3
.github/workflows/mac.yaml
vendored
@ -61,7 +61,8 @@ jobs:
|
||||
- name: Setup Go environment
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.24.4'
|
||||
go-version: '1.24.9'
|
||||
cache: false
|
||||
- name: Download Caches
|
||||
uses: ./.github/actions/macos-cache-restore
|
||||
- name: Code Check
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -117,3 +117,6 @@ WARP.md
|
||||
|
||||
# Antlr
|
||||
.antlr
|
||||
|
||||
# Gocache
|
||||
**/.gocache/
|
||||
|
||||
@ -111,6 +111,8 @@ linters-settings:
|
||||
desc: "not allowed, gogo protobuf is deprecated"
|
||||
- pkg: "github.com/golang/protobuf/proto"
|
||||
desc: "not allowed, protobuf v1 is deprecated, use google.golang.org/protobuf/proto instead"
|
||||
- pkg: "github.com/pingcap/log"
|
||||
desc: "not allowed, use github.com/milvus-io/milvus/pkg/v2/log"
|
||||
forbidigo:
|
||||
forbid:
|
||||
- '^time\.Tick$'
|
||||
|
||||
27
Makefile
27
Makefile
@ -191,9 +191,11 @@ lint-fix: getdeps
|
||||
@$(INSTALL_PATH)/gci write pkg/ --skip-generated -s standard -s default -s "prefix(github.com/milvus-io)" --custom-order
|
||||
@$(INSTALL_PATH)/gci write client/ --skip-generated -s standard -s default -s "prefix(github.com/milvus-io)" --custom-order
|
||||
@$(INSTALL_PATH)/gci write tests/ --skip-generated -s standard -s default -s "prefix(github.com/milvus-io)" --custom-order
|
||||
@echo "Running golangci-lint auto-fix"
|
||||
@echo "Running golangci-lint auto-fix for core"
|
||||
@source $(PWD)/scripts/setenv.sh && GO111MODULE=on $(INSTALL_PATH)/golangci-lint run --fix --timeout=30m --config $(PWD)/.golangci.yml;
|
||||
@echo "Running golangci-lint auto-fix for pkg"
|
||||
@source $(PWD)/scripts/setenv.sh && cd pkg && GO111MODULE=on $(INSTALL_PATH)/golangci-lint run --fix --timeout=30m --config $(PWD)/.golangci.yml
|
||||
@echo "Running golangci-lint auto-fix for client"
|
||||
@source $(PWD)/scripts/setenv.sh && cd client && GO111MODULE=on $(INSTALL_PATH)/golangci-lint run --fix --timeout=30m --config $(PWD)/client/.golangci.yml
|
||||
|
||||
#TODO: Check code specifications by golangci-lint
|
||||
@ -386,6 +388,21 @@ run-test-cpp:
|
||||
@echo $(PWD)/scripts/run_cpp_unittest.sh arg=${filter}
|
||||
@(env bash $(PWD)/scripts/run_cpp_unittest.sh arg=${filter})
|
||||
|
||||
# tool for benchmark
|
||||
exprparser-tool:
|
||||
@echo "Building exprparser helper ..."
|
||||
@source $(PWD)/scripts/setenv.sh && \
|
||||
mkdir -p $(INSTALL_PATH) && go env -w CGO_ENABLED="1" && \
|
||||
GO111MODULE=on $(GO) build -pgo=$(PGO_PATH)/default.pgo -ldflags="-r $${RPATH}" -o $(INSTALL_PATH)/exprparser $(PWD)/cmd/tools/exprparser/main.go 1>/dev/null
|
||||
|
||||
# Build unittest with external scalar-benchmark enabled
|
||||
scalar-bench: generated-proto exprparser-tool
|
||||
@echo "Building Milvus cpp unittest with scalar-benchmark ... "
|
||||
@(export CMAKE_EXTRA_ARGS="-DENABLE_SCALAR_BENCH=ON"; env bash $(PWD)/scripts/core_build.sh -t ${mode} -a ${use_asan} -u -n ${use_disk_index} -y ${use_dynamic_simd} ${AZURE_OPTION} -x ${index_engine} -o ${use_opendal} -f $(tantivy_features))
|
||||
|
||||
scalar-bench-ui:
|
||||
@echo "Starting scalar-benchmark ui ... "
|
||||
@(cd cmake_build/unittest/scalar-benchmark-src/ui && ./serve_ui_dev.sh)
|
||||
|
||||
# Run code coverage.
|
||||
codecov: codecov-go codecov-cpp
|
||||
@ -478,12 +495,7 @@ generate-mockery-rootcoord: getdeps
|
||||
$(INSTALL_PATH)/mockery --name=IMetaTable --dir=$(PWD)/internal/rootcoord --output=$(PWD)/internal/rootcoord/mocks --filename=meta_table.go --with-expecter --outpkg=mockrootcoord
|
||||
|
||||
generate-mockery-proxy: getdeps
|
||||
$(INSTALL_PATH)/mockery --name=Cache --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_cache.go --structname=MockCache --with-expecter --outpkg=proxy --inpackage
|
||||
$(INSTALL_PATH)/mockery --name=timestampAllocatorInterface --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_tso_test.go --structname=mockTimestampAllocator --with-expecter --outpkg=proxy --inpackage
|
||||
$(INSTALL_PATH)/mockery --name=LBPolicy --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_lb_policy.go --structname=MockLBPolicy --with-expecter --outpkg=proxy --inpackage
|
||||
$(INSTALL_PATH)/mockery --name=LBBalancer --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_lb_balancer.go --structname=MockLBBalancer --with-expecter --outpkg=proxy --inpackage
|
||||
$(INSTALL_PATH)/mockery --name=shardClientMgr --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_shardclient_manager.go --structname=MockShardClientManager --with-expecter --outpkg=proxy --inpackage
|
||||
$(INSTALL_PATH)/mockery --name=channelsMgr --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_channels_manager.go --structname=MockChannelsMgr --with-expecter --outpkg=proxy --inpackage
|
||||
$(INSTALL_PATH)/mockery --config $(PWD)/internal/proxy/.mockery.yaml
|
||||
|
||||
generate-mockery-querycoord: getdeps
|
||||
$(INSTALL_PATH)/mockery --config $(PWD)/internal/querycoordv2/.mockery.yaml
|
||||
@ -523,6 +535,7 @@ generate-mockery-utils: getdeps
|
||||
# tso.Allocator
|
||||
$(INSTALL_PATH)/mockery --name=Allocator --dir=internal/tso --output=internal/tso/mocks --filename=allocator.go --with-expecter --structname=Allocator --outpkg=mocktso
|
||||
$(INSTALL_PATH)/mockery --name=SessionInterface --dir=$(PWD)/internal/util/sessionutil --output=$(PWD)/internal/util/sessionutil --filename=mock_session.go --with-expecter --structname=MockSession --inpackage
|
||||
$(INSTALL_PATH)/mockery --name=SessionWatcher --dir=$(PWD)/internal/util/sessionutil --output=$(PWD)/internal/util/sessionutil --filename=mock_session_watcher.go --with-expecter --structname=MockSessionWatcher --inpackage
|
||||
$(INSTALL_PATH)/mockery --name=GrpcClient --dir=$(PWD)/internal/util/grpcclient --output=$(PWD)/internal/mocks --filename=mock_grpc_client.go --with-expecter --structname=MockGrpcClient
|
||||
# proxy_client_manager.go
|
||||
$(INSTALL_PATH)/mockery --name=ProxyClientManagerInterface --dir=$(PWD)/internal/util/proxyutil --output=$(PWD)/internal/util/proxyutil --filename=mock_proxy_client_manager.go --with-expecter --structname=MockProxyClientManager --inpackage
|
||||
|
||||
@ -8,7 +8,7 @@ Homepage: https://github.com/milvus-io/milvus
|
||||
|
||||
Package: milvus
|
||||
Architecture: any-amd64
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, tzdata
|
||||
Description: An open-source vector dstabase for unstructured data.
|
||||
Milvus was created in 2019 with a singular goal: store, index, and manage massive embedding vectors generated by deep neural networks and other machine learning (ML) models.
|
||||
|
||||
|
||||
@ -15,14 +15,14 @@ ARG TARGETARCH
|
||||
|
||||
RUN dnf install -y wget g++ gcc gdb libatomic libstdc++-static ninja-build git make zip unzip tar which \
|
||||
autoconf automake python3 python3-pip perl-FindBin texinfo \
|
||||
pkg-config libuuid-devel libaio perl-IPC-Cmd libasan openblas-devel && \
|
||||
pkg-config libuuid-devel libaio perl-IPC-Cmd libasan openblas-devel tzdata && \
|
||||
rm -rf /var/cache/yum/*
|
||||
|
||||
ENV GOPATH /go
|
||||
ENV GOROOT /usr/local/go
|
||||
ENV GO111MODULE on
|
||||
ENV PATH $GOPATH/bin:$GOROOT/bin:$PATH
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
|
||||
mkdir -p "$GOPATH/src" "$GOPATH/bin" && \
|
||||
go clean --modcache && \
|
||||
chmod -R 777 "$GOPATH" && chmod -R a+w $(go env GOTOOLDIR)
|
||||
|
||||
@ -17,7 +17,7 @@ ARG TARGETARCH
|
||||
|
||||
RUN dnf install -y make cmake automake gcc gcc-c++ curl zip unzip tar git which \
|
||||
libaio libuuid-devel wget python3 python3-pip \
|
||||
pkg-config perl-IPC-Cmd perl-Digest-SHA libatomic libtool
|
||||
pkg-config perl-IPC-Cmd perl-Digest-SHA libatomic libtool tzdata
|
||||
|
||||
# install openblas-devel texinfo ninja
|
||||
RUN dnf -y update && \
|
||||
@ -27,7 +27,7 @@ RUN dnf -y update && \
|
||||
|
||||
|
||||
RUN pip3 install conan==1.64.1
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go
|
||||
RUN curl https://sh.rustup.rs -sSf | \
|
||||
sh -s -- --default-toolchain=1.89 -y
|
||||
|
||||
|
||||
@ -17,6 +17,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget curl ca-ce
|
||||
g++ gcc gdb gdbserver ninja-build git make ccache libssl-dev zlib1g-dev zip unzip \
|
||||
clang-format-12 clang-tidy-12 lcov libtool m4 autoconf automake python3 python3-pip \
|
||||
pkg-config uuid-dev libaio-dev libopenblas-dev && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
|
||||
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
|
||||
echo "Etc/UTC" > /etc/timezone && \
|
||||
apt-get remove --purge -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@ -30,7 +33,7 @@ ENV GOPATH /go
|
||||
ENV GOROOT /usr/local/go
|
||||
ENV GO111MODULE on
|
||||
ENV PATH $GOPATH/bin:$GOROOT/bin:$PATH
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
|
||||
mkdir -p "$GOPATH/src" "$GOPATH/bin" && \
|
||||
go clean --modcache && \
|
||||
chmod -R 777 "$GOPATH" && chmod -R a+w $(go env GOTOOLDIR)
|
||||
|
||||
@ -17,6 +17,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget curl ca-ce
|
||||
g++ gcc gdb gdbserver ninja-build git make ccache libssl-dev zlib1g-dev zip unzip \
|
||||
clang-format-12 clang-tidy-12 lcov libtool m4 autoconf automake python3 python3-pip \
|
||||
pkg-config uuid-dev libaio-dev libopenblas-dev && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
|
||||
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
|
||||
echo "Etc/UTC" > /etc/timezone && \
|
||||
apt-get remove --purge -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@ -36,7 +39,7 @@ ENV GOPATH /go
|
||||
ENV GOROOT /usr/local/go
|
||||
ENV GO111MODULE on
|
||||
ENV PATH $GOPATH/bin:$GOROOT/bin:$PATH
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
|
||||
mkdir -p "$GOPATH/src" "$GOPATH/bin" && \
|
||||
go clean --modcache && \
|
||||
chmod -R 777 "$GOPATH" && chmod -R a+w $(go env GOTOOLDIR)
|
||||
|
||||
@ -19,6 +19,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget curl ca-ce
|
||||
g++ gcc gfortran git make ccache libssl-dev zlib1g-dev zip unzip \
|
||||
clang-format-12 clang-tidy-12 lcov libtool m4 autoconf automake python3 python3-pip \
|
||||
pkg-config uuid-dev libaio-dev libgoogle-perftools-dev libopenblas-dev && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
|
||||
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
|
||||
echo "Etc/UTC" > /etc/timezone && \
|
||||
apt-get remove --purge -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@ -41,7 +44,7 @@ ENV GOPATH /go
|
||||
ENV GOROOT /usr/local/go
|
||||
ENV GO111MODULE on
|
||||
ENV PATH $GOPATH/bin:$GOROOT/bin:$PATH
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
|
||||
mkdir -p "$GOPATH/src" "$GOPATH/bin" && \
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ${GOROOT}/bin v1.46.2 && \
|
||||
# export GO111MODULE=on && go get github.com/quasilyte/go-ruleguard/cmd/ruleguard@v0.2.1 && \
|
||||
|
||||
@ -8,12 +8,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget curl ca-ce
|
||||
g++ gcc gfortran git make ccache libssl-dev zlib1g-dev zip unzip \
|
||||
clang-format-12 clang-tidy-12 lcov libtool m4 autoconf automake python3 python3-pip \
|
||||
pkg-config uuid-dev libaio-dev libgoogle-perftools-dev libopenblas-dev && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
|
||||
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
|
||||
echo "Etc/UTC" > /etc/timezone && \
|
||||
apt-get remove --purge -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
# Install go
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go
|
||||
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go
|
||||
# Install conan
|
||||
RUN pip3 install conan==1.64.1
|
||||
# Install rust
|
||||
|
||||
@ -14,7 +14,7 @@ FROM amazonlinux:2023
|
||||
ARG TARGETARCH
|
||||
ARG MILVUS_ASAN_LIB
|
||||
|
||||
RUN yum install -y wget libgomp libaio libatomic openblas-devel gcc gcc-c++ && \
|
||||
RUN yum install -y wget libgomp libaio libatomic openblas-devel tzdata && \
|
||||
rm -rf /var/cache/yum/*
|
||||
|
||||
# Add Tini
|
||||
|
||||
@ -21,6 +21,9 @@ ENV TZ=UTC
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends curl libtbb-dev gfortran netcat iputils-ping ca-certificates liblapack3 libzstd-dev uuid-dev libaio-dev libboost-program-options-dev libboost-filesystem-dev && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
|
||||
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
|
||||
echo "Etc/UTC" > /etc/timezone && \
|
||||
apt-get remove --purge -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
@ -8,6 +8,9 @@ RUN apt-get update && \
|
||||
sed -i 's/http:/https:/g' /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
|
||||
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
|
||||
echo "Etc/UTC" > /etc/timezone && \
|
||||
apt-get remove --purge -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ FROM rockylinux/rockylinux:8
|
||||
ARG TARGETARCH
|
||||
ARG MILVUS_ASAN_LIB
|
||||
|
||||
RUN dnf install -y wget libgomp libaio libatomic gcc gcc-c++
|
||||
RUN dnf install -y wget libgomp libaio libatomic tzdata
|
||||
|
||||
# install openblas-devel
|
||||
RUN dnf -y install dnf-plugins-core && \
|
||||
|
||||
@ -19,7 +19,10 @@ RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends ca-certificates && \
|
||||
sed -i 's/http:/https:/g' /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev gcc g++ && \
|
||||
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
|
||||
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
|
||||
echo "Etc/UTC" > /etc/timezone && \
|
||||
apt-get remove --purge -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
@ -19,7 +19,10 @@ RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends ca-certificates && \
|
||||
sed -i 's/http:/https:/g' /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev gcc g++ && \
|
||||
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
|
||||
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
|
||||
echo "Etc/UTC" > /etc/timezone && \
|
||||
apt-get remove --purge -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ Version: %{version}
|
||||
Release: %{release}
|
||||
Summary: Milvus V2 RPM
|
||||
License: Apache License 2.0
|
||||
Requires(preun): libstdc++ libgomp tbb-devel
|
||||
Requires(preun): libstdc++ libgomp tbb-devel tzdata
|
||||
# tbb-devel actually provides it, but not defined
|
||||
Provides: libtbb.so()(64bit)
|
||||
BuildArch: x86_64
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env groovy
|
||||
|
||||
// DEPRECATED: This job is deprecated, it is replaced by nightly2 job
|
||||
|
||||
// When scheduling a job that gets automatically triggered by changes,
|
||||
// you need to include a [cronjob] tag within the commit message.
|
||||
String cron_timezone = 'TZ=Asia/Shanghai'
|
||||
|
||||
@ -3,12 +3,12 @@
|
||||
def pod = libraryResource 'io/milvus/pod/tekton-4am.yaml'
|
||||
|
||||
String cron_timezone = 'TZ=Asia/Shanghai'
|
||||
String cron_string = BRANCH_NAME == 'master' ? '50 4 * * * ' : ''
|
||||
String cron_string = BRANCH_NAME == '2.6' ? '50 1 * * * ' : ''
|
||||
|
||||
// Make timeout 4 hours so that we can run two nightly during the ci
|
||||
int total_timeout_minutes = 7 * 60
|
||||
|
||||
def milvus_helm_chart_version = '5.0.0'
|
||||
def milvus_helm_chart_version = '5.0.6'
|
||||
|
||||
pipeline {
|
||||
triggers {
|
||||
|
||||
@ -4,7 +4,7 @@ int total_timeout_minutes = 60 * 5
|
||||
int e2e_timeout_seconds = 120 * 60
|
||||
def imageTag=''
|
||||
int case_timeout_seconds = 20 * 60
|
||||
def chart_version='5.0.0'
|
||||
def chart_version='5.0.6'
|
||||
pipeline {
|
||||
options {
|
||||
timestamps()
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
def pod = libraryResource 'io/milvus/pod/tekton-4am.yaml'
|
||||
|
||||
def milvus_helm_chart_version = '5.0.0'
|
||||
def milvus_helm_chart_version = '5.0.6'
|
||||
|
||||
pipeline {
|
||||
options {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
@Library('jenkins-shared-library@tekton') _
|
||||
|
||||
def pod = libraryResource 'io/milvus/pod/tekton-4am.yaml'
|
||||
def milvus_helm_chart_version = '5.0.0'
|
||||
def milvus_helm_chart_version = '5.0.6'
|
||||
|
||||
pipeline {
|
||||
options {
|
||||
|
||||
@ -4,7 +4,7 @@ int total_timeout_minutes = 60 * 5
|
||||
int e2e_timeout_seconds = 70 * 60
|
||||
def imageTag=''
|
||||
int case_timeout_seconds = 10 * 60
|
||||
def chart_version='5.0.0'
|
||||
def chart_version='5.0.6'
|
||||
pipeline {
|
||||
options {
|
||||
timestamps()
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
@Library('jenkins-shared-library@tekton') _
|
||||
|
||||
// DEPRECATED: This job is deprecated, it is replaced by ci-v2/ut-cpp job
|
||||
|
||||
def pod = libraryResource 'io/milvus/pod/tekton-4am.yaml'
|
||||
def milvus_helm_chart_version = '4.2.56'
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ Go MilvusClient for [Milvus](https://github.com/milvus-io/milvus). To contribute
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Go 1.24.4 or higher
|
||||
Go 1.24.9 or higher
|
||||
|
||||
### Install Milvus Go SDK
|
||||
|
||||
|
||||
@ -18,5 +18,5 @@ package common
|
||||
|
||||
const (
|
||||
// SDKVersion const value for current version
|
||||
SDKVersion = `2.6.0`
|
||||
SDKVersion = `2.6.1`
|
||||
)
|
||||
|
||||
@ -1,22 +1,20 @@
|
||||
module github.com/milvus-io/milvus/client/v2
|
||||
|
||||
go 1.24.4
|
||||
go 1.24.9
|
||||
|
||||
require (
|
||||
github.com/blang/semver/v4 v4.0.0
|
||||
github.com/cockroachdb/errors v1.9.1
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3
|
||||
github.com/milvus-io/milvus/pkg/v2 v2.0.0-20250319085209-5a6b4e56d59e
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7
|
||||
github.com/milvus-io/milvus/pkg/v2 v2.6.7-0.20251201120310-af64f2acba38
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.23
|
||||
github.com/samber/lo v1.27.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/tidwall/gjson v1.17.1
|
||||
go.opentelemetry.io/otel v1.28.0
|
||||
go.uber.org/atomic v1.11.0
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
|
||||
google.golang.org/grpc v1.65.0
|
||||
google.golang.org/protobuf v1.34.2
|
||||
google.golang.org/grpc v1.71.0
|
||||
google.golang.org/protobuf v1.36.5
|
||||
)
|
||||
|
||||
require (
|
||||
@ -29,10 +27,11 @@ require (
|
||||
github.com/containerd/cgroups/v3 v3.0.3 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/getsentry/sentry-go v0.12.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
@ -42,29 +41,31 @@ require (
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.2.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.0.2 // indirect
|
||||
github.com/panjf2000/ants/v2 v2.11.3 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.22.9 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/soheilhy/cmux v0.1.5 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
@ -73,13 +74,14 @@ require (
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
|
||||
github.com/twpayne/go-geom v1.6.1 // indirect
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.5 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
|
||||
@ -88,29 +90,32 @@ require (
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.5 // indirect
|
||||
go.etcd.io/etcd/raft/v3 v3.5.5 // indirect
|
||||
go.etcd.io/etcd/server/v3 v3.5.5 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||
go.uber.org/automaxprocs v1.5.3 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/time v0.10.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.28.6 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
k8s.io/apimachinery v0.32.3 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
||||
187
client/go.sum
187
client/go.sum
@ -13,15 +13,19 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY=
|
||||
github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@ -88,14 +92,15 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
@ -117,6 +122,8 @@ github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD
|
||||
github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
|
||||
github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
|
||||
@ -159,8 +166,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
|
||||
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4=
|
||||
github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc=
|
||||
github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
@ -215,8 +222,9 @@ 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/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
@ -248,6 +256,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
|
||||
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||
@ -265,8 +275,8 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/Kgo2/7xNSUuC5G28VR8ljfrLKU2G4IjU=
|
||||
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
@ -283,6 +293,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
@ -295,6 +307,8 @@ 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/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
@ -313,15 +327,13 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3 h1:w7IBrU25KULWNlHKoKwx6ruTsDAmzrWknotIc6A4ys4=
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
|
||||
github.com/milvus-io/milvus/pkg/v2 v2.0.0-20250319085209-5a6b4e56d59e h1:VCr43pG4efacDbM4au70fh8/5hNTftoWzm1iEumvDWM=
|
||||
github.com/milvus-io/milvus/pkg/v2 v2.0.0-20250319085209-5a6b4e56d59e/go.mod h1:37AWzxVs2NS4QUJrkcbeLUwi+4Av0h5mEdjLI62EANU=
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7 h1:RJtZbkS5zKNIXxsqjGBUZc2SbnI4MGq+TfOfc8tJsuM=
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
|
||||
github.com/milvus-io/milvus/pkg/v2 v2.6.7-0.20251201120310-af64f2acba38 h1:75pdNz8Ln9jdBxlkUQRJu+P8tz4q+G48XAybS3O30FQ=
|
||||
github.com/milvus-io/milvus/pkg/v2 v2.6.7-0.20251201120310-af64f2acba38/go.mod h1:ak5nlCCbtImG4/WWcI/csU5ht6EyF/9QQ/tmivMzF4c=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@ -338,6 +350,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
@ -363,8 +377,9 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
@ -375,39 +390,41 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.23 h1:lxjt5B6ZCiBeeNO8/oQsegE6fLeCzuMRoVWSkXC4uvY=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.23/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
|
||||
github.com/remeh/sizedwaitgroup v1.0.0 h1:VNGGFwNo/R5+MJBf6yrsr110p0m4/OX4S3DCy7Kyl5E=
|
||||
github.com/remeh/sizedwaitgroup v1.0.0/go.mod h1:3j2R4OIe/SeS6YDhICBy22RWjJC5eNCJ1V+9+NVNYlo=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
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.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
@ -417,8 +434,12 @@ github.com/samber/lo v1.27.0/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+R
|
||||
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA=
|
||||
github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
@ -449,6 +470,7 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@ -458,8 +480,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
|
||||
github.com/thoas/go-funk v0.9.1/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
|
||||
@ -469,13 +492,15 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/twpayne/go-geom v1.6.1 h1:iLE+Opv0Ihm/ABIcvQFGIiFBXd76oBIar9drAwHFhR4=
|
||||
github.com/twpayne/go-geom v1.6.1/go.mod h1:Kr+Nly6BswFsKM5sd31YaoWS5PeDDH2NftJTK7Gd028=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
@ -503,8 +528,8 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
@ -524,26 +549,30 @@ go.etcd.io/etcd/server/v3 v3.5.5 h1:jNjYm/9s+f9A9r6+SC4RvNaz6AqixpOvhrFdT0PvIj0=
|
||||
go.etcd.io/etcd/server/v3 v3.5.5/go.mod h1:rZ95vDw/jrvsbj9XpTqPrTAB9/kzchVdhRirySPkUBc=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||
go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU=
|
||||
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
|
||||
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0=
|
||||
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
|
||||
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||
go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk=
|
||||
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
|
||||
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||
@ -577,8 +606,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -632,8 +661,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
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=
|
||||
@ -647,8 +676,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -691,12 +720,13 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -705,14 +735,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/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.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
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-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
|
||||
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -768,12 +798,12 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
|
||||
google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d h1:PksQg4dV6Sem3/HkBX+Ltq8T0ke0PKIRBNBatoDTVls=
|
||||
google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:s7iA721uChleev562UJO2OYB0PPT9CMFjV+Ce7VJH5M=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e h1:YA5lmSs3zc/5w+xsRcHqpETkaYyK63ivEPzNTcUUlSA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
||||
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
@ -788,8 +818,8 @@ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
||||
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@ -802,8 +832,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@ -819,8 +849,9 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
@ -843,9 +874,9 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
k8s.io/apimachinery v0.28.6 h1:RsTeR4z6S07srPg6XYrwXpTJVMXsjPXn0ODakMytSW0=
|
||||
k8s.io/apimachinery v0.28.6/go.mod h1:QFNX/kCl/EMT2WTSz8k4WLCv2XnkOLMaL8GAVRMdpsA=
|
||||
k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
|
||||
k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
|
||||
@ -86,6 +86,65 @@ func (_c *MilvusServiceServer_AddCollectionField_Call) RunAndReturn(run func(con
|
||||
return _c
|
||||
}
|
||||
|
||||
// AddCollectionFunction provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MilvusServiceServer) AddCollectionFunction(_a0 context.Context, _a1 *milvuspb.AddCollectionFunctionRequest) (*commonpb.Status, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AddCollectionFunction")
|
||||
}
|
||||
|
||||
var r0 *commonpb.Status
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFunctionRequest) (*commonpb.Status, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFunctionRequest) *commonpb.Status); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*commonpb.Status)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.AddCollectionFunctionRequest) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MilvusServiceServer_AddCollectionFunction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddCollectionFunction'
|
||||
type MilvusServiceServer_AddCollectionFunction_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// AddCollectionFunction is a helper method to define mock.On call
|
||||
// - _a0 context.Context
|
||||
// - _a1 *milvuspb.AddCollectionFunctionRequest
|
||||
func (_e *MilvusServiceServer_Expecter) AddCollectionFunction(_a0 interface{}, _a1 interface{}) *MilvusServiceServer_AddCollectionFunction_Call {
|
||||
return &MilvusServiceServer_AddCollectionFunction_Call{Call: _e.mock.On("AddCollectionFunction", _a0, _a1)}
|
||||
}
|
||||
|
||||
func (_c *MilvusServiceServer_AddCollectionFunction_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.AddCollectionFunctionRequest)) *MilvusServiceServer_AddCollectionFunction_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*milvuspb.AddCollectionFunctionRequest))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MilvusServiceServer_AddCollectionFunction_Call) Return(_a0 *commonpb.Status, _a1 error) *MilvusServiceServer_AddCollectionFunction_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MilvusServiceServer_AddCollectionFunction_Call) RunAndReturn(run func(context.Context, *milvuspb.AddCollectionFunctionRequest) (*commonpb.Status, error)) *MilvusServiceServer_AddCollectionFunction_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// AddFileResource provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MilvusServiceServer) AddFileResource(_a0 context.Context, _a1 *milvuspb.AddFileResourceRequest) (*commonpb.Status, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
@ -440,6 +499,65 @@ func (_c *MilvusServiceServer_AlterCollectionField_Call) RunAndReturn(run func(c
|
||||
return _c
|
||||
}
|
||||
|
||||
// AlterCollectionFunction provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MilvusServiceServer) AlterCollectionFunction(_a0 context.Context, _a1 *milvuspb.AlterCollectionFunctionRequest) (*commonpb.Status, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AlterCollectionFunction")
|
||||
}
|
||||
|
||||
var r0 *commonpb.Status
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AlterCollectionFunctionRequest) (*commonpb.Status, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AlterCollectionFunctionRequest) *commonpb.Status); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*commonpb.Status)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.AlterCollectionFunctionRequest) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MilvusServiceServer_AlterCollectionFunction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AlterCollectionFunction'
|
||||
type MilvusServiceServer_AlterCollectionFunction_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// AlterCollectionFunction is a helper method to define mock.On call
|
||||
// - _a0 context.Context
|
||||
// - _a1 *milvuspb.AlterCollectionFunctionRequest
|
||||
func (_e *MilvusServiceServer_Expecter) AlterCollectionFunction(_a0 interface{}, _a1 interface{}) *MilvusServiceServer_AlterCollectionFunction_Call {
|
||||
return &MilvusServiceServer_AlterCollectionFunction_Call{Call: _e.mock.On("AlterCollectionFunction", _a0, _a1)}
|
||||
}
|
||||
|
||||
func (_c *MilvusServiceServer_AlterCollectionFunction_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.AlterCollectionFunctionRequest)) *MilvusServiceServer_AlterCollectionFunction_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*milvuspb.AlterCollectionFunctionRequest))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MilvusServiceServer_AlterCollectionFunction_Call) Return(_a0 *commonpb.Status, _a1 error) *MilvusServiceServer_AlterCollectionFunction_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MilvusServiceServer_AlterCollectionFunction_Call) RunAndReturn(run func(context.Context, *milvuspb.AlterCollectionFunctionRequest) (*commonpb.Status, error)) *MilvusServiceServer_AlterCollectionFunction_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// AlterDatabase provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MilvusServiceServer) AlterDatabase(_a0 context.Context, _a1 *milvuspb.AlterDatabaseRequest) (*commonpb.Status, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
@ -2138,6 +2256,65 @@ func (_c *MilvusServiceServer_DropCollection_Call) RunAndReturn(run func(context
|
||||
return _c
|
||||
}
|
||||
|
||||
// DropCollectionFunction provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MilvusServiceServer) DropCollectionFunction(_a0 context.Context, _a1 *milvuspb.DropCollectionFunctionRequest) (*commonpb.Status, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DropCollectionFunction")
|
||||
}
|
||||
|
||||
var r0 *commonpb.Status
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.DropCollectionFunctionRequest) (*commonpb.Status, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.DropCollectionFunctionRequest) *commonpb.Status); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*commonpb.Status)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.DropCollectionFunctionRequest) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MilvusServiceServer_DropCollectionFunction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DropCollectionFunction'
|
||||
type MilvusServiceServer_DropCollectionFunction_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// DropCollectionFunction is a helper method to define mock.On call
|
||||
// - _a0 context.Context
|
||||
// - _a1 *milvuspb.DropCollectionFunctionRequest
|
||||
func (_e *MilvusServiceServer_Expecter) DropCollectionFunction(_a0 interface{}, _a1 interface{}) *MilvusServiceServer_DropCollectionFunction_Call {
|
||||
return &MilvusServiceServer_DropCollectionFunction_Call{Call: _e.mock.On("DropCollectionFunction", _a0, _a1)}
|
||||
}
|
||||
|
||||
func (_c *MilvusServiceServer_DropCollectionFunction_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.DropCollectionFunctionRequest)) *MilvusServiceServer_DropCollectionFunction_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*milvuspb.DropCollectionFunctionRequest))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MilvusServiceServer_DropCollectionFunction_Call) Return(_a0 *commonpb.Status, _a1 error) *MilvusServiceServer_DropCollectionFunction_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MilvusServiceServer_DropCollectionFunction_Call) RunAndReturn(run func(context.Context, *milvuspb.DropCollectionFunctionRequest) (*commonpb.Status, error)) *MilvusServiceServer_DropCollectionFunction_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// DropDatabase provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MilvusServiceServer) DropDatabase(_a0 context.Context, _a1 *milvuspb.DropDatabaseRequest) (*commonpb.Status, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
@ -26,10 +26,7 @@ func (c *Client) UpdateReplicateConfiguration(ctx context.Context, config *commo
|
||||
}
|
||||
|
||||
// GetReplicateInfo gets replicate information from the Milvus cluster
|
||||
func (c *Client) GetReplicateInfo(ctx context.Context, sourceClusterID string, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error) {
|
||||
req := &milvuspb.GetReplicateInfoRequest{
|
||||
SourceClusterId: sourceClusterID,
|
||||
}
|
||||
func (c *Client) GetReplicateInfo(ctx context.Context, req *milvuspb.GetReplicateInfoRequest, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error) {
|
||||
var resp *milvuspb.GetReplicateInfoResponse
|
||||
err := c.callService(func(milvusService milvuspb.MilvusServiceClient) error {
|
||||
var err error
|
||||
|
||||
@ -21,6 +21,7 @@ import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus/client/v2/milvusclient"
|
||||
)
|
||||
|
||||
@ -81,13 +82,16 @@ func ExampleClient_GetReplicateInfo() {
|
||||
}
|
||||
|
||||
// Get replicate information for a specific source cluster
|
||||
resp, err := cli.GetReplicateInfo(ctx, "source-cluster")
|
||||
resp, err := cli.GetReplicateInfo(ctx, &milvuspb.GetReplicateInfoRequest{
|
||||
SourceClusterId: "source-cluster",
|
||||
TargetPchannel: "source-channel-dml_0",
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Failed to get replicate information: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Replicate information retrieved successfully, checkpoint count: %d", len(resp.GetCheckpoints()))
|
||||
log.Printf("Replicate information retrieved successfully, checkpoint: %v", resp.GetCheckpoint())
|
||||
}
|
||||
|
||||
func ExampleClient_CreateReplicateStream() {
|
||||
|
||||
@ -216,7 +216,7 @@ func (c *mck) connectEctd() {
|
||||
var err error
|
||||
log := log.Ctx(context.TODO())
|
||||
if c.etcdIP != "" {
|
||||
etcdCli, err = etcd.GetRemoteEtcdClient([]string{c.etcdIP})
|
||||
etcdCli, err = etcd.GetRemoteEtcdClient([]string{c.etcdIP}, c.params.EtcdCfg.ClientOptions()...)
|
||||
} else {
|
||||
etcdCli, err = etcd.CreateEtcdClient(
|
||||
c.params.EtcdCfg.UseEmbedEtcd.GetAsBool(),
|
||||
@ -228,7 +228,8 @@ func (c *mck) connectEctd() {
|
||||
c.params.EtcdCfg.EtcdTLSCert.GetValue(),
|
||||
c.params.EtcdCfg.EtcdTLSKey.GetValue(),
|
||||
c.params.EtcdCfg.EtcdTLSCACert.GetValue(),
|
||||
c.params.EtcdCfg.EtcdTLSMinVersion.GetValue())
|
||||
c.params.EtcdCfg.EtcdTLSMinVersion.GetValue(),
|
||||
c.params.EtcdCfg.ClientOptions()...)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal("failed to connect to etcd", zap.Error(err))
|
||||
|
||||
@ -21,7 +21,6 @@ import (
|
||||
|
||||
"github.com/milvus-io/milvus/cmd/roles"
|
||||
"github.com/milvus-io/milvus/internal/util/sessionutil"
|
||||
"github.com/milvus-io/milvus/internal/util/streamingutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/etcd"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/hardware"
|
||||
@ -138,7 +137,7 @@ func GetMilvusRoles(args []string, flags *flag.FlagSet) *roles.MilvusRoles {
|
||||
case typeutil.DataNodeRole:
|
||||
role.EnableDataNode = true
|
||||
case typeutil.StreamingNodeRole:
|
||||
streamingutil.EnableEmbededQueryNode()
|
||||
sessionutil.EnableEmbededQueryNodeLabel()
|
||||
role.EnableStreamingNode = true
|
||||
role.EnableQueryNode = true
|
||||
case typeutil.StandaloneRole, typeutil.EmbeddedRole:
|
||||
@ -149,9 +148,9 @@ func GetMilvusRoles(args []string, flags *flag.FlagSet) *roles.MilvusRoles {
|
||||
role.EnableStreamingNode = true
|
||||
role.Local = true
|
||||
role.Embedded = serverType == typeutil.EmbeddedRole
|
||||
sessionutil.EnableStandaloneLabel()
|
||||
case typeutil.MixCoordRole:
|
||||
role.EnableMixCoord = true
|
||||
|
||||
case typeutil.MixtureRole:
|
||||
role.EnableRootCoord = enableRootCoord
|
||||
role.EnableQueryCoord = enableQueryCoord
|
||||
@ -162,7 +161,7 @@ func GetMilvusRoles(args []string, flags *flag.FlagSet) *roles.MilvusRoles {
|
||||
role.EnableStreamingNode = enableStreamingNode
|
||||
if enableStreamingNode && !enableQueryNode {
|
||||
role.EnableQueryNode = true
|
||||
streamingutil.EnableEmbededQueryNode()
|
||||
sessionutil.EnableEmbededQueryNodeLabel()
|
||||
}
|
||||
|
||||
case typeutil.CDCRole:
|
||||
|
||||
@ -21,12 +21,14 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/samber/lo"
|
||||
@ -50,10 +52,10 @@ import (
|
||||
rocksmqimpl "github.com/milvus-io/milvus/pkg/v2/mq/mqimpl/rocksmq/server"
|
||||
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
|
||||
"github.com/milvus-io/milvus/pkg/v2/tracer"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/conc"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/etcd"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/expr"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/gc"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/generic"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/logutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/metricsinfo"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
|
||||
@ -109,35 +111,40 @@ func runComponent[T component](ctx context.Context,
|
||||
runWg *sync.WaitGroup,
|
||||
creator func(context.Context, dependency.Factory) (T, error),
|
||||
metricRegister func(*prometheus.Registry),
|
||||
) component {
|
||||
var role T
|
||||
|
||||
) *conc.Future[component] {
|
||||
sign := make(chan struct{})
|
||||
go func() {
|
||||
factory := dependency.NewFactory(localMsg)
|
||||
var err error
|
||||
role, err = creator(ctx, factory)
|
||||
future := conc.Go(func() (component, error) {
|
||||
// Wrap the creation and preparation phase to enable concurrent component startup
|
||||
prepareFunc := func() (component, error) {
|
||||
defer close(sign)
|
||||
factory := dependency.NewFactory(localMsg)
|
||||
var err error
|
||||
role, err := creator(ctx, factory)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "create component failed")
|
||||
}
|
||||
if err := role.Prepare(); err != nil {
|
||||
return nil, errors.Wrap(err, "prepare component failed")
|
||||
}
|
||||
healthz.Register(role)
|
||||
metricRegister(Registry.GoRegistry)
|
||||
return role, nil
|
||||
}
|
||||
|
||||
role, err := prepareFunc()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
if err := role.Prepare(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
close(sign)
|
||||
|
||||
// Run() executes after sign is closed, allowing components to start concurrently
|
||||
if err := role.Run(); err != nil {
|
||||
panic(err)
|
||||
return nil, errors.Wrap(err, "run component failed")
|
||||
}
|
||||
runWg.Done()
|
||||
}()
|
||||
return role, nil
|
||||
})
|
||||
|
||||
<-sign
|
||||
|
||||
healthz.Register(role)
|
||||
metricRegister(Registry.GoRegistry)
|
||||
if generic.IsZero(role) {
|
||||
return nil
|
||||
}
|
||||
return role
|
||||
return future
|
||||
}
|
||||
|
||||
// MilvusRoles decides which components are brought up with Milvus.
|
||||
@ -177,18 +184,15 @@ func (mr *MilvusRoles) printLDPreLoad() {
|
||||
}
|
||||
}
|
||||
|
||||
func (mr *MilvusRoles) runProxy(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
|
||||
wg.Add(1)
|
||||
func (mr *MilvusRoles) runProxy(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
|
||||
return runComponent(ctx, localMsg, wg, components.NewProxy, metrics.RegisterProxy)
|
||||
}
|
||||
|
||||
func (mr *MilvusRoles) runMixCoord(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
|
||||
wg.Add(1)
|
||||
func (mr *MilvusRoles) runMixCoord(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
|
||||
return runComponent(ctx, localMsg, wg, components.NewMixCoord, metrics.RegisterMixCoord)
|
||||
}
|
||||
|
||||
func (mr *MilvusRoles) runQueryNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
|
||||
wg.Add(1)
|
||||
func (mr *MilvusRoles) runQueryNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
|
||||
// clear local storage
|
||||
queryDataLocalPath := pathutil.GetPath(pathutil.RootCachePath, 0)
|
||||
if !paramtable.Get().CommonCfg.EnablePosixMode.GetAsBool() {
|
||||
@ -199,21 +203,73 @@ func (mr *MilvusRoles) runQueryNode(ctx context.Context, localMsg bool, wg *sync
|
||||
return runComponent(ctx, localMsg, wg, components.NewQueryNode, metrics.RegisterQueryNode)
|
||||
}
|
||||
|
||||
func (mr *MilvusRoles) runStreamingNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
|
||||
wg.Add(1)
|
||||
func (mr *MilvusRoles) runStreamingNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
|
||||
return runComponent(ctx, localMsg, wg, components.NewStreamingNode, metrics.RegisterStreamingNode)
|
||||
}
|
||||
|
||||
func (mr *MilvusRoles) runDataNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
|
||||
wg.Add(1)
|
||||
func (mr *MilvusRoles) runDataNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
|
||||
return runComponent(ctx, localMsg, wg, components.NewDataNode, metrics.RegisterDataNode)
|
||||
}
|
||||
|
||||
func (mr *MilvusRoles) runCDC(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
|
||||
wg.Add(1)
|
||||
func (mr *MilvusRoles) runCDC(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
|
||||
return runComponent(ctx, localMsg, wg, components.NewCDC, metrics.RegisterCDC)
|
||||
}
|
||||
|
||||
func (mr *MilvusRoles) waitForAllComponentsReady(cancel context.CancelFunc, componentFutureMap map[string]*conc.Future[component]) (map[string]component, error) {
|
||||
roles := make([]string, 0, len(componentFutureMap))
|
||||
futures := make([]*conc.Future[component], 0, len(componentFutureMap))
|
||||
for role, future := range componentFutureMap {
|
||||
roles = append(roles, role)
|
||||
futures = append(futures, future)
|
||||
}
|
||||
selectCases := make([]reflect.SelectCase, 1+len(componentFutureMap))
|
||||
selectCases[0] = reflect.SelectCase{
|
||||
Dir: reflect.SelectRecv,
|
||||
Chan: reflect.ValueOf(mr.closed),
|
||||
}
|
||||
for i, future := range futures {
|
||||
selectCases[i+1] = reflect.SelectCase{
|
||||
Dir: reflect.SelectRecv,
|
||||
Chan: reflect.ValueOf(future.Inner()),
|
||||
}
|
||||
}
|
||||
componentMap := make(map[string]component, len(componentFutureMap))
|
||||
readyCount := 0
|
||||
var gerr error
|
||||
for {
|
||||
index, _, _ := reflect.Select(selectCases)
|
||||
if index == 0 {
|
||||
cancel()
|
||||
log.Warn("components are not ready before closing, wait for the start of components to be canceled...")
|
||||
} else {
|
||||
role := roles[index-1]
|
||||
component, err := futures[index-1].Await()
|
||||
readyCount++
|
||||
if err != nil {
|
||||
if gerr == nil {
|
||||
gerr = errors.Wrapf(err, "component %s is not ready before closing", role)
|
||||
cancel()
|
||||
}
|
||||
log.Warn("component is not ready before closing", zap.String("role", role), zap.Error(err))
|
||||
} else {
|
||||
componentMap[role] = component
|
||||
log.Info("component is ready", zap.String("role", role))
|
||||
}
|
||||
}
|
||||
selectCases[index] = reflect.SelectCase{
|
||||
Dir: reflect.SelectRecv,
|
||||
Chan: reflect.ValueOf(nil),
|
||||
}
|
||||
if readyCount == len(componentFutureMap) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if gerr != nil {
|
||||
return nil, errors.Wrap(gerr, "failed to wait for all components ready")
|
||||
}
|
||||
return componentMap, nil
|
||||
}
|
||||
|
||||
func (mr *MilvusRoles) setupLogger() {
|
||||
params := paramtable.Get()
|
||||
logConfig := log.Config{
|
||||
@ -227,6 +283,13 @@ func (mr *MilvusRoles) setupLogger() {
|
||||
MaxDays: params.LogCfg.MaxAge.GetAsInt(),
|
||||
MaxBackups: params.LogCfg.MaxBackups.GetAsInt(),
|
||||
},
|
||||
AsyncWriteEnable: params.LogCfg.AsyncWriteEnable.GetAsBool(),
|
||||
AsyncWriteFlushInterval: params.LogCfg.AsyncWriteFlushInterval.GetAsDurationByParse(),
|
||||
AsyncWriteDroppedTimeout: params.LogCfg.AsyncWriteDroppedTimeout.GetAsDurationByParse(),
|
||||
AsyncWriteStopTimeout: params.LogCfg.AsyncWriteStopTimeout.GetAsDurationByParse(),
|
||||
AsyncWritePendingLength: params.LogCfg.AsyncWritePendingLength.GetAsInt(),
|
||||
AsyncWriteBufferSize: int(params.LogCfg.AsyncWriteBufferSize.GetAsSize()),
|
||||
AsyncWriteMaxBytesPerLog: int(params.LogCfg.AsyncWriteMaxBytesPerLog.GetAsSize()),
|
||||
}
|
||||
id := paramtable.GetNodeID()
|
||||
roleName := paramtable.GetRole()
|
||||
@ -238,6 +301,7 @@ func (mr *MilvusRoles) setupLogger() {
|
||||
}
|
||||
|
||||
logutil.SetupLogger(&logConfig)
|
||||
|
||||
params.Watch(params.LogCfg.Level.Key, config.NewHandler("log.level", func(event *config.Event) {
|
||||
if !event.HasUpdated || event.EventType == config.DeleteType {
|
||||
return
|
||||
@ -361,14 +425,6 @@ func (mr *MilvusRoles) Run() {
|
||||
// init tracer before run any component
|
||||
tracer.Init()
|
||||
|
||||
// Initialize streaming service if enabled.
|
||||
|
||||
if mr.ServerType == typeutil.StandaloneRole || !mr.EnableDataNode {
|
||||
// only datanode does not init streaming service
|
||||
streaming.Init()
|
||||
defer streaming.Release()
|
||||
}
|
||||
|
||||
enableComponents := []bool{
|
||||
mr.EnableProxy,
|
||||
mr.EnableQueryNode,
|
||||
@ -388,6 +444,8 @@ func (mr *MilvusRoles) Run() {
|
||||
expr.Init()
|
||||
expr.Register("param", paramtable.Get())
|
||||
mr.setupLogger()
|
||||
defer log.Cleanup()
|
||||
|
||||
http.ServeHTTP()
|
||||
setupPrometheusHTTPServer(Registry)
|
||||
|
||||
@ -403,51 +461,61 @@ func (mr *MilvusRoles) Run() {
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize streaming service if enabled.
|
||||
if mr.ServerType == typeutil.StandaloneRole || !mr.EnableDataNode {
|
||||
// only datanode does not init streaming service
|
||||
streaming.Init()
|
||||
defer streaming.Release()
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
local := mr.Local
|
||||
|
||||
componentMap := make(map[string]component)
|
||||
var mixCoord component
|
||||
var proxy, dataNode, queryNode, streamingNode, cdc component
|
||||
componentFutureMap := make(map[string]*conc.Future[component])
|
||||
|
||||
if (mr.EnableRootCoord && mr.EnableDataCoord && mr.EnableQueryCoord) || mr.EnableMixCoord {
|
||||
paramtable.SetLocalComponentEnabled(typeutil.MixCoordRole)
|
||||
mixCoord = mr.runMixCoord(ctx, local, &wg)
|
||||
componentMap[typeutil.MixCoordRole] = mixCoord
|
||||
mixCoord := mr.runMixCoord(ctx, local, &wg)
|
||||
componentFutureMap[typeutil.MixCoordRole] = mixCoord
|
||||
}
|
||||
|
||||
if mr.EnableQueryNode {
|
||||
paramtable.SetLocalComponentEnabled(typeutil.QueryNodeRole)
|
||||
queryNode = mr.runQueryNode(ctx, local, &wg)
|
||||
componentMap[typeutil.QueryNodeRole] = queryNode
|
||||
queryNode := mr.runQueryNode(ctx, local, &wg)
|
||||
componentFutureMap[typeutil.QueryNodeRole] = queryNode
|
||||
}
|
||||
|
||||
if mr.EnableDataNode {
|
||||
paramtable.SetLocalComponentEnabled(typeutil.DataNodeRole)
|
||||
dataNode = mr.runDataNode(ctx, local, &wg)
|
||||
componentMap[typeutil.DataNodeRole] = dataNode
|
||||
dataNode := mr.runDataNode(ctx, local, &wg)
|
||||
componentFutureMap[typeutil.DataNodeRole] = dataNode
|
||||
}
|
||||
|
||||
if mr.EnableProxy {
|
||||
paramtable.SetLocalComponentEnabled(typeutil.ProxyRole)
|
||||
proxy = mr.runProxy(ctx, local, &wg)
|
||||
componentMap[typeutil.ProxyRole] = proxy
|
||||
proxy := mr.runProxy(ctx, local, &wg)
|
||||
componentFutureMap[typeutil.ProxyRole] = proxy
|
||||
}
|
||||
|
||||
if mr.EnableStreamingNode {
|
||||
// Before initializing the local streaming node, make sure the local registry is ready.
|
||||
paramtable.SetLocalComponentEnabled(typeutil.StreamingNodeRole)
|
||||
streamingNode = mr.runStreamingNode(ctx, local, &wg)
|
||||
componentMap[typeutil.StreamingNodeRole] = streamingNode
|
||||
streamingNode := mr.runStreamingNode(ctx, local, &wg)
|
||||
componentFutureMap[typeutil.StreamingNodeRole] = streamingNode
|
||||
}
|
||||
|
||||
if mr.EnableCDC {
|
||||
paramtable.SetLocalComponentEnabled(typeutil.CDCRole)
|
||||
cdc = mr.runCDC(ctx, local, &wg)
|
||||
componentMap[typeutil.CDCRole] = cdc
|
||||
cdc := mr.runCDC(ctx, local, &wg)
|
||||
componentFutureMap[typeutil.CDCRole] = cdc
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
componentMap, err := mr.waitForAllComponentsReady(cancel, componentFutureMap)
|
||||
if err != nil {
|
||||
log.Warn("Failed to wait for all components ready", zap.Error(err))
|
||||
return
|
||||
}
|
||||
log.Info("All components are ready", zap.Strings("roles", lo.Keys(componentMap)))
|
||||
|
||||
http.RegisterStopComponent(func(role string) error {
|
||||
if len(role) == 0 || componentMap[role] == nil {
|
||||
@ -505,6 +573,13 @@ func (mr *MilvusRoles) Run() {
|
||||
|
||||
<-mr.closed
|
||||
|
||||
mixCoord := componentMap[typeutil.MixCoordRole]
|
||||
streamingNode := componentMap[typeutil.StreamingNodeRole]
|
||||
queryNode := componentMap[typeutil.QueryNodeRole]
|
||||
dataNode := componentMap[typeutil.DataNodeRole]
|
||||
cdc := componentMap[typeutil.CDCRole]
|
||||
proxy := componentMap[typeutil.ProxyRole]
|
||||
|
||||
// stop coordinators first
|
||||
coordinators := []component{mixCoord}
|
||||
for idx, coord := range coordinators {
|
||||
|
||||
115
cmd/tools/exprparser/main.go
Normal file
115
cmd/tools/exprparser/main.go
Normal file
@ -0,0 +1,115 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
schemapb "github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/parser/planparserv2"
|
||||
_ "github.com/milvus-io/milvus/pkg/v2/proto/planpb"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
|
||||
)
|
||||
|
||||
type parseRequest struct {
|
||||
ID string `json:"id"`
|
||||
Op string `json:"op"`
|
||||
SchemaB64 string `json:"schema_b64"`
|
||||
Expr string `json:"expr"`
|
||||
Options struct {
|
||||
IsCount bool `json:"is_count"`
|
||||
Limit int64 `json:"limit"`
|
||||
} `json:"options"`
|
||||
}
|
||||
|
||||
type parseResponse struct {
|
||||
ID string `json:"id"`
|
||||
OK bool `json:"ok"`
|
||||
PlanB64 string `json:"plan_b64,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func handle(line string) parseResponse {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
return parseResponse{ID: "", OK: false, Error: "empty line"}
|
||||
}
|
||||
|
||||
var req parseRequest
|
||||
if err := json.Unmarshal([]byte(line), &req); err != nil {
|
||||
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("invalid json: %v", err)}
|
||||
}
|
||||
if req.Op != "parse_expr" {
|
||||
return parseResponse{ID: req.ID, OK: false, Error: "unsupported op"}
|
||||
}
|
||||
if req.SchemaB64 == "" {
|
||||
return parseResponse{ID: req.ID, OK: false, Error: "missing schema_b64"}
|
||||
}
|
||||
if req.Expr == "" {
|
||||
return parseResponse{ID: req.ID, OK: false, Error: "missing expr"}
|
||||
}
|
||||
|
||||
schemaBytes, err := base64.StdEncoding.DecodeString(req.SchemaB64)
|
||||
if err != nil {
|
||||
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("decode schema_b64 failed: %v", err)}
|
||||
}
|
||||
var schema schemapb.CollectionSchema
|
||||
if err := proto.Unmarshal(schemaBytes, &schema); err != nil {
|
||||
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("unmarshal schema failed: %v", err)}
|
||||
}
|
||||
|
||||
helper, err := typeutil.CreateSchemaHelper(&schema)
|
||||
if err != nil {
|
||||
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("schema helper error: %v", err)}
|
||||
}
|
||||
|
||||
planNode, err := planparserv2.CreateRetrievePlan(helper, req.Expr, nil)
|
||||
if err != nil {
|
||||
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("parse error: %v", err)}
|
||||
}
|
||||
|
||||
// Apply options if provided
|
||||
if q := planNode.GetQuery(); q != nil {
|
||||
q.IsCount = req.Options.IsCount
|
||||
if req.Options.Limit > 0 {
|
||||
q.Limit = req.Options.Limit
|
||||
}
|
||||
}
|
||||
|
||||
planBytes, err := proto.Marshal(planNode)
|
||||
if err != nil {
|
||||
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("marshal plan failed: %v", err)}
|
||||
}
|
||||
return parseResponse{ID: req.ID, OK: true, PlanB64: base64.StdEncoding.EncodeToString(planBytes)}
|
||||
}
|
||||
|
||||
func writeResp(w *bufio.Writer, resp parseResponse) {
|
||||
b, _ := json.Marshal(resp)
|
||||
_, _ = w.Write(b)
|
||||
_ = w.WriteByte('\n')
|
||||
_ = w.Flush()
|
||||
}
|
||||
|
||||
func main() {
|
||||
in := bufio.NewScanner(os.Stdin)
|
||||
buf := make([]byte, 0, 1024*1024)
|
||||
in.Buffer(buf, 16*1024*1024)
|
||||
w := bufio.NewWriter(os.Stdout)
|
||||
|
||||
for {
|
||||
if !in.Scan() {
|
||||
if err := in.Err(); err != nil && err != io.EOF {
|
||||
writeResp(w, parseResponse{ID: "", OK: false, Error: fmt.Sprintf("scan error: %v", err)})
|
||||
}
|
||||
break
|
||||
}
|
||||
resp := handle(in.Text())
|
||||
writeResp(w, resp)
|
||||
}
|
||||
}
|
||||
@ -32,7 +32,8 @@ func newEtcdBasedBackend(cfg *configs.MilvusConfig) (*etcdBasedBackend, error) {
|
||||
cfg.EtcdCfg.EtcdTLSCert.GetValue(),
|
||||
cfg.EtcdCfg.EtcdTLSKey.GetValue(),
|
||||
cfg.EtcdCfg.EtcdTLSCACert.GetValue(),
|
||||
cfg.EtcdCfg.EtcdTLSMinVersion.GetValue())
|
||||
cfg.EtcdCfg.EtcdTLSMinVersion.GetValue(),
|
||||
cfg.EtcdCfg.ClientOptions()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -49,12 +49,12 @@ func (r *Runner) watchByPrefix(prefix string) {
|
||||
_, revision, err := r.session.GetSessions(prefix)
|
||||
fn := func() { r.Stop() }
|
||||
console.AbnormalExitIf(err, r.backupFinished.Load(), console.AddCallbacks(fn))
|
||||
eventCh := r.session.WatchServices(prefix, revision, nil)
|
||||
watcher := r.session.WatchServices(prefix, revision, nil)
|
||||
for {
|
||||
select {
|
||||
case <-r.ctx.Done():
|
||||
return
|
||||
case event := <-eventCh:
|
||||
case event := <-watcher.EventChannel():
|
||||
msg := fmt.Sprintf("session up/down, exit migration, event type: %s, session: %s", event.EventType.String(), event.Session.String())
|
||||
console.AbnormalExit(r.backupFinished.Load(), msg, console.AddCallbacks(fn))
|
||||
}
|
||||
@ -79,7 +79,8 @@ func (r *Runner) initEtcdCli() {
|
||||
r.cfg.EtcdCfg.EtcdTLSCert.GetValue(),
|
||||
r.cfg.EtcdCfg.EtcdTLSKey.GetValue(),
|
||||
r.cfg.EtcdCfg.EtcdTLSCACert.GetValue(),
|
||||
r.cfg.EtcdCfg.EtcdTLSMinVersion.GetValue())
|
||||
r.cfg.EtcdCfg.EtcdTLSMinVersion.GetValue(),
|
||||
r.cfg.EtcdCfg.ClientOptions()...)
|
||||
console.AbnormalExitIf(err, r.backupFinished.Load())
|
||||
r.etcdCli = cli
|
||||
}
|
||||
@ -164,7 +165,6 @@ func (r *Runner) CheckSessions() error {
|
||||
|
||||
func (r *Runner) RegisterSession() error {
|
||||
r.session.Register()
|
||||
r.session.LivenessCheck(r.ctx, func() {})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@ func (r *Runner) waitUntilSessionExpired() {
|
||||
}
|
||||
|
||||
func (r *Runner) Stop() {
|
||||
r.session.Revoke(time.Second)
|
||||
r.session.Stop()
|
||||
r.waitUntilSessionExpired()
|
||||
r.cancel()
|
||||
r.wg.Wait()
|
||||
|
||||
@ -19,6 +19,7 @@ import (
|
||||
// Therefore, we need to read configs from 2.3.x and modify meta data if necessary.
|
||||
type MmapMigration struct {
|
||||
rootcoordMeta rootcoord.IMetaTable
|
||||
rootCoordCatalog metastore.RootCoordCatalog
|
||||
tsoAllocator tso.Allocator
|
||||
datacoordCatalog metastore.DataCoordCatalog
|
||||
}
|
||||
@ -58,8 +59,7 @@ func (m *MmapMigration) MigrateRootCoordCollection(ctx context.Context) {
|
||||
|
||||
newColl.Properties = updateOrAddMmapKey(newColl.Properties, common.MmapEnabledKey, "true")
|
||||
fmt.Printf("migrate collection %v, %s\n", collection.CollectionID, collection.Name)
|
||||
|
||||
if err := m.rootcoordMeta.AlterCollection(ctx, collection, newColl, ts, false); err != nil {
|
||||
if err := m.rootCoordCatalog.AlterCollection(ctx, collection, newColl, metastore.MODIFY, ts, false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -100,9 +100,10 @@ func (m *MmapMigration) MigrateIndexCoordCollection(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func NewMmapMigration(rootcoordMeta rootcoord.IMetaTable, tsoAllocator tso.Allocator, datacoordCatalog metastore.DataCoordCatalog) *MmapMigration {
|
||||
func NewMmapMigration(rootcoordMeta rootcoord.IMetaTable, tsoAllocator tso.Allocator, datacoordCatalog metastore.DataCoordCatalog, rootCoordCatalog metastore.RootCoordCatalog) *MmapMigration {
|
||||
return &MmapMigration{
|
||||
rootcoordMeta: rootcoordMeta,
|
||||
rootCoordCatalog: rootCoordCatalog,
|
||||
tsoAllocator: tsoAllocator,
|
||||
datacoordCatalog: datacoordCatalog,
|
||||
}
|
||||
|
||||
@ -42,9 +42,9 @@ func main() {
|
||||
}
|
||||
fmt.Printf("MmapDirPath: %s\n", paramtable.Get().QueryNodeCfg.MmapDirPath.GetValue())
|
||||
allocator := prepareTsoAllocator()
|
||||
rootCoordMeta := prepareRootCoordMeta(context.Background(), allocator)
|
||||
rootCoordMeta, rootCoordCatalog := prepareRootCoordMeta(context.Background(), allocator)
|
||||
dataCoordCatalog := prepareDataCoordCatalog()
|
||||
m := mmap.NewMmapMigration(rootCoordMeta, allocator, dataCoordCatalog)
|
||||
m := mmap.NewMmapMigration(rootCoordMeta, allocator, dataCoordCatalog, rootCoordCatalog)
|
||||
m.Migrate(context.Background())
|
||||
}
|
||||
|
||||
@ -75,7 +75,8 @@ func prepareTsoAllocator() tso.Allocator {
|
||||
etcdConfig.EtcdTLSCert.GetValue(),
|
||||
etcdConfig.EtcdTLSKey.GetValue(),
|
||||
etcdConfig.EtcdTLSCACert.GetValue(),
|
||||
etcdConfig.EtcdTLSMinVersion.GetValue())
|
||||
etcdConfig.EtcdTLSMinVersion.GetValue(),
|
||||
etcdConfig.ClientOptions()...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -109,7 +110,8 @@ func metaKVCreator() (kv.MetaKv, error) {
|
||||
etcdConfig.EtcdTLSCert.GetValue(),
|
||||
etcdConfig.EtcdTLSKey.GetValue(),
|
||||
etcdConfig.EtcdTLSCACert.GetValue(),
|
||||
etcdConfig.EtcdTLSMinVersion.GetValue())
|
||||
etcdConfig.EtcdTLSMinVersion.GetValue(),
|
||||
etcdConfig.ClientOptions()...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -117,7 +119,7 @@ func metaKVCreator() (kv.MetaKv, error) {
|
||||
etcdkv.WithRequestTimeout(paramtable.Get().ServiceParam.EtcdCfg.RequestTimeout.GetAsDuration(time.Millisecond))), nil
|
||||
}
|
||||
|
||||
func prepareRootCoordMeta(ctx context.Context, allocator tso.Allocator) rootcoord.IMetaTable {
|
||||
func prepareRootCoordMeta(ctx context.Context, allocator tso.Allocator) (rootcoord.IMetaTable, metastore.RootCoordCatalog) {
|
||||
var catalog metastore.RootCoordCatalog
|
||||
var err error
|
||||
|
||||
@ -158,7 +160,7 @@ func prepareRootCoordMeta(ctx context.Context, allocator tso.Allocator) rootcoor
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return meta
|
||||
return meta, catalog
|
||||
}
|
||||
|
||||
func prepareDataCoordCatalog() metastore.DataCoordCatalog {
|
||||
|
||||
@ -53,6 +53,8 @@ etcd:
|
||||
# We recommend using version 1.2 and above.
|
||||
tlsMinVersion: 1.3
|
||||
requestTimeout: 10000 # Etcd operation timeout in milliseconds
|
||||
dialKeepAliveTime: 3000 # Interval in milliseconds for gRPC dial keepalive pings sent to etcd endpoints.
|
||||
dialKeepAliveTimeout: 2000 # Timeout in milliseconds waiting for keepalive responses before marking the connection as unhealthy.
|
||||
use:
|
||||
embed: false # Whether to enable embedded Etcd (an in-process EtcdServer).
|
||||
data:
|
||||
@ -211,6 +213,8 @@ woodpecker:
|
||||
segmentReadPolicy:
|
||||
maxBatchSize: 16M # Maximum size of a batch in bytes.
|
||||
maxFetchThreads: 32 # Maximum number of threads to fetch data.
|
||||
retentionPolicy:
|
||||
ttl: 72h # Time to live for truncated segments in seconds, default is 72h
|
||||
storage:
|
||||
type: minio # The Type of the storage provider. Valid values: [minio, local]
|
||||
rootPath: default # The root path of the storage provider. If set to 'default', uses localStorage.path as base directory and creates a woodpecker subdirectory. Otherwise, specifies a custom woodpecker data storage directory.
|
||||
@ -242,8 +246,7 @@ pulsar:
|
||||
# If these options is non-zero, the wal data in pulsar is fully protected by retention policy,
|
||||
# so admin of pulsar should give enough retention time to avoid the wal message lost.
|
||||
# If these options is zero, no subscription will be created, so pulsar cluster must close the backlog protection, otherwise the milvus can not recovered if backlog exceed.
|
||||
# Moreover, if these option is zero, Milvus use a truncation subscriber to protect the wal data in pulsar if user disable the subscriptionExpirationTimeMinutes.
|
||||
# The retention policy of pulsar can set shorter to save the storage space in this case.
|
||||
# If this option is zero or negative, it will be ignored and the default value (100m) will be used.
|
||||
backlogAutoClearBytes: 100m
|
||||
|
||||
# If you want to enable kafka, needs to comment the pulsar configs
|
||||
@ -310,7 +313,7 @@ proxy:
|
||||
bufSize: 512 # The maximum number of messages can be buffered in the timeTick message stream of the proxy when producing messages.
|
||||
maxNameLength: 255 # The maximum length of the name or alias that can be created in Milvus, including the collection name, collection alias, partition name, and field name.
|
||||
maxFieldNum: 64 # The maximum number of field can be created when creating in a collection. It is strongly DISCOURAGED to set maxFieldNum >= 64.
|
||||
maxVectorFieldNum: 4 # The maximum number of vector fields that can be specified in a collection. Value range: [1, 10].
|
||||
maxVectorFieldNum: 4 # The maximum number of vector fields that can be specified in a collection
|
||||
maxShardNum: 16 # The maximum number of shards can be created when creating in a collection.
|
||||
maxDimension: 32768 # The maximum number of dimensions of a vector can have when creating in a collection.
|
||||
# Whether to produce gin logs.\n
|
||||
@ -465,6 +468,7 @@ queryNode:
|
||||
memExpansionRate: 1.15 # extra memory needed by building interim index
|
||||
buildParallelRate: 0.5 # the ratio of building interim index parallel matched with cpu num
|
||||
multipleChunkedEnable: true # Deprecated. Enable multiple chunked search
|
||||
enableGeometryCache: false # Enable geometry cache for geometry data
|
||||
tieredStorage:
|
||||
warmup:
|
||||
# options: sync, disable.
|
||||
@ -488,20 +492,6 @@ queryNode:
|
||||
# Enable eviction for Tiered Storage. Defaults to false.
|
||||
# Note that if eviction is enabled, cache data loaded during sync warmup is also subject to eviction.
|
||||
evictionEnabled: false
|
||||
# This ratio estimates how much evictable memory can be cached.
|
||||
# The higher the ratio, the more physical memory is reserved for evictable memory,
|
||||
# resulting in fewer evictions but fewer segments can be loaded.
|
||||
# Conversely, a lower ratio results in more evictions but allows more segments to be loaded.
|
||||
# This parameter is only valid when eviction is enabled.
|
||||
# It defaults to 0.3 (meaning about 30% of evictable in-memory data can be cached), with a valid range of [0.0, 1.0].
|
||||
evictableMemoryCacheRatio: 0.3
|
||||
# This ratio estimates how much evictable disk space can be cached.
|
||||
# The higher the ratio, the more physical disk space is reserved for evictable disk usage,
|
||||
# resulting in fewer evictions but fewer segments can be loaded.
|
||||
# Conversely, a lower ratio results in more evictions but allows more segments to be loaded.
|
||||
# This parameter is only valid when eviction is enabled.
|
||||
# It defaults to 0.3 (meaning about 30% of evictable on-disk data can be cached), with a valid range of [0.0, 1.0].
|
||||
evictableDiskCacheRatio: 0.3
|
||||
# Enable background eviction for Tiered Storage. Defaults to false.
|
||||
# Background eviction is used to do periodic eviction in a separate thread.
|
||||
# And it will only work when both 'evictionEnabled' and 'backgroundEvictionEnabled' are set to 'true'.
|
||||
@ -524,7 +514,7 @@ queryNode:
|
||||
vectorIndex: false # Enable mmap for loading vector index
|
||||
scalarField: false # Enable mmap for loading scalar data
|
||||
scalarIndex: false # Enable mmap for loading scalar index
|
||||
jsonStats: true # Enable mmap for loading json stats
|
||||
jsonShredding: true # Enable mmap for loading json stats
|
||||
# Enable memory mapping (mmap) to optimize the handling of growing raw data.
|
||||
# By activating this feature, the memory overhead associated with newly added or modified data will be significantly minimized.
|
||||
# However, this optimization may come at the cost of a slight decrease in query latency for the affected data segments.
|
||||
@ -742,11 +732,11 @@ dataCoord:
|
||||
indexTaskSlotUsage: 64 # slot usage of index task per 512mb
|
||||
statsTaskSlotUsage: 8 # slot usage of stats task per 512mb
|
||||
analyzeTaskSlotUsage: 65535 # slot usage of analyze task
|
||||
jsonStatsTriggerCount: 10 # jsonkey stats task count per trigger
|
||||
jsonStatsTriggerInterval: 10 # jsonkey task interval per trigger
|
||||
jsonStatsMaxShreddingColumns: 1024 # the max number of columns to shred
|
||||
jsonStatsShreddingRatioThreshold: 0.3 # the ratio threshold to shred
|
||||
jsonStatsWriteBatchSize: 819200 # the batch size to write
|
||||
jsonShreddingTriggerCount: 10 # jsonkey stats task count per trigger
|
||||
jsonShreddingTriggerInterval: 10 # jsonkey task interval per trigger
|
||||
jsonShreddingMaxColumns: 1024 # the max number of columns to shred
|
||||
jsonShreddingRatioThreshold: 0.3 # the ratio threshold to shred
|
||||
jsonShreddingWriteBatchSize: 81920 # the batch size to write
|
||||
ip: # TCP/IP address of dataCoord. If not specified, use the first unicastable address
|
||||
port: 13333 # TCP port of dataCoord
|
||||
grpc:
|
||||
@ -945,7 +935,7 @@ common:
|
||||
# Currently, only QueryNode uses 'common.diskWrite*' parameters. Support for other components will be added in the future.
|
||||
# The options include 'direct' and 'buffered'. The default value is 'buffered'.
|
||||
diskWriteMode: buffered
|
||||
# Disk write buffer size in KB, only used when disk write mode is 'direct', default is 64KB.
|
||||
# Disk write buffer size in KB, used for both 'direct' and 'buffered' modes, default is 64KB.
|
||||
# Current valid range is [4, 65536]. If the value is not aligned to 4KB, it will be rounded up to the nearest multiple of 4KB.
|
||||
diskWriteBufferSizeKb: 64
|
||||
# This parameter controls the number of writer threads used for disk write operations. The valid range is [0, hardware_concurrency].
|
||||
@ -983,7 +973,7 @@ common:
|
||||
readwrite:
|
||||
privileges: ListDatabases,SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,ListPrivilegeGroups,FlushAll,TransferNode,TransferReplica,UpdateResourceGroups # Cluster level readwrite privileges
|
||||
admin:
|
||||
privileges: ListDatabases,SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,ListPrivilegeGroups,FlushAll,TransferNode,TransferReplica,UpdateResourceGroups,BackupRBAC,RestoreRBAC,CreateDatabase,DropDatabase,CreateOwnership,DropOwnership,ManageOwnership,CreateResourceGroup,DropResourceGroup,UpdateUser,RenameCollection,CreatePrivilegeGroup,DropPrivilegeGroup,OperatePrivilegeGroup # Cluster level admin privileges
|
||||
privileges: ListDatabases,SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,ListPrivilegeGroups,FlushAll,TransferNode,TransferReplica,UpdateResourceGroups,BackupRBAC,RestoreRBAC,CreateDatabase,DropDatabase,CreateOwnership,DropOwnership,ManageOwnership,CreateResourceGroup,DropResourceGroup,UpdateUser,RenameCollection,CreatePrivilegeGroup,DropPrivilegeGroup,OperatePrivilegeGroup,UpdateReplicateConfiguration # Cluster level admin privileges
|
||||
database:
|
||||
readonly:
|
||||
privileges: ShowCollections,DescribeDatabase # Database level readonly privileges
|
||||
@ -1001,7 +991,7 @@ common:
|
||||
internaltlsEnabled: false
|
||||
tlsMode: 0
|
||||
session:
|
||||
ttl: 10 # ttl value when session granting a lease to register service
|
||||
ttl: 15 # ttl value when session granting a lease to register service
|
||||
retryTimes: 30 # retry times when session sending etcd requests
|
||||
locks:
|
||||
metrics:
|
||||
@ -1036,11 +1026,11 @@ common:
|
||||
sync:
|
||||
taskPoolReleaseTimeoutSeconds: 60 # The maximum time to wait for the task to finish and release resources in the pool
|
||||
enabledOptimizeExpr: true # Indicates whether to enable optimize expr
|
||||
enabledJSONKeyStats: false # Indicates sealedsegment whether to enable JSON key stats
|
||||
enabledGrowingSegmentJSONKeyStats: false # Indicates growingsegment whether to enable JSON key stats
|
||||
enabledJSONShredding: false # Indicates sealedsegment whether to enable JSON key stats
|
||||
enabledGrowingSegmentJSONShredding: false # Indicates growingsegment whether to enable JSON key stats
|
||||
enableConfigParamTypeCheck: true # Indicates whether to enable config param type check
|
||||
enablePosixMode: false # Specifies whether to run in POSIX mode for enhanced file system compatibility
|
||||
UsingJSONStatsForQuery: true # Indicates whether to use json stats when query
|
||||
usingJSONShreddingForQuery: true # Indicates whether to use json stats when query
|
||||
clusterID: 0 # cluster id
|
||||
|
||||
# QuotaConfig, configurations of Milvus quota and limits.
|
||||
@ -1223,6 +1213,7 @@ quotaAndLimits:
|
||||
diskProtection:
|
||||
enabled: true # When the total file size of object storage is greater than `diskQuota`, all dml requests would be rejected;
|
||||
diskQuota: -1 # MB, (0, +inf), default no limit
|
||||
loadedDiskQuota: -1 # MB, (0, +inf), default no limit
|
||||
diskQuotaPerDB: -1 # MB, (0, +inf), default no limit
|
||||
diskQuotaPerCollection: -1 # MB, (0, +inf), default no limit
|
||||
diskQuotaPerPartition: -1 # MB, (0, +inf), default no limit
|
||||
@ -1325,7 +1316,7 @@ streaming:
|
||||
# it also determine the depth of depth first search method that is used to find the best balance result, 3 by default
|
||||
rebalanceMaxStep: 3
|
||||
walBroadcaster:
|
||||
concurrencyRatio: 1 # The concurrency ratio based on number of CPU for wal broadcaster, 1 by default.
|
||||
concurrencyRatio: 4 # The concurrency ratio based on number of CPU for wal broadcaster, 4 by default.
|
||||
txn:
|
||||
defaultKeepaliveTimeout: 10s # The default keepalive timeout for wal txn, 10s by default
|
||||
walWriteAheadBuffer:
|
||||
@ -1376,23 +1367,17 @@ streaming:
|
||||
# When the wal is on-closing, the recovery module will try to persist the recovery info for wal to make next recovery operation more fast.
|
||||
# If that persist operation exceeds this timeout, the wal recovery module will close right now.
|
||||
gracefulCloseTimeout: 3s
|
||||
walTruncate:
|
||||
# The interval of sampling wal checkpoint when truncate, 30m by default.
|
||||
# Every time the checkpoint is persisted, the checkpoint will be sampled and used to be a candidate of truncate checkpoint.
|
||||
# More samples, more frequent truncate, more memory usage.
|
||||
sampleInterval: 30m
|
||||
# The retention interval of wal truncate, 72h by default.
|
||||
# If the sampled checkpoint is older than this interval, it will be used to truncate wal checkpoint.
|
||||
# Greater the interval, more wal storage usage, more redundant data in wal.
|
||||
# Because current query path doesn't promise the read operation not happen before the truncate point,
|
||||
# retention interval should be greater than the dataCoord.segment.maxLife to avoid the message lost at query path.
|
||||
# If the wal is pulsar, the pulsar should close the subscription expiration to avoid the message lost.
|
||||
# because the wal truncate operation is implemented by pulsar consumer.
|
||||
retentionInterval: 72h
|
||||
|
||||
# Any configuration related to the knowhere vector search engine
|
||||
knowhere:
|
||||
enable: true # When enable this configuration, the index parameters defined following will be automatically populated as index parameters, without requiring user input.
|
||||
AISAQ:
|
||||
build:
|
||||
max_degree: 56 # Maximum degree of the Vamana graph
|
||||
pq_code_budget_gb_ratio: 0.125 # Size limit on the PQ code (compared with raw data)
|
||||
search_list_size: 100 # Size of the candidate list during building graph
|
||||
search:
|
||||
beam_width_ratio: 4 # Ratio between the maximum number of IO requests per search iteration and CPU number
|
||||
DISKANN:
|
||||
build:
|
||||
max_degree: 56 # Maximum degree of the Vamana graph
|
||||
|
||||
@ -30,7 +30,7 @@ $ ./minio server /minio
|
||||
To start Milvus standalone, you need a Milvus binary file. Currently you can get the latest version of Milvus binary file through the Milvus docker image. (We will upload Milvus binary files in the future)
|
||||
|
||||
```shell
|
||||
$ docker run -d --name milvus milvusdb/milvus:v2.6.1 /bin/bash
|
||||
$ docker run -d --name milvus milvusdb/milvus:v2.6.6 /bin/bash
|
||||
$ docker cp milvus:/milvus .
|
||||
```
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ dependencies_network= host
|
||||
nodes_network= host
|
||||
|
||||
; Setup varibale to controll what image version of Milvus to use.
|
||||
image= milvusdb/milvus:v2.6.1
|
||||
image= milvusdb/milvus:v2.6.6
|
||||
|
||||
; Setup static IP addresses of the docker hosts as variable for container environment variable config.
|
||||
; Before running the playbook, below 4 IP addresses need to be replaced with the IP of your host VM
|
||||
|
||||
@ -38,7 +38,7 @@ services:
|
||||
|
||||
standalone:
|
||||
container_name: milvus-standalone
|
||||
image: milvusdb/milvus:v2.6.1-gpu
|
||||
image: milvusdb/milvus:v2.6.6-gpu
|
||||
command: ["milvus", "run", "standalone"]
|
||||
security_opt:
|
||||
- seccomp:unconfined
|
||||
|
||||
@ -38,7 +38,7 @@ services:
|
||||
|
||||
standalone:
|
||||
container_name: milvus-standalone
|
||||
image: milvusdb/milvus:v2.6.1
|
||||
image: milvusdb/milvus:v2.6.6
|
||||
command: ["milvus", "run", "standalone"]
|
||||
security_opt:
|
||||
- seccomp:unconfined
|
||||
|
||||
77
go.mod
77
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/milvus-io/milvus
|
||||
|
||||
go 1.24.4
|
||||
go 1.24.9
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
|
||||
@ -19,16 +19,16 @@ require (
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.1.2
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||
github.com/klauspost/compress v1.17.9
|
||||
github.com/klauspost/compress v1.18.0
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7
|
||||
github.com/minio/minio-go/v7 v7.0.73
|
||||
github.com/panjf2000/ants/v2 v2.11.3 // indirect
|
||||
github.com/pingcap/log v1.1.1-0.20221015072633-39906604fb81
|
||||
github.com/pingcap/log v1.1.1-0.20221015072633-39906604fb81 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/prometheus/common v0.55.0
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.23
|
||||
github.com/samber/lo v1.27.0
|
||||
github.com/sbinet/npyio v0.6.0
|
||||
github.com/soheilhy/cmux v0.1.5
|
||||
@ -37,28 +37,28 @@ require (
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.865 // indirect
|
||||
github.com/tikv/client-go/v2 v2.0.4
|
||||
go.etcd.io/etcd/api/v3 v3.5.5
|
||||
go.etcd.io/etcd/client/v3 v3.5.5
|
||||
go.etcd.io/etcd/server/v3 v3.5.5
|
||||
go.etcd.io/etcd/api/v3 v3.5.23
|
||||
go.etcd.io/etcd/client/v3 v3.5.23
|
||||
go.etcd.io/etcd/server/v3 v3.5.23
|
||||
go.opentelemetry.io/otel v1.34.0
|
||||
go.opentelemetry.io/otel/trace v1.34.0
|
||||
go.uber.org/atomic v1.11.0
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.41.0
|
||||
golang.org/x/crypto v0.45.0
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
|
||||
golang.org/x/net v0.43.0
|
||||
golang.org/x/net v0.47.0
|
||||
golang.org/x/oauth2 v0.28.0
|
||||
golang.org/x/sync v0.16.0
|
||||
golang.org/x/text v0.28.0
|
||||
google.golang.org/grpc v1.71.0
|
||||
golang.org/x/sync v0.18.0
|
||||
golang.org/x/text v0.31.0
|
||||
google.golang.org/grpc v1.71.1
|
||||
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/storage v1.50.0
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1
|
||||
github.com/apache/pulsar-client-go v0.15.1
|
||||
github.com/apache/pulsar-client-go v0.17.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.3
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.9
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.62
|
||||
@ -74,10 +74,10 @@ require (
|
||||
github.com/jolestar/go-commons-pool/v2 v2.1.2
|
||||
github.com/magiconair/properties v1.8.7
|
||||
github.com/milvus-io/milvus/client/v2 v2.0.0-00010101000000-000000000000
|
||||
github.com/milvus-io/milvus/pkg/v2 v2.5.7
|
||||
github.com/milvus-io/milvus/pkg/v2 v2.6.7-0.20251201120310-af64f2acba38
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/remeh/sizedwaitgroup v1.0.0
|
||||
github.com/shirou/gopsutil/v4 v4.24.10
|
||||
github.com/shirou/gopsutil/v4 v4.25.10
|
||||
github.com/tidwall/gjson v1.17.1
|
||||
github.com/twpayne/go-geom v1.6.1
|
||||
github.com/valyala/fastjson v1.6.4
|
||||
@ -153,11 +153,12 @@ require (
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.1 // indirect
|
||||
github.com/dvsekhvalnov/jose2go v1.7.0 // indirect
|
||||
github.com/ebitengine/purego v0.9.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/expr-lang/expr v1.15.7 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
@ -172,12 +173,15 @@ require (
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/goccy/go-json v0.10.3 // indirect
|
||||
github.com/goccy/go-yaml v1.11.0 // indirect
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
|
||||
github.com/godbus/dbus/v5 v5.0.4 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/google/flatbuffers v24.3.25+incompatible // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
@ -189,12 +193,13 @@ require (
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
|
||||
github.com/hamba/avro/v2 v2.26.0 // indirect
|
||||
github.com/hamba/avro/v2 v2.29.0 // indirect
|
||||
github.com/hashicorp/go-syslog v1.0.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.174 // indirect
|
||||
github.com/ianlancetaylor/cgosymbolizer v0.0.0-20221217025313-27d3c9f66b6a // indirect
|
||||
github.com/jonboulle/clockwork v0.2.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect
|
||||
github.com/klauspost/asmfmt v1.3.2 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
@ -225,7 +230,7 @@ require (
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
@ -248,8 +253,9 @@ require (
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.15 // indirect
|
||||
github.com/tklauser/numcpus v0.10.0 // indirect
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/twmb/murmur3 v1.1.6 // indirect
|
||||
@ -260,12 +266,13 @@ require (
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zilliztech/woodpecker v0.1.6 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
|
||||
go.etcd.io/etcd/client/v2 v2.305.5 // indirect
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.5 // indirect
|
||||
go.etcd.io/etcd/raft/v3 v3.5.5 // indirect
|
||||
github.com/zilliztech/woodpecker v0.1.12 // indirect
|
||||
go.etcd.io/bbolt v1.3.12 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.23 // indirect
|
||||
go.etcd.io/etcd/client/v2 v2.305.23 // indirect
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.23 // indirect
|
||||
go.etcd.io/etcd/raft/v3 v3.5.23 // indirect
|
||||
go.mongodb.org/mongo-driver v1.13.1 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
|
||||
@ -280,11 +287,12 @@ require (
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||
go.uber.org/automaxprocs v1.5.3 // indirect
|
||||
golang.org/x/arch v0.11.0 // indirect
|
||||
golang.org/x/mod v0.26.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
golang.org/x/mod v0.29.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect
|
||||
golang.org/x/term v0.37.0 // indirect
|
||||
golang.org/x/time v0.10.0 // indirect
|
||||
golang.org/x/tools v0.35.0 // indirect
|
||||
golang.org/x/tools v0.38.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
gonum.org/v1/gonum v0.15.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
@ -310,7 +318,6 @@ replace (
|
||||
github.com/bketelsen/crypt => github.com/bketelsen/crypt v0.0.4 // Fix security alert for core-os/etcd
|
||||
github.com/expr-lang/expr => github.com/SimFG/expr v0.0.0-20250513112851-9b981e8400b9
|
||||
github.com/go-kit/kit => github.com/go-kit/kit v0.1.0
|
||||
github.com/golang-jwt/jwt => github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/greatroar/blobloom => github.com/milvus-io/blobloom v0.0.0-20240603110411-471ae49f3b93
|
||||
github.com/ianlancetaylor/cgosymbolizer => github.com/milvus-io/cgosymbolizer v0.0.0-20250318084424-114f4050c3a6
|
||||
github.com/milvus-io/milvus/pkg/v2 => ./pkg
|
||||
|
||||
183
go.sum
183
go.sum
@ -144,8 +144,8 @@ github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQY
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||
github.com/apache/pulsar-client-go v0.15.1 h1:/BtkKA0WnGLDRJe1GJGhhRcpfxZ85IBHHOktmbz6fME=
|
||||
github.com/apache/pulsar-client-go v0.15.1/go.mod h1:ow9PhLoGUY6ncrKOtjnWeJycFnTKOwrIV39j3kNV54M=
|
||||
github.com/apache/pulsar-client-go v0.17.0 h1:FLyfsW6FfGHZPjDapu6Y+Thp/9JQNGJS3dms+18bdpA=
|
||||
github.com/apache/pulsar-client-go v0.17.0/go.mod h1:sGZ3k5Knrf38skZh6YMoK8bibNH4aIq6wx7McQu8IAE=
|
||||
github.com/apache/thrift v0.20.0 h1:631+KvYbsBZxmuJjYwhezVsrfc/TbqtZV4QcxOX1fOI=
|
||||
github.com/apache/thrift v0.20.0/go.mod h1:hOk1BQqcp2OLzGsyVXdfMk7YFlMxK3aoEVhjD06QhB8=
|
||||
github.com/ardielle/ardielle-go v1.5.2 h1:TilHTpHIQJ27R1Tl/iITBzMwiUGSlVfiVhwDNGM3Zj4=
|
||||
@ -217,12 +217,10 @@ github.com/casbin/casbin/v2 v2.44.2 h1:mlWtgbX872r707frOq+REaHzfvsl+qQw0Eq+ekzJ7
|
||||
github.com/casbin/casbin/v2 v2.44.2/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
|
||||
github.com/casbin/json-adapter/v2 v2.0.0 h1:nOCN3TK1CJKSNQQ/MnakbU9/cUcNR3N0AxBDnEBLSDI=
|
||||
github.com/casbin/json-adapter/v2 v2.0.0/go.mod h1:LvsfPXXr8CD0ZFucAxawcY9Xb0FtLk3mozJ1qcSTUD4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
@ -240,7 +238,6 @@ 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/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
@ -263,8 +260,6 @@ github.com/confluentinc/confluent-kafka-go v1.9.1 h1:L3aW6KvTyrq/+BOMnDm9xJylhAE
|
||||
github.com/confluentinc/confluent-kafka-go v1.9.1/go.mod h1:ptXNqsuDfYbAE/LBW6pnwWZElUoWxHoV8E43DCrliyo=
|
||||
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
|
||||
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
|
||||
github.com/containerd/containerd v1.7.27 h1:yFyEyojddO3MIGVER2xJLWoCIn+Up4GaHFquP7hsFII=
|
||||
github.com/containerd/containerd v1.7.27/go.mod h1:xZmPnl75Vc+BLGt4MIfu6bp+fy03gdHAn9bz+FreFR0=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
@ -303,8 +298,8 @@ github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4w
|
||||
github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
|
||||
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v28.0.0+incompatible h1:Olh0KS820sJ7nPsBKChVhk5pzqcwDR15fumfAd/p9hM=
|
||||
github.com/docker/docker v28.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
@ -317,10 +312,10 @@ github.com/dubbogo/jsonparser v1.0.1/go.mod h1:tYAtpctvSP/tWw4MeelsowSPgXQRVHHWb
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY=
|
||||
github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=
|
||||
github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE=
|
||||
github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo=
|
||||
github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=
|
||||
github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k=
|
||||
github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
@ -328,7 +323,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
|
||||
@ -350,6 +344,7 @@ github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+ne
|
||||
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
||||
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
@ -432,11 +427,16 @@ github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn
|
||||
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
||||
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.9.8/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXKkTfoE=
|
||||
github.com/goccy/go-yaml v1.11.0 h1:n7Z+zx8S9f9KgzG6KtQKf+kwqXZlLNR2F6018Dgau54=
|
||||
github.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
@ -454,6 +454,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
|
||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
@ -465,7 +467,6 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
@ -497,12 +498,12 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=
|
||||
@ -588,8 +589,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9K
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
|
||||
github.com/hamba/avro v1.5.6/go.mod h1:3vNT0RLXXpFm2Tb/5KC71ZRJlOroggq1Rcitb6k4Fr8=
|
||||
github.com/hamba/avro/v2 v2.26.0 h1:IaT5l6W3zh7K67sMrT2+RreJyDTllBGVJm4+Hedk9qE=
|
||||
github.com/hamba/avro/v2 v2.26.0/go.mod h1:I8glyswHnpED3Nlx2ZdUe+4LJnCOOyiCzLMno9i/Uu0=
|
||||
github.com/hamba/avro/v2 v2.29.0 h1:fkqoWEPxfygZxrkktgSHEpd0j/P7RKTBTDbcEeMdVEY=
|
||||
github.com/hamba/avro/v2 v2.29.0/go.mod h1:Pk3T+x74uJoJOFmHrdJ8PRdgSEL/kEKteJ31NytCKxI=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@ -619,6 +620,8 @@ github.com/heetch/avro v0.3.1/go.mod h1:4xn38Oz/+hiEUTpbVfGVLfvOg0yKLlRP7Q9+gJJI
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.174 h1:FBlx7E5rl8doUTbizt+DXR0zU05Mu2oEYvc/2GMB7pc=
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.174/go.mod h1:M+yna96Fx9o5GbIUnF3OvVvQGjgfVSyeJbV9Yb1z/wI=
|
||||
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
|
||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
@ -653,8 +656,9 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/Kgo2/7xNSUuC5G28VR8ljfrLKU2G4IjU=
|
||||
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
@ -706,8 +710,9 @@ github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
|
||||
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
@ -794,8 +799,8 @@ github.com/milvus-io/cgosymbolizer v0.0.0-20250318084424-114f4050c3a6 h1:YHMFI6L
|
||||
github.com/milvus-io/cgosymbolizer v0.0.0-20250318084424-114f4050c3a6/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg=
|
||||
github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b h1:TfeY0NxYxZzUfIfYe5qYDBzt4ZYRqzUjTR6CvUzjat8=
|
||||
github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b/go.mod h1:iwW+9cWfIzzDseEBCCeDSN5SD16Tidvy8cwQ7ZY8Qj4=
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3 h1:w7IBrU25KULWNlHKoKwx6ruTsDAmzrWknotIc6A4ys4=
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7 h1:RJtZbkS5zKNIXxsqjGBUZc2SbnI4MGq+TfOfc8tJsuM=
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
|
||||
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs=
|
||||
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
|
||||
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI=
|
||||
@ -834,6 +839,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||
@ -914,8 +920,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
@ -925,7 +932,6 @@ github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
@ -953,8 +959,8 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.23 h1:lxjt5B6ZCiBeeNO8/oQsegE6fLeCzuMRoVWSkXC4uvY=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.23/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remeh/sizedwaitgroup v1.0.0 h1:VNGGFwNo/R5+MJBf6yrsr110p0m4/OX4S3DCy7Kyl5E=
|
||||
@ -993,12 +999,13 @@ github.com/shirou/gopsutil v3.20.11+incompatible h1:LJr4ZQK4mPpIV5gOa4jCOKOGb4ty
|
||||
github.com/shirou/gopsutil v3.20.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
|
||||
github.com/shirou/gopsutil/v4 v4.24.10 h1:7VOzPtfw/5YDU+jLEoBwXwxJbQetULywoSV4RYY7HkM=
|
||||
github.com/shirou/gopsutil/v4 v4.24.10/go.mod h1:s4D/wg+ag4rG0WO7AiTj2BeYCRhym0vM7DHbZRxnIT8=
|
||||
github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
|
||||
github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/httpfs v0.0.0-20181222201310-74dc9339e414/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
@ -1034,7 +1041,6 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
@ -1092,10 +1098,14 @@ github.com/tikv/client-go/v2 v2.0.4 h1:cPtMXTExqjzk8L40qhrgB/mXiBXKP5LRU0vwjtI2X
|
||||
github.com/tikv/client-go/v2 v2.0.4/go.mod h1:v52O5zDtv2BBus4lm5yrSQhxGW4Z4RaXWfg0U1Kuyqo=
|
||||
github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 h1:ckPpxKcl75mO2N6a4cJXiZH43hvcHPpqc9dh1TmH1nc=
|
||||
github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07/go.mod h1:CipBxPfxPUME+BImx9MUYXCnAVLS3VJUr3mnSJwh40A=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
|
||||
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
|
||||
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
|
||||
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
||||
@ -1128,6 +1138,9 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
@ -1137,6 +1150,7 @@ github.com/xiaofan-luan/pulsarctl v0.5.1 h1:2V+IWFarElzcln5WBbU3VNu3zC8Q7RS6rMpV
|
||||
github.com/xiaofan-luan/pulsarctl v0.5.1/go.mod h1:kfeG1rRglz+QDSxyBB21H2Q4hMnzfirW32bs8yx/Q0Q=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
|
||||
@ -1145,6 +1159,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
@ -1152,35 +1167,37 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
|
||||
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
|
||||
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
|
||||
github.com/zilliztech/woodpecker v0.1.6 h1:3Ml1UJtiJXVPy01E5/qbVZHIPadL4RjJgg+e0Nj2LDw=
|
||||
github.com/zilliztech/woodpecker v0.1.6/go.mod h1:xA7jPkUnnr5S4+LmQghrc/1hNU2kiU8KWZ93Uup2jks=
|
||||
github.com/zilliztech/woodpecker v0.1.12 h1:GWq95o9FvwP/EvjedbDJlBwQPo/ZC9NxOmoSpeboznk=
|
||||
github.com/zilliztech/woodpecker v0.1.12/go.mod h1:xA7jPkUnnr5S4+LmQghrc/1hNU2kiU8KWZ93Uup2jks=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.etcd.io/bbolt v1.3.12 h1:UAxZAIuJqzFwByP19gZC3zd5robK3FOangrGS+Fdczg=
|
||||
go.etcd.io/bbolt v1.3.12/go.mod h1:Gi2toLZr1jFkuReJm+yEPn7H8wk6ooptePtHYCbCS1g=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/api/v3 v3.5.5 h1:BX4JIbQ7hl7+jL+g+2j5UAr0o1bctCm6/Ct+ArBGkf0=
|
||||
go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8=
|
||||
go.etcd.io/etcd/api/v3 v3.5.23 h1:tQi/RaO6peOhmf0c11miU3RQIYPZmiL3UzG9V+f8g6k=
|
||||
go.etcd.io/etcd/api/v3 v3.5.23/go.mod h1:QP4ZLWROP49Kk/vPLhudxYQcF4ndhMQ1gvJE4rCTAgc=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.5 h1:9S0JUVvmrVl7wCF39iTQthdaaNIiAaQbmK75ogO6GU8=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.23 h1:RzwVV28JgOwGl5TUjA47s9IWxl5qQjM2VqSh8wjFFLM=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.23/go.mod h1:IdIjxGUGNy+8HWeVlbBXDqmPqe+n8GsVGVYnccAEZ5o=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v2 v2.305.5 h1:DktRP60//JJpnPC0VBymAN/7V71GHMdjDCBt4ZPXDjI=
|
||||
go.etcd.io/etcd/client/v2 v2.305.5/go.mod h1:zQjKllfqfBVyVStbt4FaosoX2iYd8fV/GRy/PbowgP4=
|
||||
go.etcd.io/etcd/client/v2 v2.305.23 h1:lo6nsSHjp3tGsRLrzmM+neVSahXxbhxnfoatEdB6nao=
|
||||
go.etcd.io/etcd/client/v2 v2.305.23/go.mod h1:Up9T9+5M3MMcCj/V0nDfadBERNMxIYf1tdycva1dXM4=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8=
|
||||
go.etcd.io/etcd/client/v3 v3.5.5 h1:q++2WTJbUgpQu4B6hCuT7VkdwaTP7Qz6Daak3WzbrlI=
|
||||
go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c=
|
||||
go.etcd.io/etcd/client/v3 v3.5.23 h1:WN7sypGG326sFP5jLkFqD3anf/k6NNlV5Hy/UxvTPvc=
|
||||
go.etcd.io/etcd/client/v3 v3.5.23/go.mod h1:XTf1oMQi4ZzpXGFoPgvAqbY9JFmTFQqWI1SF4g+hV6o=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.5 h1:Ablg7T7OkR+AeeeU32kdVhw/AGDsitkKPl7aW73ssjU=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.5/go.mod h1:6ksYFxttiUGzC2uxyqiyOEvhAiD0tuIqSZkX3TyPdaE=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.23 h1:q2skPu7VFC7oerL3MrFqImVACjAFWPlZMjHU0zll9x4=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.23/go.mod h1:zUWlm5U4HgvDg+0PUWb8TgMF7ZrUiQA8aQq7FxE0WHo=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0/go.mod h1:FAwse6Zlm5v4tEWZaTjmNhe17Int4Oxbu7+2r0DiD3w=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.5 h1:Ibz6XyZ60OYyRopu73lLM/P+qco3YtlZMOhnXNS051I=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.5/go.mod h1:76TA48q03g1y1VpTue92jZLr9lIHKUNcYdZOOGyx8rI=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.23 h1:NhCdh4xz1VsrqHd2c+h6SLvhE95B1Hs7K+ESaAs6LLQ=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.23/go.mod h1:NJz9BGkhGvru47lIc1wL0QHsg5yvHTy6tUpEqM69ERM=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0-alpha.0/go.mod h1:tsKetYpt980ZTpzl/gb+UOJj9RkIyCb1u4wjzMg90BQ=
|
||||
go.etcd.io/etcd/server/v3 v3.5.5 h1:jNjYm/9s+f9A9r6+SC4RvNaz6AqixpOvhrFdT0PvIj0=
|
||||
go.etcd.io/etcd/server/v3 v3.5.5/go.mod h1:rZ95vDw/jrvsbj9XpTqPrTAB9/kzchVdhRirySPkUBc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.23 h1:2g1hz32pp1TYMI7xUyifR8gXOlUnTBCfixV+uJ8BqRU=
|
||||
go.etcd.io/etcd/server/v3 v3.5.23/go.mod h1:sZwt/lLSwYQ/S5aAbzSQX2xNw1WA0Fo5noUCVxVYB4g=
|
||||
go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk=
|
||||
go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
@ -1192,20 +1209,16 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
||||
go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.13.0 h1:VAMoGujbVV8Q0JNM/cEbhzUIWWBxnEqH45HP9iBKN04=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.13.0/go.mod h1:fHwbmle6mBFJA1p2ZIhilvffCdq/dM5UTIiCOmEjS+w=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.20.0 h1:CsBiKCiQPdSjS+MlRiqeTI9JDDpSuk0Hb6QTRfwer8k=
|
||||
@ -1216,16 +1229,13 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0 h1:4s9HxB4azeeQkhY
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0/go.mod h1:djVA3TUJ2fSdMX0JE5XxFBOaZzprElJoP7fD4vnV2SU=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||
go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
@ -1272,13 +1282,14 @@ golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
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=
|
||||
@ -1328,8 +1339,9 @@ 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.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
||||
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/net v0.0.0-20180406214816-61147c48b25b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
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=
|
||||
@ -1369,6 +1381,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
@ -1381,8 +1394,9 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
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=
|
||||
@ -1408,8 +1422,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180807162357-acbc56fc7007/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -1457,7 +1472,6 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -1487,7 +1501,10 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -1495,11 +1512,14 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU=
|
||||
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||
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=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1509,14 +1529,15 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
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=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
|
||||
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -1586,8 +1607,9 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
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=
|
||||
@ -1710,14 +1732,11 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
|
||||
google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f h1:rqzndB2lIQGivcXdTuY3Y9NBvr70X+y77woofSRluec=
|
||||
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f/go.mod h1:gxndsbNG1n4TZcHGgsYEfVGnTxqfEdfiDv6/DADXX9o=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
|
||||
@ -14,6 +14,9 @@ packages:
|
||||
Broadcast:
|
||||
Local:
|
||||
Scanner:
|
||||
github.com/milvus-io/milvus/internal/rootcoord/tombstone:
|
||||
interfaces:
|
||||
TombstoneSweeper:
|
||||
github.com/milvus-io/milvus/internal/streamingcoord/server/balancer:
|
||||
interfaces:
|
||||
Balancer:
|
||||
|
||||
@ -49,12 +49,12 @@ func startEmbedEtcdServer() (*embed.Etcd, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.LCUrls = []url.URL{*u}
|
||||
config.ListenClientUrls = []url.URL{*u}
|
||||
u, err = url.Parse("http://localhost:0")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.LPUrls = []url.URL{*u}
|
||||
config.ListenPeerUrls = []url.URL{*u}
|
||||
|
||||
return embed.StartEtcd(config)
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.32.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.3. DO NOT EDIT.
|
||||
|
||||
package allocator
|
||||
|
||||
@ -21,6 +21,10 @@ func (_m *MockGlobalIDAllocator) EXPECT() *MockGlobalIDAllocator_Expecter {
|
||||
func (_m *MockGlobalIDAllocator) Alloc(count uint32) (int64, int64, error) {
|
||||
ret := _m.Called(count)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Alloc")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 int64
|
||||
var r2 error
|
||||
@ -76,10 +80,14 @@ func (_c *MockGlobalIDAllocator_Alloc_Call) RunAndReturn(run func(uint32) (int64
|
||||
return _c
|
||||
}
|
||||
|
||||
// AllocOne provides a mock function with given fields:
|
||||
// AllocOne provides a mock function with no fields
|
||||
func (_m *MockGlobalIDAllocator) AllocOne() (int64, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AllocOne")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func() (int64, error)); ok {
|
||||
@ -127,10 +135,14 @@ func (_c *MockGlobalIDAllocator_AllocOne_Call) RunAndReturn(run func() (int64, e
|
||||
return _c
|
||||
}
|
||||
|
||||
// Initialize provides a mock function with given fields:
|
||||
// Initialize provides a mock function with no fields
|
||||
func (_m *MockGlobalIDAllocator) Initialize() error {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Initialize")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
|
||||
@ -19,6 +19,3 @@ packages:
|
||||
github.com/milvus-io/milvus/internal/cdc/replication/replicatemanager:
|
||||
interfaces:
|
||||
ChannelReplicator:
|
||||
github.com/milvus-io/milvus/internal/cdc/controller:
|
||||
interfaces:
|
||||
Controller:
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
// Licensed to the LF AI & Data foundation under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus/client/v2/milvusclient"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
)
|
||||
|
||||
type ClusterClient interface {
|
||||
CreateMilvusClient(ctx context.Context, cluster *commonpb.MilvusCluster) (MilvusClient, error)
|
||||
}
|
||||
|
||||
var _ ClusterClient = (*clusterClient)(nil)
|
||||
|
||||
type clusterClient struct{}
|
||||
|
||||
func NewClusterClient() ClusterClient {
|
||||
return &clusterClient{}
|
||||
}
|
||||
|
||||
func (c *clusterClient) CreateMilvusClient(ctx context.Context, cluster *commonpb.MilvusCluster) (MilvusClient, error) {
|
||||
cli, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
|
||||
Address: cluster.GetConnectionParam().GetUri(),
|
||||
APIKey: cluster.GetConnectionParam().GetToken(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Warn("failed to create milvus client", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return cli, nil
|
||||
}
|
||||
@ -19,16 +19,32 @@ package cluster
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus/client/v2/milvusclient"
|
||||
)
|
||||
|
||||
type MilvusClient interface {
|
||||
// GetReplicateInfo gets the replicate information from the milvus cluster.
|
||||
GetReplicateInfo(ctx context.Context, sourceClusterID string, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)
|
||||
GetReplicateInfo(ctx context.Context, req *milvuspb.GetReplicateInfoRequest, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)
|
||||
// CreateReplicateStream creates a replicate stream to the milvus cluster.
|
||||
CreateReplicateStream(ctx context.Context, opts ...grpc.CallOption) (milvuspb.MilvusService_CreateReplicateStreamClient, error)
|
||||
// Close closes the milvus client.
|
||||
Close(ctx context.Context) error
|
||||
}
|
||||
|
||||
type CreateMilvusClientFunc func(ctx context.Context, cluster *commonpb.MilvusCluster) (MilvusClient, error)
|
||||
|
||||
func NewMilvusClient(ctx context.Context, cluster *commonpb.MilvusCluster) (MilvusClient, error) {
|
||||
cli, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
|
||||
Address: cluster.GetConnectionParam().GetUri(),
|
||||
APIKey: cluster.GetConnectionParam().GetToken(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create milvus client")
|
||||
}
|
||||
return cli, nil
|
||||
}
|
||||
|
||||
@ -1,97 +0,0 @@
|
||||
// Code generated by mockery v2.53.3. DO NOT EDIT.
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
commonpb "github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockClusterClient is an autogenerated mock type for the ClusterClient type
|
||||
type MockClusterClient struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockClusterClient_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockClusterClient) EXPECT() *MockClusterClient_Expecter {
|
||||
return &MockClusterClient_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// CreateMilvusClient provides a mock function with given fields: ctx, _a1
|
||||
func (_m *MockClusterClient) CreateMilvusClient(ctx context.Context, _a1 *commonpb.MilvusCluster) (MilvusClient, error) {
|
||||
ret := _m.Called(ctx, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CreateMilvusClient")
|
||||
}
|
||||
|
||||
var r0 MilvusClient
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *commonpb.MilvusCluster) (MilvusClient, error)); ok {
|
||||
return rf(ctx, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *commonpb.MilvusCluster) MilvusClient); ok {
|
||||
r0 = rf(ctx, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(MilvusClient)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *commonpb.MilvusCluster) error); ok {
|
||||
r1 = rf(ctx, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockClusterClient_CreateMilvusClient_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateMilvusClient'
|
||||
type MockClusterClient_CreateMilvusClient_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// CreateMilvusClient is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - _a1 *commonpb.MilvusCluster
|
||||
func (_e *MockClusterClient_Expecter) CreateMilvusClient(ctx interface{}, _a1 interface{}) *MockClusterClient_CreateMilvusClient_Call {
|
||||
return &MockClusterClient_CreateMilvusClient_Call{Call: _e.mock.On("CreateMilvusClient", ctx, _a1)}
|
||||
}
|
||||
|
||||
func (_c *MockClusterClient_CreateMilvusClient_Call) Run(run func(ctx context.Context, _a1 *commonpb.MilvusCluster)) *MockClusterClient_CreateMilvusClient_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*commonpb.MilvusCluster))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockClusterClient_CreateMilvusClient_Call) Return(_a0 MilvusClient, _a1 error) *MockClusterClient_CreateMilvusClient_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockClusterClient_CreateMilvusClient_Call) RunAndReturn(run func(context.Context, *commonpb.MilvusCluster) (MilvusClient, error)) *MockClusterClient_CreateMilvusClient_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewMockClusterClient creates a new instance of MockClusterClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockClusterClient(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockClusterClient {
|
||||
mock := &MockClusterClient{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
@ -144,14 +144,14 @@ func (_c *MockMilvusClient_CreateReplicateStream_Call) RunAndReturn(run func(con
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetReplicateInfo provides a mock function with given fields: ctx, sourceClusterID, opts
|
||||
func (_m *MockMilvusClient) GetReplicateInfo(ctx context.Context, sourceClusterID string, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error) {
|
||||
// GetReplicateInfo provides a mock function with given fields: ctx, req, opts
|
||||
func (_m *MockMilvusClient) GetReplicateInfo(ctx context.Context, req *milvuspb.GetReplicateInfoRequest, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, sourceClusterID)
|
||||
_ca = append(_ca, ctx, req)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
@ -161,19 +161,19 @@ func (_m *MockMilvusClient) GetReplicateInfo(ctx context.Context, sourceClusterI
|
||||
|
||||
var r0 *milvuspb.GetReplicateInfoResponse
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)); ok {
|
||||
return rf(ctx, sourceClusterID, opts...)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.GetReplicateInfoRequest, ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)); ok {
|
||||
return rf(ctx, req, opts...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, ...grpc.CallOption) *milvuspb.GetReplicateInfoResponse); ok {
|
||||
r0 = rf(ctx, sourceClusterID, opts...)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.GetReplicateInfoRequest, ...grpc.CallOption) *milvuspb.GetReplicateInfoResponse); ok {
|
||||
r0 = rf(ctx, req, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*milvuspb.GetReplicateInfoResponse)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, sourceClusterID, opts...)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.GetReplicateInfoRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, req, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@ -188,14 +188,14 @@ type MockMilvusClient_GetReplicateInfo_Call struct {
|
||||
|
||||
// GetReplicateInfo is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - sourceClusterID string
|
||||
// - req *milvuspb.GetReplicateInfoRequest
|
||||
// - opts ...grpc.CallOption
|
||||
func (_e *MockMilvusClient_Expecter) GetReplicateInfo(ctx interface{}, sourceClusterID interface{}, opts ...interface{}) *MockMilvusClient_GetReplicateInfo_Call {
|
||||
func (_e *MockMilvusClient_Expecter) GetReplicateInfo(ctx interface{}, req interface{}, opts ...interface{}) *MockMilvusClient_GetReplicateInfo_Call {
|
||||
return &MockMilvusClient_GetReplicateInfo_Call{Call: _e.mock.On("GetReplicateInfo",
|
||||
append([]interface{}{ctx, sourceClusterID}, opts...)...)}
|
||||
append([]interface{}{ctx, req}, opts...)...)}
|
||||
}
|
||||
|
||||
func (_c *MockMilvusClient_GetReplicateInfo_Call) Run(run func(ctx context.Context, sourceClusterID string, opts ...grpc.CallOption)) *MockMilvusClient_GetReplicateInfo_Call {
|
||||
func (_c *MockMilvusClient_GetReplicateInfo_Call) Run(run func(ctx context.Context, req *milvuspb.GetReplicateInfoRequest, opts ...grpc.CallOption)) *MockMilvusClient_GetReplicateInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
variadicArgs := make([]grpc.CallOption, len(args)-2)
|
||||
for i, a := range args[2:] {
|
||||
@ -203,7 +203,7 @@ func (_c *MockMilvusClient_GetReplicateInfo_Call) Run(run func(ctx context.Conte
|
||||
variadicArgs[i] = a.(grpc.CallOption)
|
||||
}
|
||||
}
|
||||
run(args[0].(context.Context), args[1].(string), variadicArgs...)
|
||||
run(args[0].(context.Context), args[1].(*milvuspb.GetReplicateInfoRequest), variadicArgs...)
|
||||
})
|
||||
return _c
|
||||
}
|
||||
@ -213,7 +213,7 @@ func (_c *MockMilvusClient_GetReplicateInfo_Call) Return(_a0 *milvuspb.GetReplic
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockMilvusClient_GetReplicateInfo_Call) RunAndReturn(run func(context.Context, string, ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)) *MockMilvusClient_GetReplicateInfo_Call {
|
||||
func (_c *MockMilvusClient_GetReplicateInfo_Call) RunAndReturn(run func(context.Context, *milvuspb.GetReplicateInfoRequest, ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)) *MockMilvusClient_GetReplicateInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
@ -16,9 +16,159 @@
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"go.etcd.io/etcd/api/v3/mvccpb"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
|
||||
)
|
||||
|
||||
// Controller controls and schedules the CDC process.
|
||||
// It will periodically update the replications by the replicate configuration.
|
||||
type Controller interface {
|
||||
Start()
|
||||
Start() error
|
||||
Stop()
|
||||
}
|
||||
|
||||
type controller struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
|
||||
prefix string
|
||||
}
|
||||
|
||||
func NewController() *controller {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
return &controller{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
prefix: path.Join(
|
||||
paramtable.Get().EtcdCfg.MetaRootPath.GetValue(),
|
||||
streamingcoord.ReplicatePChannelMetaPrefix,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) Start() error {
|
||||
c.startWatchLoop()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *controller) recoverReplicatePChannelMeta(channels []*meta.ReplicateChannel) {
|
||||
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
|
||||
for _, channelMeta := range channels {
|
||||
if !strings.Contains(channelMeta.Value.GetSourceChannelName(), currentClusterID) {
|
||||
// current cluster is not source cluster, skip create replicator
|
||||
continue
|
||||
}
|
||||
log.Info("recover replicate pchannel meta",
|
||||
zap.String("key", channelMeta.Key),
|
||||
zap.Int64("revision", channelMeta.ModRevision),
|
||||
)
|
||||
channel := &meta.ReplicateChannel{
|
||||
Key: channelMeta.Key,
|
||||
Value: channelMeta.Value,
|
||||
ModRevision: channelMeta.ModRevision,
|
||||
}
|
||||
resource.Resource().ReplicateManagerClient().CreateReplicator(channel)
|
||||
}
|
||||
resource.Resource().ReplicateManagerClient().RemoveOutdatedReplicators(channels)
|
||||
}
|
||||
|
||||
func (c *controller) watchEvents(revision int64) clientv3.WatchChan {
|
||||
eventCh := resource.Resource().ETCD().Watch(
|
||||
c.ctx,
|
||||
c.prefix,
|
||||
clientv3.WithPrefix(),
|
||||
clientv3.WithPrevKV(),
|
||||
clientv3.WithRev(revision),
|
||||
)
|
||||
log.Ctx(c.ctx).Info("succeed to watch replicate pchannel meta events",
|
||||
zap.Int64("revision", revision), zap.String("prefix", c.prefix))
|
||||
return eventCh
|
||||
}
|
||||
|
||||
func (c *controller) startWatchLoop() {
|
||||
c.wg.Add(1)
|
||||
go func() {
|
||||
defer c.wg.Done()
|
||||
for {
|
||||
m, err := meta.ListReplicatePChannels(c.ctx, resource.Resource().ETCD(), c.prefix)
|
||||
if err != nil && c.ctx.Err() == nil {
|
||||
log.Ctx(c.ctx).Warn("failed to list replicate pchannels", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
c.recoverReplicatePChannelMeta(m.Channels)
|
||||
eventCh := c.watchEvents(m.Revision + 1)
|
||||
err = c.watchLoop(eventCh)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (c *controller) watchLoop(eventCh clientv3.WatchChan) error {
|
||||
for {
|
||||
select {
|
||||
case <-c.ctx.Done():
|
||||
return nil
|
||||
case event, ok := <-eventCh:
|
||||
if !ok {
|
||||
panic("etcd event channel closed")
|
||||
}
|
||||
if err := event.Err(); err != nil {
|
||||
log.Warn("etcd event error", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
for _, e := range event.Events {
|
||||
switch e.Type {
|
||||
case mvccpb.PUT:
|
||||
log.Info("handle replicate pchannel PUT event",
|
||||
zap.String("key", string(e.Kv.Key)),
|
||||
zap.Int64("modRevision", e.Kv.ModRevision),
|
||||
)
|
||||
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
|
||||
replicate := meta.MustParseReplicateChannelFromEvent(e)
|
||||
if !strings.Contains(replicate.GetSourceChannelName(), currentClusterID) {
|
||||
// current cluster is not source cluster, skip create replicator
|
||||
continue
|
||||
}
|
||||
channel := &meta.ReplicateChannel{
|
||||
Key: string(e.Kv.Key),
|
||||
Value: replicate,
|
||||
ModRevision: e.Kv.ModRevision,
|
||||
}
|
||||
resource.Resource().ReplicateManagerClient().CreateReplicator(channel)
|
||||
case mvccpb.DELETE:
|
||||
log.Info("handle replicate pchannel DELETE event",
|
||||
zap.String("key", string(e.Kv.Key)),
|
||||
zap.Int64("prevModRevision", e.PrevKv.ModRevision),
|
||||
)
|
||||
key := string(e.Kv.Key)
|
||||
revision := e.PrevKv.ModRevision
|
||||
resource.Resource().ReplicateManagerClient().RemoveReplicator(key, revision)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) Stop() {
|
||||
log.Ctx(c.ctx).Info("stop CDC controller...")
|
||||
c.cancel()
|
||||
c.wg.Wait()
|
||||
resource.Resource().ReplicateManagerClient().Close()
|
||||
log.Ctx(c.ctx).Info("CDC controller stopped")
|
||||
}
|
||||
|
||||
104
internal/cdc/controller/controller_test.go
Normal file
104
internal/cdc/controller/controller_test.go
Normal file
@ -0,0 +1,104 @@
|
||||
// Licensed to the LF AI & Data foundation under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
"go.etcd.io/etcd/api/v3/mvccpb"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
"github.com/milvus-io/milvus/internal/cdc/replication"
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
)
|
||||
|
||||
func TestController_StartAndStop_WithEvents(t *testing.T) {
|
||||
mockReplicateManagerClient := replication.NewMockReplicateManagerClient(t)
|
||||
mockReplicateManagerClient.EXPECT().Close().Return()
|
||||
|
||||
// Create test data
|
||||
replicateMeta := &streamingpb.ReplicatePChannelMeta{
|
||||
SourceChannelName: "by-dev-test-source-channel",
|
||||
TargetChannelName: "by-dev-test-target-channel",
|
||||
}
|
||||
metaBytes, _ := proto.Marshal(replicateMeta)
|
||||
|
||||
// Create mock events
|
||||
putEvent := &clientv3.Event{
|
||||
Type: mvccpb.PUT,
|
||||
Kv: &mvccpb.KeyValue{
|
||||
Key: []byte(streamingcoord.BuildReplicatePChannelMetaKey(replicateMeta)),
|
||||
Value: metaBytes,
|
||||
},
|
||||
}
|
||||
|
||||
deleteEvent := &clientv3.Event{
|
||||
Type: mvccpb.DELETE,
|
||||
Kv: &mvccpb.KeyValue{
|
||||
Key: []byte(streamingcoord.BuildReplicatePChannelMetaKey(replicateMeta)),
|
||||
},
|
||||
PrevKv: &mvccpb.KeyValue{
|
||||
Value: metaBytes,
|
||||
},
|
||||
}
|
||||
|
||||
eventCh := make(chan clientv3.WatchResponse, 2)
|
||||
// Send events
|
||||
go func() {
|
||||
eventCh <- clientv3.WatchResponse{
|
||||
Events: []*clientv3.Event{putEvent},
|
||||
}
|
||||
eventCh <- clientv3.WatchResponse{
|
||||
Events: []*clientv3.Event{deleteEvent},
|
||||
}
|
||||
}()
|
||||
|
||||
notifyCh := make(chan struct{}, 2)
|
||||
mockReplicateManagerClient.EXPECT().CreateReplicator(mock.Anything).RunAndReturn(func(replicate *meta.ReplicateChannel) {
|
||||
notifyCh <- struct{}{}
|
||||
})
|
||||
mockReplicateManagerClient.EXPECT().RemoveReplicator(mock.Anything, mock.Anything).RunAndReturn(func(key string, modRevision int64) {
|
||||
notifyCh <- struct{}{}
|
||||
})
|
||||
|
||||
resource.InitForTest(t,
|
||||
resource.OptReplicateManagerClient(mockReplicateManagerClient),
|
||||
)
|
||||
|
||||
ctrl := NewController()
|
||||
go ctrl.watchLoop(eventCh)
|
||||
|
||||
// Wait for put event to be processed
|
||||
select {
|
||||
case <-notifyCh:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("timeout waiting for put event")
|
||||
}
|
||||
// Wait for delete event to be processed
|
||||
select {
|
||||
case <-notifyCh:
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Fatal("timeout waiting for delete event")
|
||||
}
|
||||
ctrl.Stop()
|
||||
}
|
||||
@ -1,87 +0,0 @@
|
||||
// Licensed to the LF AI & Data foundation under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controllerimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
)
|
||||
|
||||
const checkInterval = 10 * time.Second
|
||||
|
||||
type controller struct {
|
||||
ctx context.Context
|
||||
wg sync.WaitGroup
|
||||
stopOnce sync.Once
|
||||
stopChan chan struct{}
|
||||
}
|
||||
|
||||
func NewController() *controller {
|
||||
return &controller{
|
||||
ctx: context.Background(),
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) Start() {
|
||||
log.Ctx(c.ctx).Info("CDC controller started")
|
||||
c.wg.Add(1)
|
||||
go func() {
|
||||
defer c.wg.Done()
|
||||
timer := time.NewTicker(checkInterval)
|
||||
defer timer.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-c.stopChan:
|
||||
return
|
||||
case <-timer.C:
|
||||
c.run()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (c *controller) Stop() {
|
||||
c.stopOnce.Do(func() {
|
||||
log.Ctx(c.ctx).Info("CDC controller stopping...")
|
||||
close(c.stopChan)
|
||||
c.wg.Wait()
|
||||
resource.Resource().ReplicateManagerClient().Close()
|
||||
log.Ctx(c.ctx).Info("CDC controller stopped")
|
||||
})
|
||||
}
|
||||
|
||||
func (c *controller) run() {
|
||||
targetReplicatePChannels, err := resource.Resource().ReplicationCatalog().ListReplicatePChannels(c.ctx)
|
||||
if err != nil {
|
||||
log.Ctx(c.ctx).Error("failed to get replicate pchannels", zap.Error(err))
|
||||
return
|
||||
}
|
||||
// create replicators for all replicate pchannels
|
||||
for _, replicatePChannel := range targetReplicatePChannels {
|
||||
resource.Resource().ReplicateManagerClient().CreateReplicator(replicatePChannel)
|
||||
}
|
||||
|
||||
// remove out of target replicators
|
||||
resource.Resource().ReplicateManagerClient().RemoveOutOfTargetReplicators(targetReplicatePChannels)
|
||||
}
|
||||
@ -1,87 +0,0 @@
|
||||
// Licensed to the LF AI & Data foundation under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controllerimpl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/replication"
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"github.com/milvus-io/milvus/internal/mocks/mock_metastore"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
)
|
||||
|
||||
func TestController_StartAndStop(t *testing.T) {
|
||||
mockReplicateManagerClient := replication.NewMockReplicateManagerClient(t)
|
||||
mockReplicateManagerClient.EXPECT().Close().Return()
|
||||
resource.InitForTest(t,
|
||||
resource.OptReplicateManagerClient(mockReplicateManagerClient),
|
||||
)
|
||||
|
||||
ctrl := NewController()
|
||||
assert.NotPanics(t, func() {
|
||||
ctrl.Start()
|
||||
})
|
||||
assert.NotPanics(t, func() {
|
||||
ctrl.Stop()
|
||||
})
|
||||
}
|
||||
|
||||
func TestController_Run(t *testing.T) {
|
||||
mockReplicateManagerClient := replication.NewMockReplicateManagerClient(t)
|
||||
mockReplicateManagerClient.EXPECT().Close().Return()
|
||||
|
||||
replicatePChannels := []*streamingpb.ReplicatePChannelMeta{
|
||||
{
|
||||
SourceChannelName: "test-source-channel-1",
|
||||
TargetChannelName: "test-target-channel-1",
|
||||
},
|
||||
}
|
||||
mockReplicationCatalog := mock_metastore.NewMockReplicationCatalog(t)
|
||||
mockReplicationCatalog.EXPECT().ListReplicatePChannels(mock.Anything).Return(replicatePChannels, nil)
|
||||
mockReplicateManagerClient.EXPECT().CreateReplicator(replicatePChannels[0]).Return()
|
||||
mockReplicateManagerClient.EXPECT().RemoveOutOfTargetReplicators(replicatePChannels).Return()
|
||||
resource.InitForTest(t,
|
||||
resource.OptReplicateManagerClient(mockReplicateManagerClient),
|
||||
resource.OptReplicationCatalog(mockReplicationCatalog),
|
||||
)
|
||||
|
||||
ctrl := NewController()
|
||||
ctrl.Start()
|
||||
defer ctrl.Stop()
|
||||
ctrl.run()
|
||||
}
|
||||
|
||||
func TestController_RunError(t *testing.T) {
|
||||
mockReplicateManagerClient := replication.NewMockReplicateManagerClient(t)
|
||||
mockReplicateManagerClient.EXPECT().Close().Return()
|
||||
|
||||
mockReplicationCatalog := mock_metastore.NewMockReplicationCatalog(t)
|
||||
mockReplicationCatalog.EXPECT().ListReplicatePChannels(mock.Anything).Return(nil, assert.AnError)
|
||||
resource.InitForTest(t,
|
||||
resource.OptReplicateManagerClient(mockReplicateManagerClient),
|
||||
resource.OptReplicationCatalog(mockReplicationCatalog),
|
||||
)
|
||||
|
||||
ctrl := NewController()
|
||||
ctrl.Start()
|
||||
defer ctrl.Stop()
|
||||
ctrl.run()
|
||||
}
|
||||
@ -1,96 +0,0 @@
|
||||
// Code generated by mockery v2.53.3. DO NOT EDIT.
|
||||
|
||||
package controller
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
// MockController is an autogenerated mock type for the Controller type
|
||||
type MockController struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockController_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockController) EXPECT() *MockController_Expecter {
|
||||
return &MockController_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// Start provides a mock function with no fields
|
||||
func (_m *MockController) Start() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// MockController_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start'
|
||||
type MockController_Start_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Start is a helper method to define mock.On call
|
||||
func (_e *MockController_Expecter) Start() *MockController_Start_Call {
|
||||
return &MockController_Start_Call{Call: _e.mock.On("Start")}
|
||||
}
|
||||
|
||||
func (_c *MockController_Start_Call) Run(run func()) *MockController_Start_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockController_Start_Call) Return() *MockController_Start_Call {
|
||||
_c.Call.Return()
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockController_Start_Call) RunAndReturn(run func()) *MockController_Start_Call {
|
||||
_c.Run(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Stop provides a mock function with no fields
|
||||
func (_m *MockController) Stop() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// MockController_Stop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Stop'
|
||||
type MockController_Stop_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Stop is a helper method to define mock.On call
|
||||
func (_e *MockController_Expecter) Stop() *MockController_Stop_Call {
|
||||
return &MockController_Stop_Call{Call: _e.mock.On("Stop")}
|
||||
}
|
||||
|
||||
func (_c *MockController_Stop_Call) Run(run func()) *MockController_Stop_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockController_Stop_Call) Return() *MockController_Stop_Call {
|
||||
_c.Call.Return()
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockController_Stop_Call) RunAndReturn(run func()) *MockController_Stop_Call {
|
||||
_c.Run(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewMockController creates a new instance of MockController. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockController(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockController {
|
||||
mock := &MockController{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
111
internal/cdc/meta/replicate_meta.go
Normal file
111
internal/cdc/meta/replicate_meta.go
Normal file
@ -0,0 +1,111 @@
|
||||
package meta
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
)
|
||||
|
||||
const requestTimeout = 30 * time.Second
|
||||
|
||||
type ReplicateChannel struct {
|
||||
Key string
|
||||
Value *streamingpb.ReplicatePChannelMeta
|
||||
ModRevision int64
|
||||
}
|
||||
|
||||
type ReplicateChannels struct {
|
||||
Channels []*ReplicateChannel
|
||||
Revision int64
|
||||
}
|
||||
|
||||
// ListReplicatePChannels lists the replicate pchannels metadata from metastore.
|
||||
func ListReplicatePChannels(ctx context.Context, etcdCli *clientv3.Client, prefix string) (*ReplicateChannels, error) {
|
||||
resp, err := listByPrefix(ctx, etcdCli, prefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keys := make([]string, 0, resp.Count)
|
||||
values := make([]string, 0, resp.Count)
|
||||
revisions := make([]int64, 0, resp.Count)
|
||||
for _, kv := range resp.Kvs {
|
||||
keys = append(keys, string(kv.Key))
|
||||
values = append(values, string(kv.Value))
|
||||
revisions = append(revisions, kv.ModRevision)
|
||||
}
|
||||
channels := make([]*ReplicateChannel, 0, len(values))
|
||||
for k, value := range values {
|
||||
meta := &streamingpb.ReplicatePChannelMeta{}
|
||||
err = proto.Unmarshal([]byte(value), meta)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unmarshal replicate pchannel meta %s failed", keys[k])
|
||||
}
|
||||
channel := &ReplicateChannel{
|
||||
Key: keys[k],
|
||||
Value: meta,
|
||||
ModRevision: revisions[k],
|
||||
}
|
||||
channels = append(channels, channel)
|
||||
}
|
||||
return &ReplicateChannels{
|
||||
Channels: channels,
|
||||
Revision: resp.Header.Revision,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RemoveReplicatePChannelWithRevision removes the replicate pchannel from metastore.
|
||||
// Remove the task of CDC replication task of current cluster, should be called when a CDC replication task is finished.
|
||||
// Because CDC removes the replicate pchannel meta asynchronously, there may be ordering conflicts
|
||||
// during primary-secondary switches. For example:
|
||||
// 1. Init: A -> B, Save key
|
||||
// 2. Switch: B -> A, Delete key asynchronously
|
||||
// 3. Switch again: A -> B, Save key
|
||||
// Expected meta op order: [Save, Delete, Save]
|
||||
// Actual meta op may be: [Save, Save, Delete]
|
||||
// To avoid ordering conflicts, we need to pass the key’s revision
|
||||
// and only remove the KV when the revision matches.
|
||||
func RemoveReplicatePChannelWithRevision(ctx context.Context, etcdCli *clientv3.Client, key string, revision int64) (bool, error) {
|
||||
result, err := removeWithCmps(ctx, etcdCli, key, clientv3.Compare(clientv3.ModRevision(key), "=", revision))
|
||||
return result, err
|
||||
}
|
||||
|
||||
func MustParseReplicateChannelFromEvent(e *clientv3.Event) *streamingpb.ReplicatePChannelMeta {
|
||||
meta := &streamingpb.ReplicatePChannelMeta{}
|
||||
err := proto.Unmarshal(e.Kv.Value, meta)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to unmarshal replicate pchannel meta: %v", err))
|
||||
}
|
||||
return meta
|
||||
}
|
||||
|
||||
// listByPrefix gets the key-value pairs with the given prefix.
|
||||
func listByPrefix(ctx context.Context, etcdCli *clientv3.Client, prefix string) (*clientv3.GetResponse, error) {
|
||||
ctx1, cancel := context.WithTimeout(ctx, requestTimeout)
|
||||
defer cancel()
|
||||
|
||||
opts := []clientv3.OpOption{
|
||||
clientv3.WithPrefix(),
|
||||
clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend),
|
||||
}
|
||||
return etcdCli.Get(ctx1, prefix, opts...)
|
||||
}
|
||||
|
||||
// removeWithCmps removes the key with given cmps.
|
||||
func removeWithCmps(ctx context.Context, etcdCli *clientv3.Client, key string, cmps ...clientv3.Cmp) (bool, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, requestTimeout)
|
||||
defer cancel()
|
||||
|
||||
delOp := clientv3.OpDelete(key)
|
||||
txn := etcdCli.Txn(ctx).If(cmps...).Then(delOp)
|
||||
resp, err := txn.Commit()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return resp.Succeeded, nil
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
package replication
|
||||
|
||||
import (
|
||||
streamingpb "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
meta "github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
@ -52,9 +52,9 @@ func (_c *MockReplicateManagerClient_Close_Call) RunAndReturn(run func()) *MockR
|
||||
return _c
|
||||
}
|
||||
|
||||
// CreateReplicator provides a mock function with given fields: replicateInfo
|
||||
func (_m *MockReplicateManagerClient) CreateReplicator(replicateInfo *streamingpb.ReplicatePChannelMeta) {
|
||||
_m.Called(replicateInfo)
|
||||
// CreateReplicator provides a mock function with given fields: channel
|
||||
func (_m *MockReplicateManagerClient) CreateReplicator(channel *meta.ReplicateChannel) {
|
||||
_m.Called(channel)
|
||||
}
|
||||
|
||||
// MockReplicateManagerClient_CreateReplicator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateReplicator'
|
||||
@ -63,14 +63,14 @@ type MockReplicateManagerClient_CreateReplicator_Call struct {
|
||||
}
|
||||
|
||||
// CreateReplicator is a helper method to define mock.On call
|
||||
// - replicateInfo *streamingpb.ReplicatePChannelMeta
|
||||
func (_e *MockReplicateManagerClient_Expecter) CreateReplicator(replicateInfo interface{}) *MockReplicateManagerClient_CreateReplicator_Call {
|
||||
return &MockReplicateManagerClient_CreateReplicator_Call{Call: _e.mock.On("CreateReplicator", replicateInfo)}
|
||||
// - channel *meta.ReplicateChannel
|
||||
func (_e *MockReplicateManagerClient_Expecter) CreateReplicator(channel interface{}) *MockReplicateManagerClient_CreateReplicator_Call {
|
||||
return &MockReplicateManagerClient_CreateReplicator_Call{Call: _e.mock.On("CreateReplicator", channel)}
|
||||
}
|
||||
|
||||
func (_c *MockReplicateManagerClient_CreateReplicator_Call) Run(run func(replicateInfo *streamingpb.ReplicatePChannelMeta)) *MockReplicateManagerClient_CreateReplicator_Call {
|
||||
func (_c *MockReplicateManagerClient_CreateReplicator_Call) Run(run func(channel *meta.ReplicateChannel)) *MockReplicateManagerClient_CreateReplicator_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(*streamingpb.ReplicatePChannelMeta))
|
||||
run(args[0].(*meta.ReplicateChannel))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
@ -80,40 +80,74 @@ func (_c *MockReplicateManagerClient_CreateReplicator_Call) Return() *MockReplic
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockReplicateManagerClient_CreateReplicator_Call) RunAndReturn(run func(*streamingpb.ReplicatePChannelMeta)) *MockReplicateManagerClient_CreateReplicator_Call {
|
||||
func (_c *MockReplicateManagerClient_CreateReplicator_Call) RunAndReturn(run func(*meta.ReplicateChannel)) *MockReplicateManagerClient_CreateReplicator_Call {
|
||||
_c.Run(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// RemoveOutOfTargetReplicators provides a mock function with given fields: targetReplicatePChannels
|
||||
func (_m *MockReplicateManagerClient) RemoveOutOfTargetReplicators(targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta) {
|
||||
_m.Called(targetReplicatePChannels)
|
||||
// RemoveOutdatedReplicators provides a mock function with given fields: aliveChannels
|
||||
func (_m *MockReplicateManagerClient) RemoveOutdatedReplicators(aliveChannels []*meta.ReplicateChannel) {
|
||||
_m.Called(aliveChannels)
|
||||
}
|
||||
|
||||
// MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveOutOfTargetReplicators'
|
||||
type MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call struct {
|
||||
// MockReplicateManagerClient_RemoveOutdatedReplicators_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveOutdatedReplicators'
|
||||
type MockReplicateManagerClient_RemoveOutdatedReplicators_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// RemoveOutOfTargetReplicators is a helper method to define mock.On call
|
||||
// - targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta
|
||||
func (_e *MockReplicateManagerClient_Expecter) RemoveOutOfTargetReplicators(targetReplicatePChannels interface{}) *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call {
|
||||
return &MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call{Call: _e.mock.On("RemoveOutOfTargetReplicators", targetReplicatePChannels)}
|
||||
// RemoveOutdatedReplicators is a helper method to define mock.On call
|
||||
// - aliveChannels []*meta.ReplicateChannel
|
||||
func (_e *MockReplicateManagerClient_Expecter) RemoveOutdatedReplicators(aliveChannels interface{}) *MockReplicateManagerClient_RemoveOutdatedReplicators_Call {
|
||||
return &MockReplicateManagerClient_RemoveOutdatedReplicators_Call{Call: _e.mock.On("RemoveOutdatedReplicators", aliveChannels)}
|
||||
}
|
||||
|
||||
func (_c *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call) Run(run func(targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta)) *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call {
|
||||
func (_c *MockReplicateManagerClient_RemoveOutdatedReplicators_Call) Run(run func(aliveChannels []*meta.ReplicateChannel)) *MockReplicateManagerClient_RemoveOutdatedReplicators_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].([]*streamingpb.ReplicatePChannelMeta))
|
||||
run(args[0].([]*meta.ReplicateChannel))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call) Return() *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call {
|
||||
func (_c *MockReplicateManagerClient_RemoveOutdatedReplicators_Call) Return() *MockReplicateManagerClient_RemoveOutdatedReplicators_Call {
|
||||
_c.Call.Return()
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call) RunAndReturn(run func([]*streamingpb.ReplicatePChannelMeta)) *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call {
|
||||
func (_c *MockReplicateManagerClient_RemoveOutdatedReplicators_Call) RunAndReturn(run func([]*meta.ReplicateChannel)) *MockReplicateManagerClient_RemoveOutdatedReplicators_Call {
|
||||
_c.Run(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// RemoveReplicator provides a mock function with given fields: key, modRevision
|
||||
func (_m *MockReplicateManagerClient) RemoveReplicator(key string, modRevision int64) {
|
||||
_m.Called(key, modRevision)
|
||||
}
|
||||
|
||||
// MockReplicateManagerClient_RemoveReplicator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveReplicator'
|
||||
type MockReplicateManagerClient_RemoveReplicator_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// RemoveReplicator is a helper method to define mock.On call
|
||||
// - key string
|
||||
// - modRevision int64
|
||||
func (_e *MockReplicateManagerClient_Expecter) RemoveReplicator(key interface{}, modRevision interface{}) *MockReplicateManagerClient_RemoveReplicator_Call {
|
||||
return &MockReplicateManagerClient_RemoveReplicator_Call{Call: _e.mock.On("RemoveReplicator", key, modRevision)}
|
||||
}
|
||||
|
||||
func (_c *MockReplicateManagerClient_RemoveReplicator_Call) Run(run func(key string, modRevision int64)) *MockReplicateManagerClient_RemoveReplicator_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(string), args[1].(int64))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockReplicateManagerClient_RemoveReplicator_Call) Return() *MockReplicateManagerClient_RemoveReplicator_Call {
|
||||
_c.Call.Return()
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockReplicateManagerClient_RemoveReplicator_Call) RunAndReturn(run func(string, int64)) *MockReplicateManagerClient_RemoveReplicator_Call {
|
||||
_c.Run(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
@ -16,15 +16,18 @@
|
||||
|
||||
package replication
|
||||
|
||||
import "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
import "github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
|
||||
// ReplicateManagerClient is the client that manages the replicate configuration.
|
||||
type ReplicateManagerClient interface {
|
||||
// CreateReplicator creates a new replicator for the replicate pchannel.
|
||||
CreateReplicator(replicateInfo *streamingpb.ReplicatePChannelMeta)
|
||||
CreateReplicator(channel *meta.ReplicateChannel)
|
||||
|
||||
// RemoveOutOfTargetReplicators removes replicators that are not in the target replicate pchannels.
|
||||
RemoveOutOfTargetReplicators(targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta)
|
||||
// RemoveReplicator removes a replicator for the replicate pchannel.
|
||||
RemoveReplicator(key string, modRevision int64)
|
||||
|
||||
// RemoveOutdatedReplicators removes the outdated replicators.
|
||||
RemoveOutdatedReplicators(aliveChannels []*meta.ReplicateChannel)
|
||||
|
||||
// Close closes the replicate manager client.
|
||||
Close()
|
||||
|
||||
@ -21,162 +21,181 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus/internal/cdc/cluster"
|
||||
"github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
"github.com/milvus-io/milvus/internal/cdc/replication/replicatestream"
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"github.com/milvus-io/milvus/internal/cdc/util"
|
||||
"github.com/milvus-io/milvus/internal/distributed/streaming"
|
||||
"github.com/milvus-io/milvus/internal/streamingnode/server/wal/utility"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
|
||||
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message/adaptor"
|
||||
"github.com/milvus-io/milvus/pkg/v2/streaming/util/options"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/syncutil"
|
||||
)
|
||||
|
||||
const scannerHandlerChanSize = 64
|
||||
|
||||
// Replicator is the client that replicates the message to the channel in the target cluster.
|
||||
type Replicator interface {
|
||||
// StartReplicate starts the replicate for the channel.
|
||||
StartReplicate()
|
||||
// StartReplication starts the replicate for the channel.
|
||||
StartReplication()
|
||||
|
||||
// StopReplicate stops the replicate loop
|
||||
// StopReplication stops the replicate loop
|
||||
// and wait for the loop to exit.
|
||||
StopReplicate()
|
||||
|
||||
// GetState returns the current state of the replicator.
|
||||
GetState() typeutil.LifetimeState
|
||||
StopReplication()
|
||||
}
|
||||
|
||||
var _ Replicator = (*channelReplicator)(nil)
|
||||
|
||||
// channelReplicator is the implementation of ChannelReplicator.
|
||||
type channelReplicator struct {
|
||||
replicateInfo *streamingpb.ReplicatePChannelMeta
|
||||
channel *meta.ReplicateChannel
|
||||
createRscFunc replicatestream.CreateReplicateStreamClientFunc
|
||||
createMcFunc cluster.CreateMilvusClientFunc
|
||||
targetClient cluster.MilvusClient
|
||||
streamClient replicatestream.ReplicateStreamClient
|
||||
msgScanner streaming.Scanner
|
||||
msgChan adaptor.ChanMessageHandler
|
||||
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
lifetime *typeutil.Lifetime
|
||||
asyncNotifier *syncutil.AsyncTaskNotifier[struct{}]
|
||||
}
|
||||
|
||||
// NewChannelReplicator creates a new ChannelReplicator.
|
||||
func NewChannelReplicator(replicateMeta *streamingpb.ReplicatePChannelMeta) Replicator {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
func NewChannelReplicator(channel *meta.ReplicateChannel) Replicator {
|
||||
createRscFunc := replicatestream.NewReplicateStreamClient
|
||||
return &channelReplicator{
|
||||
replicateInfo: replicateMeta,
|
||||
channel: channel,
|
||||
createRscFunc: createRscFunc,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
lifetime: typeutil.NewLifetime(),
|
||||
createMcFunc: cluster.NewMilvusClient,
|
||||
asyncNotifier: syncutil.NewAsyncTaskNotifier[struct{}](),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *channelReplicator) StartReplicate() {
|
||||
logger := log.With(
|
||||
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
|
||||
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
|
||||
)
|
||||
if !r.lifetime.Add(typeutil.LifetimeStateWorking) {
|
||||
logger.Warn("replicate channel already started")
|
||||
return
|
||||
}
|
||||
func (r *channelReplicator) StartReplication() {
|
||||
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("modRevision", r.channel.ModRevision))
|
||||
logger.Info("start replicate channel")
|
||||
go func() {
|
||||
defer r.lifetime.Done()
|
||||
for {
|
||||
err := r.replicateLoop()
|
||||
if err != nil {
|
||||
logger.Warn("replicate channel failed", zap.Error(err))
|
||||
time.Sleep(10 * time.Second)
|
||||
continue
|
||||
defer func() {
|
||||
if r.streamClient != nil {
|
||||
r.streamClient.Close()
|
||||
}
|
||||
if r.msgScanner != nil {
|
||||
r.msgScanner.Close()
|
||||
}
|
||||
if r.targetClient != nil {
|
||||
r.targetClient.Close(r.asyncNotifier.Context())
|
||||
}
|
||||
r.asyncNotifier.Finish(struct{}{})
|
||||
}()
|
||||
INIT_LOOP:
|
||||
for {
|
||||
select {
|
||||
case <-r.asyncNotifier.Context().Done():
|
||||
return
|
||||
default:
|
||||
err := r.init()
|
||||
if err != nil {
|
||||
logger.Warn("initialize replicator failed", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
break INIT_LOOP
|
||||
}
|
||||
break
|
||||
}
|
||||
logger.Info("stop replicate channel")
|
||||
r.startConsumeLoop()
|
||||
}()
|
||||
}
|
||||
|
||||
// replicateLoop starts the replicate loop.
|
||||
func (r *channelReplicator) replicateLoop() error {
|
||||
logger := log.With(
|
||||
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
|
||||
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
|
||||
)
|
||||
cp, err := r.getReplicateCheckpoint()
|
||||
if err != nil {
|
||||
return err
|
||||
func (r *channelReplicator) init() error {
|
||||
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("modRevision", r.channel.ModRevision))
|
||||
// init target client
|
||||
if r.targetClient == nil {
|
||||
dialCtx, dialCancel := context.WithTimeout(r.asyncNotifier.Context(), 30*time.Second)
|
||||
defer dialCancel()
|
||||
milvusClient, err := r.createMcFunc(dialCtx, r.channel.Value.GetTargetCluster())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.targetClient = milvusClient
|
||||
logger.Info("target client initialized")
|
||||
}
|
||||
ch := make(adaptor.ChanMessageHandler, scannerHandlerChanSize)
|
||||
scanner := streaming.WAL().Read(r.ctx, streaming.ReadOption{
|
||||
PChannel: r.replicateInfo.GetSourceChannelName(),
|
||||
DeliverPolicy: options.DeliverPolicyStartFrom(cp.MessageID),
|
||||
DeliverFilters: []options.DeliverFilter{options.DeliverFilterTimeTickGT(cp.TimeTick)},
|
||||
MessageHandler: ch,
|
||||
})
|
||||
defer scanner.Close()
|
||||
// init msg scanner
|
||||
if r.msgScanner == nil {
|
||||
cp, err := r.getReplicateCheckpoint()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ch := make(adaptor.ChanMessageHandler)
|
||||
scanner := streaming.WAL().Read(r.asyncNotifier.Context(), streaming.ReadOption{
|
||||
PChannel: r.channel.Value.GetSourceChannelName(),
|
||||
DeliverPolicy: options.DeliverPolicyStartFrom(cp.MessageID),
|
||||
DeliverFilters: []options.DeliverFilter{options.DeliverFilterTimeTickGT(cp.TimeTick)},
|
||||
MessageHandler: ch,
|
||||
})
|
||||
r.msgScanner = scanner
|
||||
r.msgChan = ch
|
||||
logger.Info("scanner initialized", zap.Any("checkpoint", cp))
|
||||
}
|
||||
// init replicate stream client
|
||||
if r.streamClient == nil {
|
||||
r.streamClient = r.createRscFunc(r.asyncNotifier.Context(), r.targetClient, r.channel)
|
||||
logger.Info("stream client initialized")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
rsc := r.createRscFunc(r.ctx, r.replicateInfo)
|
||||
defer rsc.Close()
|
||||
|
||||
logger.Info("start replicate channel loop", zap.Any("startFrom", cp))
|
||||
// startConsumeLoop starts the replicate loop.
|
||||
func (r *channelReplicator) startConsumeLoop() {
|
||||
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("modRevision", r.channel.ModRevision))
|
||||
logger.Info("start consume loop")
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-r.ctx.Done():
|
||||
logger.Info("replicate channel stopped")
|
||||
return nil
|
||||
case msg := <-ch:
|
||||
// TODO: Should be done at streamingnode.
|
||||
if msg.MessageType().IsSelfControlled() {
|
||||
if msg.MessageType() != message.MessageTypeTimeTick {
|
||||
logger.Debug("skip self-controlled message", log.FieldMessage(msg))
|
||||
case <-r.asyncNotifier.Context().Done():
|
||||
logger.Info("consume loop stopped")
|
||||
return
|
||||
case msg := <-r.msgChan:
|
||||
err := r.streamClient.Replicate(msg)
|
||||
if err != nil {
|
||||
if !errors.Is(err, replicatestream.ErrReplicateIgnored) {
|
||||
panic(fmt.Sprintf("replicate message failed due to unrecoverable error: %v", err))
|
||||
}
|
||||
continue
|
||||
}
|
||||
err := rsc.Replicate(msg)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("replicate message failed due to unrecoverable error: %v", err))
|
||||
}
|
||||
logger.Debug("replicate message success", log.FieldMessage(msg))
|
||||
if msg.MessageType() == message.MessageTypeAlterReplicateConfig {
|
||||
if util.IsReplicationRemovedByAlterReplicateConfigMessage(msg, r.channel.Value) {
|
||||
logger.Info("replication removed, stop consume loop")
|
||||
r.streamClient.BlockUntilFinish()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *channelReplicator) getReplicateCheckpoint() (*utility.ReplicateCheckpoint, error) {
|
||||
logger := log.With(
|
||||
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
|
||||
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
|
||||
)
|
||||
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("modRevision", r.channel.ModRevision))
|
||||
|
||||
ctx, cancel := context.WithTimeout(r.ctx, 30*time.Second)
|
||||
ctx, cancel := context.WithTimeout(r.asyncNotifier.Context(), 30*time.Second)
|
||||
defer cancel()
|
||||
milvusClient, err := resource.Resource().ClusterClient().CreateMilvusClient(ctx, r.replicateInfo.GetTargetCluster())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer milvusClient.Close(ctx)
|
||||
|
||||
sourceClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
|
||||
replicateInfo, err := milvusClient.GetReplicateInfo(ctx, sourceClusterID)
|
||||
req := &milvuspb.GetReplicateInfoRequest{
|
||||
SourceClusterId: sourceClusterID,
|
||||
TargetPchannel: r.channel.Value.GetTargetChannelName(),
|
||||
}
|
||||
replicateInfo, err := r.targetClient.GetReplicateInfo(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "failed to get replicate info")
|
||||
}
|
||||
|
||||
var checkpoint *commonpb.ReplicateCheckpoint
|
||||
for _, cp := range replicateInfo.GetCheckpoints() {
|
||||
if cp.GetPchannel() == r.replicateInfo.GetSourceChannelName() {
|
||||
checkpoint = cp
|
||||
break
|
||||
}
|
||||
}
|
||||
checkpoint := replicateInfo.GetCheckpoint()
|
||||
if checkpoint == nil || checkpoint.MessageId == nil {
|
||||
initializedCheckpoint := utility.NewReplicateCheckpointFromProto(r.replicateInfo.InitializedCheckpoint)
|
||||
initializedCheckpoint := utility.NewReplicateCheckpointFromProto(r.channel.Value.InitializedCheckpoint)
|
||||
logger.Info("channel not found in replicate info, will start from the beginning",
|
||||
zap.Stringer("messageID", initializedCheckpoint.MessageID),
|
||||
zap.Uint64("timeTick", initializedCheckpoint.TimeTick),
|
||||
@ -192,12 +211,7 @@ func (r *channelReplicator) getReplicateCheckpoint() (*utility.ReplicateCheckpoi
|
||||
return cp, nil
|
||||
}
|
||||
|
||||
func (r *channelReplicator) StopReplicate() {
|
||||
r.lifetime.SetState(typeutil.LifetimeStateStopped)
|
||||
r.cancel()
|
||||
r.lifetime.Wait()
|
||||
}
|
||||
|
||||
func (r *channelReplicator) GetState() typeutil.LifetimeState {
|
||||
return r.lifetime.GetState()
|
||||
func (r *channelReplicator) StopReplication() {
|
||||
r.asyncNotifier.Cancel()
|
||||
r.asyncNotifier.BlockUntilFinish()
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ package replicatemanager
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/apache/pulsar-client-go/pulsar"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -27,13 +28,12 @@ import (
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus/internal/cdc/cluster"
|
||||
"github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
"github.com/milvus-io/milvus/internal/cdc/replication/replicatestream"
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"github.com/milvus-io/milvus/internal/distributed/streaming"
|
||||
"github.com/milvus-io/milvus/internal/mocks/distributed/mock_streaming"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
pulsar2 "github.com/milvus-io/milvus/pkg/v2/streaming/walimpls/impls/pulsar"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
|
||||
)
|
||||
|
||||
func newMockPulsarMessageID() *commonpb.MessageID {
|
||||
@ -49,22 +49,13 @@ func TestChannelReplicator_StartReplicateChannel(t *testing.T) {
|
||||
mockMilvusClient := cluster.NewMockMilvusClient(t)
|
||||
mockMilvusClient.EXPECT().GetReplicateInfo(mock.Anything, mock.Anything).
|
||||
Return(&milvuspb.GetReplicateInfoResponse{
|
||||
Checkpoints: []*commonpb.ReplicateCheckpoint{
|
||||
{
|
||||
Pchannel: "test-source-channel",
|
||||
MessageId: newMockPulsarMessageID(),
|
||||
},
|
||||
Checkpoint: &commonpb.ReplicateCheckpoint{
|
||||
Pchannel: "test-source-channel",
|
||||
MessageId: newMockPulsarMessageID(),
|
||||
},
|
||||
}, nil)
|
||||
mockMilvusClient.EXPECT().Close(mock.Anything).Return(nil)
|
||||
|
||||
mockClusterClient := cluster.NewMockClusterClient(t)
|
||||
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
|
||||
Return(mockMilvusClient, nil)
|
||||
resource.InitForTest(t,
|
||||
resource.OptClusterClient(mockClusterClient),
|
||||
)
|
||||
|
||||
scanner := mock_streaming.NewMockScanner(t)
|
||||
scanner.EXPECT().Close().Return()
|
||||
wal := mock_streaming.NewMockWALAccesser(t)
|
||||
@ -74,23 +65,31 @@ func TestChannelReplicator_StartReplicateChannel(t *testing.T) {
|
||||
rs := replicatestream.NewMockReplicateStreamClient(t)
|
||||
rs.EXPECT().Close().Return()
|
||||
|
||||
cluster := &commonpb.MilvusCluster{ClusterId: "test-cluster"}
|
||||
mc := &commonpb.MilvusCluster{ClusterId: "test-cluster"}
|
||||
replicateInfo := &streamingpb.ReplicatePChannelMeta{
|
||||
SourceChannelName: "test-source-channel",
|
||||
TargetChannelName: "test-target-channel",
|
||||
TargetCluster: cluster,
|
||||
TargetCluster: mc,
|
||||
}
|
||||
replicator := NewChannelReplicator(replicateInfo)
|
||||
replicator := NewChannelReplicator(&meta.ReplicateChannel{
|
||||
Value: replicateInfo,
|
||||
ModRevision: 0,
|
||||
})
|
||||
assert.NotNil(t, replicator)
|
||||
|
||||
replicator.(*channelReplicator).createRscFunc = func(ctx context.Context,
|
||||
replicateInfo *streamingpb.ReplicatePChannelMeta,
|
||||
c cluster.MilvusClient,
|
||||
rm *meta.ReplicateChannel,
|
||||
) replicatestream.ReplicateStreamClient {
|
||||
return rs
|
||||
}
|
||||
assert.NotNil(t, replicator)
|
||||
replicator.(*channelReplicator).createMcFunc = func(ctx context.Context,
|
||||
cluster *commonpb.MilvusCluster,
|
||||
) (cluster.MilvusClient, error) {
|
||||
return mockMilvusClient, nil
|
||||
}
|
||||
|
||||
replicator.StartReplicate()
|
||||
replicator.StopReplicate()
|
||||
|
||||
state := replicator.GetState()
|
||||
assert.Equal(t, typeutil.LifetimeStateStopped, state)
|
||||
replicator.StartReplication()
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
replicator.StopReplication()
|
||||
}
|
||||
|
||||
@ -18,74 +18,103 @@ package replicatemanager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
|
||||
"github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
|
||||
)
|
||||
|
||||
// replicateManager is the implementation of ReplicateManagerClient.
|
||||
type replicateManager struct {
|
||||
ctx context.Context
|
||||
mu sync.Mutex
|
||||
|
||||
// replicators is a map of replicate pchannel name to ChannelReplicator.
|
||||
replicators map[string]Replicator
|
||||
replicatorPChannels map[string]*streamingpb.ReplicatePChannelMeta
|
||||
replicators map[string]Replicator
|
||||
replicatorChannels map[string]*meta.ReplicateChannel
|
||||
}
|
||||
|
||||
func NewReplicateManager() *replicateManager {
|
||||
return &replicateManager{
|
||||
ctx: context.Background(),
|
||||
replicators: make(map[string]Replicator),
|
||||
replicatorPChannels: make(map[string]*streamingpb.ReplicatePChannelMeta),
|
||||
ctx: context.Background(),
|
||||
replicators: make(map[string]Replicator),
|
||||
replicatorChannels: make(map[string]*meta.ReplicateChannel),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *replicateManager) CreateReplicator(replicateInfo *streamingpb.ReplicatePChannelMeta) {
|
||||
logger := log.With(
|
||||
zap.String("sourceChannel", replicateInfo.GetSourceChannelName()),
|
||||
zap.String("targetChannel", replicateInfo.GetTargetChannelName()),
|
||||
)
|
||||
func buildReplicatorKey(metaKey string, modRevision int64) string {
|
||||
return fmt.Sprintf("%s/_v%d", metaKey, modRevision)
|
||||
}
|
||||
|
||||
func (r *replicateManager) CreateReplicator(channel *meta.ReplicateChannel) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
logger := log.With(zap.String("key", channel.Key), zap.Int64("modRevision", channel.ModRevision))
|
||||
repKey := buildReplicatorKey(channel.Key, channel.ModRevision)
|
||||
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
|
||||
if !strings.Contains(replicateInfo.GetSourceChannelName(), currentClusterID) {
|
||||
// current cluster is not source cluster, skip create replicator
|
||||
if !strings.Contains(channel.Value.GetSourceChannelName(), currentClusterID) {
|
||||
return
|
||||
}
|
||||
replicatorKey := streamingcoord.BuildReplicatePChannelMetaKey(replicateInfo)
|
||||
_, ok := r.replicators[replicatorKey]
|
||||
_, ok := r.replicators[repKey]
|
||||
if ok {
|
||||
logger.Debug("replicator already exists, skip create replicator")
|
||||
return
|
||||
}
|
||||
replicator := NewChannelReplicator(replicateInfo)
|
||||
replicator.StartReplicate()
|
||||
r.replicators[replicatorKey] = replicator
|
||||
r.replicatorPChannels[replicatorKey] = replicateInfo
|
||||
replicator := NewChannelReplicator(channel)
|
||||
replicator.StartReplication()
|
||||
r.replicators[repKey] = replicator
|
||||
r.replicatorChannels[repKey] = channel
|
||||
logger.Info("created replicator for replicate pchannel")
|
||||
}
|
||||
|
||||
func (r *replicateManager) RemoveOutOfTargetReplicators(targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta) {
|
||||
targets := lo.KeyBy(targetReplicatePChannels, streamingcoord.BuildReplicatePChannelMetaKey)
|
||||
for replicatorKey, replicator := range r.replicators {
|
||||
if pchannelMeta, ok := targets[replicatorKey]; !ok {
|
||||
replicator.StopReplicate()
|
||||
delete(r.replicators, replicatorKey)
|
||||
delete(r.replicatorPChannels, replicatorKey)
|
||||
log.Info("removed replicator due to out of target",
|
||||
zap.String("sourceChannel", pchannelMeta.GetSourceChannelName()),
|
||||
zap.String("targetChannel", pchannelMeta.GetTargetChannelName()),
|
||||
)
|
||||
func (r *replicateManager) RemoveReplicator(key string, modRevision int64) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.removeReplicatorInternal(key, modRevision)
|
||||
}
|
||||
|
||||
func (r *replicateManager) removeReplicatorInternal(key string, modRevision int64) {
|
||||
logger := log.With(zap.String("key", key), zap.Int64("modRevision", modRevision))
|
||||
repKey := buildReplicatorKey(key, modRevision)
|
||||
replicator, ok := r.replicators[repKey]
|
||||
if !ok {
|
||||
logger.Info("replicator not found, skip remove")
|
||||
return
|
||||
}
|
||||
replicator.StopReplication()
|
||||
delete(r.replicators, repKey)
|
||||
delete(r.replicatorChannels, repKey)
|
||||
logger.Info("removed replicator for replicate pchannel")
|
||||
}
|
||||
|
||||
func (r *replicateManager) RemoveOutdatedReplicators(aliveChannels []*meta.ReplicateChannel) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
alivesMap := make(map[string]struct{})
|
||||
for _, channel := range aliveChannels {
|
||||
repKey := buildReplicatorKey(channel.Key, channel.ModRevision)
|
||||
alivesMap[repKey] = struct{}{}
|
||||
}
|
||||
for repKey := range r.replicators {
|
||||
if _, ok := alivesMap[repKey]; !ok {
|
||||
channel := r.replicatorChannels[repKey]
|
||||
r.removeReplicatorInternal(channel.Key, channel.ModRevision)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *replicateManager) Close() {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
for _, replicator := range r.replicators {
|
||||
replicator.StopReplicate()
|
||||
replicator.StopReplication()
|
||||
}
|
||||
r.replicators = make(map[string]Replicator)
|
||||
r.replicatorChannels = make(map[string]*meta.ReplicateChannel)
|
||||
}
|
||||
|
||||
@ -24,8 +24,7 @@ import (
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus/internal/cdc/cluster"
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
|
||||
"github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
|
||||
)
|
||||
@ -39,13 +38,6 @@ func TestReplicateManager_CreateReplicator(t *testing.T) {
|
||||
Return(nil, assert.AnError).Maybe()
|
||||
mockMilvusClient.EXPECT().Close(mock.Anything).Return(nil).Maybe()
|
||||
|
||||
mockClusterClient := cluster.NewMockClusterClient(t)
|
||||
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
|
||||
Return(mockMilvusClient, nil).Maybe()
|
||||
resource.InitForTest(t,
|
||||
resource.OptClusterClient(mockClusterClient),
|
||||
)
|
||||
|
||||
manager := NewReplicateManager()
|
||||
|
||||
// Test creating first replicator
|
||||
@ -56,13 +48,18 @@ func TestReplicateManager_CreateReplicator(t *testing.T) {
|
||||
ClusterId: "test-cluster-1",
|
||||
},
|
||||
}
|
||||
key := "test-replicate-key-1"
|
||||
replicateMeta := &meta.ReplicateChannel{
|
||||
Key: key,
|
||||
Value: replicateInfo,
|
||||
ModRevision: 0,
|
||||
}
|
||||
|
||||
manager.CreateReplicator(replicateInfo)
|
||||
manager.CreateReplicator(replicateMeta)
|
||||
|
||||
// Verify replicator was created
|
||||
assert.Equal(t, 1, len(manager.replicators))
|
||||
key := streamingcoord.BuildReplicatePChannelMetaKey(replicateInfo)
|
||||
replicator, exists := manager.replicators[key]
|
||||
replicator, exists := manager.replicators[buildReplicatorKey(key, 0)]
|
||||
assert.True(t, exists)
|
||||
assert.NotNil(t, replicator)
|
||||
|
||||
@ -74,18 +71,23 @@ func TestReplicateManager_CreateReplicator(t *testing.T) {
|
||||
ClusterId: "test-cluster-2",
|
||||
},
|
||||
}
|
||||
key2 := "test-replicate-key-2"
|
||||
replicateMeta2 := &meta.ReplicateChannel{
|
||||
Key: key2,
|
||||
Value: replicateInfo2,
|
||||
ModRevision: 0,
|
||||
}
|
||||
|
||||
manager.CreateReplicator(replicateInfo2)
|
||||
manager.CreateReplicator(replicateMeta2)
|
||||
|
||||
// Verify second replicator was created
|
||||
assert.Equal(t, 2, len(manager.replicators))
|
||||
key2 := streamingcoord.BuildReplicatePChannelMetaKey(replicateInfo2)
|
||||
replicator2, exists := manager.replicators[key2]
|
||||
replicator2, exists := manager.replicators[buildReplicatorKey(key2, 0)]
|
||||
assert.True(t, exists)
|
||||
assert.NotNil(t, replicator2)
|
||||
|
||||
// Verify first replicator still exists
|
||||
replicator1, exists := manager.replicators[key]
|
||||
replicator1, exists := manager.replicators[buildReplicatorKey(key, 0)]
|
||||
assert.True(t, exists)
|
||||
assert.NotNil(t, replicator1)
|
||||
}
|
||||
|
||||
@ -19,9 +19,11 @@ package replicatestream
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/milvus-io/milvus/pkg/v2/metrics"
|
||||
streamingpb "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
message "github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/timerecord"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/tsoutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
|
||||
@ -31,9 +33,11 @@ type ReplicateMetrics interface {
|
||||
StartReplicate(msg message.ImmutableMessage)
|
||||
OnSent(msg message.ImmutableMessage)
|
||||
OnConfirmed(msg message.ImmutableMessage)
|
||||
OnNoIncomingMessages()
|
||||
OnInitiate()
|
||||
OnConnect()
|
||||
OnDisconnect()
|
||||
OnReconnect()
|
||||
OnClose()
|
||||
}
|
||||
|
||||
type msgMetrics struct {
|
||||
@ -96,10 +100,18 @@ func (m *replicateMetrics) OnConfirmed(msg message.ImmutableMessage) {
|
||||
).Set(float64(lag.Milliseconds()))
|
||||
}
|
||||
|
||||
func (m *replicateMetrics) OnConnect() {
|
||||
// OnNoIncomingMessages is called when there are no incoming messages.
|
||||
func (m *replicateMetrics) OnNoIncomingMessages() {
|
||||
metrics.CDCReplicateLag.WithLabelValues(
|
||||
m.replicateInfo.GetSourceChannelName(),
|
||||
m.replicateInfo.GetTargetChannelName(),
|
||||
).Set(0)
|
||||
}
|
||||
|
||||
func (m *replicateMetrics) OnInitiate() {
|
||||
metrics.CDCStreamRPCConnections.WithLabelValues(
|
||||
m.replicateInfo.GetTargetCluster().GetClusterId(),
|
||||
metrics.CDCStatusConnected,
|
||||
metrics.CDCStatusDisconnected,
|
||||
).Inc()
|
||||
}
|
||||
|
||||
@ -115,7 +127,7 @@ func (m *replicateMetrics) OnDisconnect() {
|
||||
).Inc()
|
||||
}
|
||||
|
||||
func (m *replicateMetrics) OnReconnect() {
|
||||
func (m *replicateMetrics) OnConnect() {
|
||||
targetClusterID := m.replicateInfo.GetTargetCluster().GetClusterId()
|
||||
metrics.CDCStreamRPCConnections.WithLabelValues(
|
||||
targetClusterID,
|
||||
@ -130,3 +142,9 @@ func (m *replicateMetrics) OnReconnect() {
|
||||
targetClusterID,
|
||||
).Inc()
|
||||
}
|
||||
|
||||
func (m *replicateMetrics) OnClose() {
|
||||
metrics.CDCStreamRPCConnections.DeletePartialMatch(prometheus.Labels{
|
||||
metrics.CDCLabelTargetCluster: m.replicateInfo.GetTargetCluster().GetClusterId(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -20,6 +20,38 @@ func (_m *MockReplicateStreamClient) EXPECT() *MockReplicateStreamClient_Expecte
|
||||
return &MockReplicateStreamClient_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// BlockUntilFinish provides a mock function with no fields
|
||||
func (_m *MockReplicateStreamClient) BlockUntilFinish() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// MockReplicateStreamClient_BlockUntilFinish_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BlockUntilFinish'
|
||||
type MockReplicateStreamClient_BlockUntilFinish_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// BlockUntilFinish is a helper method to define mock.On call
|
||||
func (_e *MockReplicateStreamClient_Expecter) BlockUntilFinish() *MockReplicateStreamClient_BlockUntilFinish_Call {
|
||||
return &MockReplicateStreamClient_BlockUntilFinish_Call{Call: _e.mock.On("BlockUntilFinish")}
|
||||
}
|
||||
|
||||
func (_c *MockReplicateStreamClient_BlockUntilFinish_Call) Run(run func()) *MockReplicateStreamClient_BlockUntilFinish_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockReplicateStreamClient_BlockUntilFinish_Call) Return() *MockReplicateStreamClient_BlockUntilFinish_Call {
|
||||
_c.Call.Return()
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockReplicateStreamClient_BlockUntilFinish_Call) RunAndReturn(run func()) *MockReplicateStreamClient_BlockUntilFinish_Call {
|
||||
_c.Run(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Close provides a mock function with no fields
|
||||
func (_m *MockReplicateStreamClient) Close() {
|
||||
_m.Called()
|
||||
|
||||
@ -62,18 +62,28 @@ type msgQueue struct {
|
||||
notEmpty *sync.Cond
|
||||
notFull *sync.Cond
|
||||
|
||||
buf []message.ImmutableMessage
|
||||
readIdx int
|
||||
cap int
|
||||
closed bool
|
||||
buf []message.ImmutableMessage
|
||||
bufBytes int
|
||||
readIdx int
|
||||
cap int
|
||||
maxSize int
|
||||
closed bool
|
||||
}
|
||||
|
||||
type MsgQueueOptions struct {
|
||||
Capacity int
|
||||
MaxSize int
|
||||
}
|
||||
|
||||
// NewMsgQueue creates a queue with a fixed capacity (>0).
|
||||
func NewMsgQueue(capacity int) *msgQueue {
|
||||
if capacity <= 0 {
|
||||
func NewMsgQueue(options MsgQueueOptions) *msgQueue {
|
||||
if options.Capacity <= 0 {
|
||||
panic("capacity must be > 0")
|
||||
}
|
||||
q := &msgQueue{cap: capacity}
|
||||
if options.MaxSize <= 0 {
|
||||
panic("max size must be > 0")
|
||||
}
|
||||
q := &msgQueue{cap: options.Capacity, maxSize: options.MaxSize}
|
||||
q.notEmpty = sync.NewCond(&q.mu)
|
||||
q.notFull = sync.NewCond(&q.mu)
|
||||
return q
|
||||
@ -92,7 +102,7 @@ func (q *msgQueue) Enqueue(ctx context.Context, msg message.ImmutableMessage) er
|
||||
q.mu.Lock()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
for len(q.buf) >= q.cap {
|
||||
for len(q.buf) >= q.cap || q.bufBytes >= q.maxSize {
|
||||
if ctx.Err() != nil {
|
||||
return context.Canceled
|
||||
}
|
||||
@ -110,6 +120,7 @@ func (q *msgQueue) Enqueue(ctx context.Context, msg message.ImmutableMessage) er
|
||||
// }
|
||||
|
||||
q.buf = append(q.buf, msg)
|
||||
q.bufBytes += msg.EstimateSize()
|
||||
|
||||
// New data is available for readers.
|
||||
q.notEmpty.Signal()
|
||||
@ -176,6 +187,11 @@ func (q *msgQueue) CleanupConfirmedMessages(lastConfirmedTimeTick uint64) []mess
|
||||
copy(cleanedMessages, q.buf[:cut])
|
||||
|
||||
// Drop the prefix [0:cut)
|
||||
// Release memory of [0:cut) by zeroing references before reslicing
|
||||
for i := 0; i < cut; i++ {
|
||||
q.bufBytes -= q.buf[i].EstimateSize()
|
||||
q.buf[i] = nil
|
||||
}
|
||||
q.buf = q.buf[cut:]
|
||||
// Adjust read cursor relative to the new slice
|
||||
q.readIdx -= cut
|
||||
|
||||
@ -29,7 +29,7 @@ import (
|
||||
|
||||
func TestMsgQueue_BasicOperations(t *testing.T) {
|
||||
// Test basic queue operations
|
||||
queue := NewMsgQueue(3)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 3, MaxSize: 1000})
|
||||
assert.Equal(t, 3, queue.Cap())
|
||||
assert.Equal(t, 0, queue.Len())
|
||||
|
||||
@ -37,6 +37,7 @@ func TestMsgQueue_BasicOperations(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
msg1 := mock_message.NewMockImmutableMessage(t)
|
||||
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
|
||||
msg1.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
|
||||
err := queue.Enqueue(ctx, msg1)
|
||||
assert.NoError(t, err)
|
||||
@ -51,14 +52,16 @@ func TestMsgQueue_BasicOperations(t *testing.T) {
|
||||
|
||||
func TestMsgQueue_EnqueueBlocking(t *testing.T) {
|
||||
// Test enqueue blocking when queue is full
|
||||
queue := NewMsgQueue(2)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 2, MaxSize: 1000})
|
||||
ctx := context.Background()
|
||||
|
||||
// Fill the queue
|
||||
msg1 := mock_message.NewMockImmutableMessage(t)
|
||||
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
|
||||
msg1.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
msg2 := mock_message.NewMockImmutableMessage(t)
|
||||
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
|
||||
msg2.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
|
||||
err := queue.Enqueue(ctx, msg1)
|
||||
assert.NoError(t, err)
|
||||
@ -69,6 +72,7 @@ func TestMsgQueue_EnqueueBlocking(t *testing.T) {
|
||||
// Try to enqueue when full - should block
|
||||
msg3 := mock_message.NewMockImmutableMessage(t)
|
||||
msg3.EXPECT().TimeTick().Return(uint64(300)).Maybe()
|
||||
msg3.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
|
||||
// Use a context with timeout to test blocking
|
||||
ctxWithTimeout, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
@ -82,7 +86,7 @@ func TestMsgQueue_EnqueueBlocking(t *testing.T) {
|
||||
|
||||
func TestMsgQueue_DequeueBlocking(t *testing.T) {
|
||||
// Test dequeue blocking when queue is empty
|
||||
queue := NewMsgQueue(2)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 2, MaxSize: 1000})
|
||||
ctx := context.Background()
|
||||
|
||||
// Try to dequeue from empty queue - should block
|
||||
@ -97,14 +101,16 @@ func TestMsgQueue_DequeueBlocking(t *testing.T) {
|
||||
|
||||
func TestMsgQueue_SeekToHead(t *testing.T) {
|
||||
// Test seek to head functionality
|
||||
queue := NewMsgQueue(3)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 3, MaxSize: 1000})
|
||||
ctx := context.Background()
|
||||
|
||||
// Add messages
|
||||
msg1 := mock_message.NewMockImmutableMessage(t)
|
||||
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
|
||||
msg1.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
msg2 := mock_message.NewMockImmutableMessage(t)
|
||||
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
|
||||
msg2.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
|
||||
err := queue.Enqueue(ctx, msg1)
|
||||
assert.NoError(t, err)
|
||||
@ -127,16 +133,19 @@ func TestMsgQueue_SeekToHead(t *testing.T) {
|
||||
|
||||
func TestMsgQueue_CleanupConfirmedMessages(t *testing.T) {
|
||||
// Test cleanup functionality
|
||||
queue := NewMsgQueue(5)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 5, MaxSize: 1000})
|
||||
ctx := context.Background()
|
||||
|
||||
// Add messages with different timeticks
|
||||
msg1 := mock_message.NewMockImmutableMessage(t)
|
||||
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
|
||||
msg1.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
msg2 := mock_message.NewMockImmutableMessage(t)
|
||||
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
|
||||
msg2.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
msg3 := mock_message.NewMockImmutableMessage(t)
|
||||
msg3.EXPECT().TimeTick().Return(uint64(300)).Maybe()
|
||||
msg3.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
|
||||
err := queue.Enqueue(ctx, msg1)
|
||||
assert.NoError(t, err)
|
||||
@ -162,16 +171,19 @@ func TestMsgQueue_CleanupConfirmedMessages(t *testing.T) {
|
||||
|
||||
func TestMsgQueue_CleanupWithReadCursor(t *testing.T) {
|
||||
// Test cleanup when read cursor is advanced
|
||||
queue := NewMsgQueue(5)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 5, MaxSize: 1000})
|
||||
ctx := context.Background()
|
||||
|
||||
// Add messages
|
||||
msg1 := mock_message.NewMockImmutableMessage(t)
|
||||
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
|
||||
msg1.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
msg2 := mock_message.NewMockImmutableMessage(t)
|
||||
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
|
||||
msg2.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
msg3 := mock_message.NewMockImmutableMessage(t)
|
||||
msg3.EXPECT().TimeTick().Return(uint64(300)).Maybe()
|
||||
msg3.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
|
||||
err := queue.Enqueue(ctx, msg1)
|
||||
assert.NoError(t, err)
|
||||
@ -184,30 +196,30 @@ func TestMsgQueue_CleanupWithReadCursor(t *testing.T) {
|
||||
dequeuedMsg, err := queue.ReadNext(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, msg1, dequeuedMsg)
|
||||
assert.Equal(t, 1, queue.readIdx)
|
||||
|
||||
// Cleanup messages with timetick <= 150
|
||||
cleanedMessages := queue.CleanupConfirmedMessages(150)
|
||||
assert.Equal(t, 2, queue.Len()) // msg1 removed, msg2 and msg3 remain
|
||||
assert.Equal(t, 0, queue.readIdx) // read cursor adjusted
|
||||
assert.Equal(t, 2, queue.Len()) // msg1 removed, msg2 and msg3 remain
|
||||
assert.Equal(t, 1, len(cleanedMessages))
|
||||
assert.Equal(t, msg1, cleanedMessages[0])
|
||||
}
|
||||
|
||||
func TestMsgQueue_ContextCancellation(t *testing.T) {
|
||||
// Test context cancellation
|
||||
queue := NewMsgQueue(1)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: 1000})
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
// Fill the queue
|
||||
msg1 := mock_message.NewMockImmutableMessage(t)
|
||||
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
|
||||
msg1.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
err := queue.Enqueue(ctx, msg1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Try to enqueue when full
|
||||
msg2 := mock_message.NewMockImmutableMessage(t)
|
||||
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
|
||||
msg2.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
|
||||
// Cancel context before enqueue
|
||||
cancel()
|
||||
@ -219,22 +231,30 @@ func TestMsgQueue_ContextCancellation(t *testing.T) {
|
||||
func TestMsgQueue_NewMsgQueueValidation(t *testing.T) {
|
||||
// Test constructor validation
|
||||
assert.Panics(t, func() {
|
||||
NewMsgQueue(0)
|
||||
NewMsgQueue(MsgQueueOptions{Capacity: 0, MaxSize: 1000})
|
||||
})
|
||||
|
||||
assert.Panics(t, func() {
|
||||
NewMsgQueue(-1)
|
||||
NewMsgQueue(MsgQueueOptions{Capacity: -1, MaxSize: 1000})
|
||||
})
|
||||
|
||||
assert.Panics(t, func() {
|
||||
NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: 0})
|
||||
})
|
||||
|
||||
assert.Panics(t, func() {
|
||||
NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: -1})
|
||||
})
|
||||
|
||||
// Valid capacity
|
||||
queue := NewMsgQueue(1)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: 1000})
|
||||
assert.NotNil(t, queue)
|
||||
assert.Equal(t, 1, queue.Cap())
|
||||
}
|
||||
|
||||
func TestMsgQueue_ConcurrentOperations(t *testing.T) {
|
||||
// Test concurrent enqueue and dequeue operations
|
||||
queue := NewMsgQueue(10)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 10, MaxSize: 10000})
|
||||
ctx := context.Background()
|
||||
numMessages := 100
|
||||
|
||||
@ -246,6 +266,7 @@ func TestMsgQueue_ConcurrentOperations(t *testing.T) {
|
||||
for i := 0; i < numMessages; i++ {
|
||||
msg := mock_message.NewMockImmutableMessage(t)
|
||||
msg.EXPECT().TimeTick().Return(uint64(i)).Maybe()
|
||||
msg.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
err := queue.Enqueue(ctx, msg)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@ -270,7 +291,7 @@ func TestMsgQueue_ConcurrentOperations(t *testing.T) {
|
||||
|
||||
func TestMsgQueue_EdgeCases(t *testing.T) {
|
||||
// Test edge cases
|
||||
queue := NewMsgQueue(1)
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: 1000})
|
||||
|
||||
// Test with nil message (if allowed by interface)
|
||||
// This depends on the actual message.ImmutableMessage interface implementation
|
||||
@ -283,5 +304,90 @@ func TestMsgQueue_EdgeCases(t *testing.T) {
|
||||
|
||||
// Test seek to head on empty queue
|
||||
queue.SeekToHead()
|
||||
assert.Equal(t, 0, queue.readIdx)
|
||||
// Note: readIdx is not accessible from outside the package
|
||||
}
|
||||
|
||||
func TestMsgQueue_SizeBasedCapacity(t *testing.T) {
|
||||
// Test size-based capacity control
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 10, MaxSize: 100})
|
||||
ctx := context.Background()
|
||||
|
||||
// Add messages that exceed size limit but not count limit
|
||||
msg1 := mock_message.NewMockImmutableMessage(t)
|
||||
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
|
||||
msg1.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
msg2 := mock_message.NewMockImmutableMessage(t)
|
||||
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
|
||||
msg2.EXPECT().EstimateSize().Return(50).Maybe()
|
||||
|
||||
err := queue.Enqueue(ctx, msg1)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, queue.Len())
|
||||
|
||||
// Try to enqueue second message - should block due to size limit (100 >= 100)
|
||||
ctxWithTimeout, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
err = queue.Enqueue(ctxWithTimeout, msg2)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, context.Canceled, err)
|
||||
}
|
||||
|
||||
func TestMsgQueue_SizeBasedCapacityWithCleanup(t *testing.T) {
|
||||
// Test size-based capacity with cleanup
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 10, MaxSize: 300})
|
||||
ctx := context.Background()
|
||||
|
||||
// Add messages
|
||||
msg1 := mock_message.NewMockImmutableMessage(t)
|
||||
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
|
||||
msg1.EXPECT().EstimateSize().Return(200).Maybe()
|
||||
msg2 := mock_message.NewMockImmutableMessage(t)
|
||||
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
|
||||
msg2.EXPECT().EstimateSize().Return(200).Maybe()
|
||||
|
||||
err := queue.Enqueue(ctx, msg1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Cleanup first message to free space
|
||||
cleanedMessages := queue.CleanupConfirmedMessages(100)
|
||||
assert.Equal(t, 1, len(cleanedMessages))
|
||||
assert.Equal(t, msg1, cleanedMessages[0])
|
||||
|
||||
// Now should be able to enqueue second message (200 < 300)
|
||||
err = queue.Enqueue(ctx, msg2)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, queue.Len())
|
||||
}
|
||||
|
||||
func TestMsgQueue_MixedCapacityLimits(t *testing.T) {
|
||||
// Test both count and size limits
|
||||
queue := NewMsgQueue(MsgQueueOptions{Capacity: 2, MaxSize: 1000})
|
||||
ctx := context.Background()
|
||||
|
||||
// Add messages that hit count limit first
|
||||
msg1 := mock_message.NewMockImmutableMessage(t)
|
||||
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
|
||||
msg1.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
msg2 := mock_message.NewMockImmutableMessage(t)
|
||||
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
|
||||
msg2.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
|
||||
err := queue.Enqueue(ctx, msg1)
|
||||
assert.NoError(t, err)
|
||||
err = queue.Enqueue(ctx, msg2)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 2, queue.Len())
|
||||
|
||||
// Try to enqueue third message - should block due to count limit
|
||||
msg3 := mock_message.NewMockImmutableMessage(t)
|
||||
msg3.EXPECT().TimeTick().Return(uint64(300)).Maybe()
|
||||
msg3.EXPECT().EstimateSize().Return(100).Maybe()
|
||||
|
||||
ctxWithTimeout, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
err = queue.Enqueue(ctxWithTimeout, msg3)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, context.Canceled, err)
|
||||
}
|
||||
|
||||
@ -19,20 +19,29 @@ package replicatestream
|
||||
import (
|
||||
context "context"
|
||||
|
||||
streamingpb "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
"github.com/cockroachdb/errors"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/cluster"
|
||||
"github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
|
||||
)
|
||||
|
||||
var ErrReplicateIgnored = errors.New("ignored replicate message")
|
||||
|
||||
// ReplicateStreamClient is the client that replicates the message to the given cluster.
|
||||
type ReplicateStreamClient interface {
|
||||
// Replicate replicates the message to the target cluster.
|
||||
// Replicate opeartion doesn't promise the message is delivered to the target cluster.
|
||||
// It will cache the message in memory and retry until the message is delivered to the target cluster or the client is closed.
|
||||
// Once the error is returned, the replicate operation will be unrecoverable.
|
||||
// return ErrReplicateIgnored if the message should not be replicated.
|
||||
Replicate(msg message.ImmutableMessage) error
|
||||
|
||||
// Stop stops the replicate operation.
|
||||
// BlockUntilFinish blocks until the replicate stream client is finished.
|
||||
BlockUntilFinish()
|
||||
|
||||
// Close closes the replicate stream client.
|
||||
Close()
|
||||
}
|
||||
|
||||
type CreateReplicateStreamClientFunc func(ctx context.Context, replicateInfo *streamingpb.ReplicatePChannelMeta) ReplicateStreamClient
|
||||
type CreateReplicateStreamClientFunc func(ctx context.Context, c cluster.MilvusClient, rm *meta.ReplicateChannel) ReplicateStreamClient
|
||||
|
||||
@ -22,27 +22,35 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/cockroachdb/errors"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus/internal/cdc/cluster"
|
||||
"github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"github.com/milvus-io/milvus/internal/cdc/util"
|
||||
"github.com/milvus-io/milvus/internal/util/streamingutil/service/contextutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/replicateutil"
|
||||
)
|
||||
|
||||
const pendingMessageQueueLength = 128
|
||||
const (
|
||||
// TODO: sheep, make these parameters configurable
|
||||
pendingMessageQueueLength = 128
|
||||
pendingMessageQueueMaxSize = 128 * 1024 * 1024
|
||||
)
|
||||
|
||||
var ErrReplicationRemoved = errors.New("replication removed")
|
||||
|
||||
// replicateStreamClient is the implementation of ReplicateStreamClient.
|
||||
type replicateStreamClient struct {
|
||||
replicateInfo *streamingpb.ReplicatePChannelMeta
|
||||
|
||||
clusterID string
|
||||
targetClient cluster.MilvusClient
|
||||
client milvuspb.MilvusService_CreateReplicateStreamClient
|
||||
channel *meta.ReplicateChannel
|
||||
pendingMessages MsgQueue
|
||||
metrics ReplicateMetrics
|
||||
|
||||
@ -52,34 +60,37 @@ type replicateStreamClient struct {
|
||||
}
|
||||
|
||||
// NewReplicateStreamClient creates a new ReplicateStreamClient.
|
||||
func NewReplicateStreamClient(ctx context.Context, replicateInfo *streamingpb.ReplicatePChannelMeta) ReplicateStreamClient {
|
||||
func NewReplicateStreamClient(ctx context.Context, c cluster.MilvusClient, channel *meta.ReplicateChannel) ReplicateStreamClient {
|
||||
ctx1, cancel := context.WithCancel(ctx)
|
||||
ctx1 = contextutil.WithClusterID(ctx1, replicateInfo.GetTargetCluster().GetClusterId())
|
||||
ctx1 = contextutil.WithClusterID(ctx1, channel.Value.GetTargetCluster().GetClusterId())
|
||||
|
||||
options := MsgQueueOptions{
|
||||
Capacity: pendingMessageQueueLength,
|
||||
MaxSize: pendingMessageQueueMaxSize,
|
||||
}
|
||||
pendingMessages := NewMsgQueue(options)
|
||||
rs := &replicateStreamClient{
|
||||
clusterID: paramtable.Get().CommonCfg.ClusterPrefix.GetValue(),
|
||||
replicateInfo: replicateInfo,
|
||||
pendingMessages: NewMsgQueue(pendingMessageQueueLength),
|
||||
metrics: NewReplicateMetrics(replicateInfo),
|
||||
targetClient: c,
|
||||
channel: channel,
|
||||
pendingMessages: pendingMessages,
|
||||
metrics: NewReplicateMetrics(channel.Value),
|
||||
ctx: ctx1,
|
||||
cancel: cancel,
|
||||
finishedCh: make(chan struct{}),
|
||||
}
|
||||
|
||||
rs.metrics.OnConnect()
|
||||
rs.metrics.OnInitiate()
|
||||
go rs.startInternal()
|
||||
return rs
|
||||
}
|
||||
|
||||
func (r *replicateStreamClient) startInternal() {
|
||||
logger := log.With(
|
||||
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
|
||||
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
|
||||
)
|
||||
|
||||
defer func() {
|
||||
r.metrics.OnDisconnect()
|
||||
logger.Info("replicate stream client closed")
|
||||
log.Info("replicate stream client closed",
|
||||
zap.String("key", r.channel.Key),
|
||||
zap.Int64("revision", r.channel.ModRevision))
|
||||
r.metrics.OnClose()
|
||||
close(r.finishedCh)
|
||||
}()
|
||||
|
||||
@ -87,52 +98,67 @@ func (r *replicateStreamClient) startInternal() {
|
||||
backoff.InitialInterval = 100 * time.Millisecond
|
||||
backoff.MaxInterval = 10 * time.Second
|
||||
backoff.MaxElapsedTime = 0
|
||||
backoff.Reset()
|
||||
|
||||
for {
|
||||
// Create a local context for this connection that can be canceled
|
||||
// when we need to stop the send/recv loops
|
||||
connCtx, connCancel := context.WithCancel(r.ctx)
|
||||
|
||||
milvusClient, err := resource.Resource().ClusterClient().CreateMilvusClient(connCtx, r.replicateInfo.GetTargetCluster())
|
||||
if err != nil {
|
||||
logger.Warn("create milvus client failed, retry...", zap.Error(err))
|
||||
time.Sleep(backoff.NextBackOff())
|
||||
continue
|
||||
}
|
||||
client, err := milvusClient.CreateReplicateStream(connCtx)
|
||||
if err != nil {
|
||||
logger.Warn("create milvus replicate stream failed, retry...", zap.Error(err))
|
||||
time.Sleep(backoff.NextBackOff())
|
||||
continue
|
||||
}
|
||||
logger.Info("replicate stream client service started")
|
||||
|
||||
// reset client and pending messages
|
||||
r.client = client
|
||||
r.pendingMessages.SeekToHead()
|
||||
|
||||
sendCh := r.startSendLoop(connCtx)
|
||||
recvCh := r.startRecvLoop(connCtx)
|
||||
|
||||
select {
|
||||
case <-r.ctx.Done():
|
||||
case <-sendCh:
|
||||
case <-recvCh:
|
||||
}
|
||||
|
||||
connCancel() // Cancel the connection context
|
||||
<-sendCh
|
||||
<-recvCh // wait for send/recv loops to exit
|
||||
|
||||
if r.ctx.Err() != nil {
|
||||
logger.Info("close replicate stream client by ctx done")
|
||||
restart := r.startReplicating(backoff)
|
||||
if !restart {
|
||||
return
|
||||
} else {
|
||||
logger.Warn("restart replicate stream client")
|
||||
r.metrics.OnDisconnect()
|
||||
time.Sleep(backoff.NextBackOff())
|
||||
}
|
||||
time.Sleep(backoff.NextBackOff())
|
||||
}
|
||||
}
|
||||
|
||||
func (r *replicateStreamClient) startReplicating(backoff backoff.BackOff) (needRestart bool) {
|
||||
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
|
||||
if r.ctx.Err() != nil {
|
||||
logger.Info("close replicate stream client due to ctx done")
|
||||
return false
|
||||
}
|
||||
|
||||
// Create a local context for this connection that can be canceled
|
||||
// when we need to stop the send/recv loops
|
||||
connCtx, connCancel := context.WithCancel(r.ctx)
|
||||
defer connCancel()
|
||||
|
||||
client, err := r.targetClient.CreateReplicateStream(connCtx)
|
||||
if err != nil {
|
||||
logger.Warn("create milvus replicate stream failed, retry...", zap.Error(err))
|
||||
return true
|
||||
}
|
||||
defer client.CloseSend()
|
||||
|
||||
logger.Info("replicate stream client service started")
|
||||
r.metrics.OnConnect()
|
||||
backoff.Reset()
|
||||
|
||||
// reset client and pending messages
|
||||
r.client = client
|
||||
r.pendingMessages.SeekToHead()
|
||||
|
||||
sendCh := r.startSendLoop(connCtx)
|
||||
recvCh := r.startRecvLoop(connCtx)
|
||||
|
||||
var chErr error
|
||||
select {
|
||||
case <-r.ctx.Done():
|
||||
case chErr = <-sendCh:
|
||||
case chErr = <-recvCh:
|
||||
}
|
||||
|
||||
connCancel() // Cancel the connection context
|
||||
<-sendCh
|
||||
<-recvCh // wait for send/recv loops to exit
|
||||
|
||||
if r.ctx.Err() != nil {
|
||||
logger.Info("close replicate stream client due to ctx done")
|
||||
return false
|
||||
} else if errors.Is(chErr, ErrReplicationRemoved) {
|
||||
logger.Info("close replicate stream client due to replication removed")
|
||||
return false
|
||||
} else {
|
||||
logger.Warn("restart replicate stream client due to unexpected error", zap.Error(chErr))
|
||||
r.metrics.OnDisconnect()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,42 +168,48 @@ func (r *replicateStreamClient) Replicate(msg message.ImmutableMessage) error {
|
||||
case <-r.ctx.Done():
|
||||
return nil
|
||||
default:
|
||||
// TODO: Should be done at streamingnode, but after move it into streamingnode, the metric need to be adjusted.
|
||||
if msg.MessageType().IsSelfControlled() {
|
||||
if r.pendingMessages.Len() == 0 {
|
||||
// if there is no pending messages, there's no lag between source and target.
|
||||
r.metrics.OnNoIncomingMessages()
|
||||
}
|
||||
return ErrReplicateIgnored
|
||||
}
|
||||
r.metrics.StartReplicate(msg)
|
||||
r.pendingMessages.Enqueue(r.ctx, msg)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (r *replicateStreamClient) startSendLoop(ctx context.Context) <-chan struct{} {
|
||||
ch := make(chan struct{})
|
||||
func (r *replicateStreamClient) startSendLoop(ctx context.Context) <-chan error {
|
||||
ch := make(chan error)
|
||||
go func() {
|
||||
_ = r.sendLoop(ctx)
|
||||
err := r.sendLoop(ctx)
|
||||
ch <- err
|
||||
close(ch)
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
func (r *replicateStreamClient) startRecvLoop(ctx context.Context) <-chan struct{} {
|
||||
ch := make(chan struct{})
|
||||
func (r *replicateStreamClient) startRecvLoop(ctx context.Context) <-chan error {
|
||||
ch := make(chan error)
|
||||
go func() {
|
||||
_ = r.recvLoop(ctx)
|
||||
err := r.recvLoop(ctx)
|
||||
ch <- err
|
||||
close(ch)
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
func (r *replicateStreamClient) sendLoop(ctx context.Context) (err error) {
|
||||
logger := log.With(
|
||||
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
|
||||
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
|
||||
)
|
||||
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
|
||||
defer func() {
|
||||
if err != nil {
|
||||
logger.Warn("send loop closed by unexpected error", zap.Error(err))
|
||||
} else {
|
||||
logger.Info("send loop closed")
|
||||
}
|
||||
r.client.CloseSend()
|
||||
}()
|
||||
for {
|
||||
select {
|
||||
@ -225,10 +257,7 @@ func (r *replicateStreamClient) sendLoop(ctx context.Context) (err error) {
|
||||
|
||||
func (r *replicateStreamClient) sendMessage(msg message.ImmutableMessage) (err error) {
|
||||
defer func() {
|
||||
logger := log.With(
|
||||
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
|
||||
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
|
||||
)
|
||||
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
|
||||
if err != nil {
|
||||
logger.Warn("send message failed", zap.Error(err), log.FieldMessage(msg))
|
||||
} else {
|
||||
@ -253,15 +282,12 @@ func (r *replicateStreamClient) sendMessage(msg message.ImmutableMessage) (err e
|
||||
}
|
||||
|
||||
func (r *replicateStreamClient) recvLoop(ctx context.Context) (err error) {
|
||||
logger := log.With(
|
||||
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
|
||||
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
|
||||
)
|
||||
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err != nil && !errors.Is(err, ErrReplicationRemoved) {
|
||||
logger.Warn("recv loop closed by unexpected error", zap.Error(err))
|
||||
} else {
|
||||
logger.Info("recv loop closed")
|
||||
logger.Info("recv loop closed", zap.Error(err))
|
||||
}
|
||||
}()
|
||||
for {
|
||||
@ -278,46 +304,56 @@ func (r *replicateStreamClient) recvLoop(ctx context.Context) (err error) {
|
||||
if lastConfirmedMessageInfo != nil {
|
||||
messages := r.pendingMessages.CleanupConfirmedMessages(lastConfirmedMessageInfo.GetConfirmedTimeTick())
|
||||
for _, msg := range messages {
|
||||
r.metrics.OnConfirmed(msg)
|
||||
if msg.MessageType() == message.MessageTypeAlterReplicateConfig {
|
||||
roleChanged := r.handleAlterReplicateConfigMessage(msg)
|
||||
if roleChanged {
|
||||
// Role changed, return and stop replicate.
|
||||
return nil
|
||||
replicationRemoved := r.handleAlterReplicateConfigMessage(msg)
|
||||
if replicationRemoved {
|
||||
// Replication removed, return and stop replicate.
|
||||
return ErrReplicationRemoved
|
||||
}
|
||||
}
|
||||
r.metrics.OnConfirmed(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *replicateStreamClient) handleAlterReplicateConfigMessage(msg message.ImmutableMessage) (roleChanged bool) {
|
||||
logger := log.With(
|
||||
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
|
||||
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
|
||||
)
|
||||
func (r *replicateStreamClient) handleAlterReplicateConfigMessage(msg message.ImmutableMessage) (replicationRemoved bool) {
|
||||
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
|
||||
logger.Info("handle AlterReplicateConfigMessage", log.FieldMessage(msg))
|
||||
prcMsg := message.MustAsImmutableAlterReplicateConfigMessageV2(msg)
|
||||
replicateConfig := prcMsg.Header().ReplicateConfiguration
|
||||
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
|
||||
currentCluster := replicateutil.MustNewConfigHelper(currentClusterID, replicateConfig).GetCurrentCluster()
|
||||
_, err := currentCluster.GetTargetChannel(r.replicateInfo.GetSourceChannelName(),
|
||||
r.replicateInfo.GetTargetCluster().GetClusterId())
|
||||
if err != nil {
|
||||
|
||||
replicationRemoved = util.IsReplicationRemovedByAlterReplicateConfigMessage(msg, r.channel.Value)
|
||||
if replicationRemoved {
|
||||
// Cannot find the target channel, it means that the `current->target` topology edge is removed,
|
||||
// so we need to remove the replicate pchannel and stop replicate.
|
||||
err := resource.Resource().ReplicationCatalog().RemoveReplicatePChannel(r.ctx, r.replicateInfo)
|
||||
etcdCli := resource.Resource().ETCD()
|
||||
ok, err := meta.RemoveReplicatePChannelWithRevision(r.ctx, etcdCli, r.channel.Key, r.channel.ModRevision)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to remove replicate pchannel: %v", err))
|
||||
logger.Warn("failed to remove replicate pchannel", zap.Error(err))
|
||||
// When performing delete operation on etcd, the context may be canceled by the delete event
|
||||
// in cdc controller and then return `context.Canceled` error.
|
||||
// Since the delete event is generated after the delete operation is committed in etcd,
|
||||
// the delete is guaranteed to have succeeded on the server side.
|
||||
// So we can ignore the context canceled error here.
|
||||
if !errors.Is(err, context.Canceled) {
|
||||
panic(fmt.Sprintf("failed to remove replicate pchannel: %v", err))
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
logger.Info("handle AlterReplicateConfigMessage done, replicate pchannel removed")
|
||||
} else {
|
||||
logger.Info("handle AlterReplicateConfigMessage done, revision not match, replicate pchannel not removed")
|
||||
}
|
||||
logger.Info("handle AlterReplicateConfigMessage done, replicate pchannel removed")
|
||||
return true
|
||||
}
|
||||
logger.Info("target channel found, skip handle AlterReplicateConfigMessage")
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *replicateStreamClient) BlockUntilFinish() {
|
||||
<-r.finishedCh
|
||||
}
|
||||
|
||||
func (r *replicateStreamClient) Close() {
|
||||
r.cancel()
|
||||
<-r.finishedCh
|
||||
|
||||
@ -19,6 +19,7 @@ package replicatestream
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -30,7 +31,7 @@ import (
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
milvuspb "github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus/internal/cdc/cluster"
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"github.com/milvus-io/milvus/internal/cdc/meta"
|
||||
"github.com/milvus-io/milvus/internal/distributed/streaming"
|
||||
"github.com/milvus-io/milvus/internal/mocks/distributed/mock_streaming"
|
||||
mock_message "github.com/milvus-io/milvus/pkg/v2/mocks/streaming/util/mock_message"
|
||||
@ -55,23 +56,22 @@ func TestReplicateStreamClient_Replicate(t *testing.T) {
|
||||
mockMilvusClient := cluster.NewMockMilvusClient(t)
|
||||
mockMilvusClient.EXPECT().CreateReplicateStream(mock.Anything).Return(mockStreamClient, nil)
|
||||
|
||||
mockClusterClient := cluster.NewMockClusterClient(t)
|
||||
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
|
||||
Return(mockMilvusClient, nil)
|
||||
|
||||
resource.InitForTest(t,
|
||||
resource.OptClusterClient(mockClusterClient),
|
||||
)
|
||||
|
||||
wal := mock_streaming.NewMockWALAccesser(t)
|
||||
streaming.SetWALForTest(wal)
|
||||
|
||||
replicateInfo := &streamingpb.ReplicatePChannelMeta{
|
||||
repMeta := &streamingpb.ReplicatePChannelMeta{
|
||||
SourceChannelName: "test-source-channel",
|
||||
TargetChannelName: "test-target-channel",
|
||||
TargetCluster: targetCluster,
|
||||
}
|
||||
replicateClient := NewReplicateStreamClient(ctx, replicateInfo)
|
||||
key := "test-replicate-key"
|
||||
channel := &meta.ReplicateChannel{
|
||||
Key: key,
|
||||
Value: repMeta,
|
||||
ModRevision: 0,
|
||||
}
|
||||
replicateClient := NewReplicateStreamClient(ctx, mockMilvusClient, channel)
|
||||
defer replicateClient.Close()
|
||||
|
||||
// Test Replicate method
|
||||
const msgCount = pendingMessageQueueLength * 10
|
||||
@ -101,8 +101,10 @@ func TestReplicateStreamClient_Replicate(t *testing.T) {
|
||||
mockStreamClient.ExpectRecv()
|
||||
}
|
||||
assert.Equal(t, msgCount, mockStreamClient.GetRecvCount())
|
||||
assert.Equal(t, 0, replicateClient.(*replicateStreamClient).pendingMessages.Len())
|
||||
replicateClient.Close()
|
||||
assert.Eventually(t, func() bool {
|
||||
return replicateClient.(*replicateStreamClient).pendingMessages.Len() == 0
|
||||
}, time.Second, 100*time.Millisecond)
|
||||
mockStreamClient.Close()
|
||||
}
|
||||
|
||||
func TestReplicateStreamClient_Replicate_ContextCanceled(t *testing.T) {
|
||||
@ -121,23 +123,21 @@ func TestReplicateStreamClient_Replicate_ContextCanceled(t *testing.T) {
|
||||
mockMilvusClient.EXPECT().CreateReplicateStream(mock.Anything).Return(mockStreamClient, nil).Maybe()
|
||||
mockMilvusClient.EXPECT().Close(mock.Anything).Return(nil).Maybe()
|
||||
|
||||
mockClusterClient := cluster.NewMockClusterClient(t)
|
||||
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
|
||||
Return(mockMilvusClient, nil).Maybe()
|
||||
|
||||
resource.InitForTest(t,
|
||||
resource.OptClusterClient(mockClusterClient),
|
||||
)
|
||||
|
||||
wal := mock_streaming.NewMockWALAccesser(t)
|
||||
streaming.SetWALForTest(wal)
|
||||
|
||||
replicateInfo := &streamingpb.ReplicatePChannelMeta{
|
||||
key := "test-replicate-key"
|
||||
repMeta := &streamingpb.ReplicatePChannelMeta{
|
||||
SourceChannelName: "test-source-channel",
|
||||
TargetChannelName: "test-target-channel",
|
||||
TargetCluster: targetCluster,
|
||||
}
|
||||
client := NewReplicateStreamClient(ctx, replicateInfo)
|
||||
channel := &meta.ReplicateChannel{
|
||||
Key: key,
|
||||
Value: repMeta,
|
||||
ModRevision: 0,
|
||||
}
|
||||
client := NewReplicateStreamClient(ctx, mockMilvusClient, channel)
|
||||
defer client.Close()
|
||||
|
||||
// Cancel context
|
||||
@ -172,24 +172,23 @@ func TestReplicateStreamClient_Reconnect(t *testing.T) {
|
||||
return mockStreamClient, nil
|
||||
}).Times(reconnectTimes) // expect to be called reconnectTimes times
|
||||
|
||||
mockClusterClient := cluster.NewMockClusterClient(t)
|
||||
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
|
||||
Return(mockMilvusClient, nil)
|
||||
|
||||
resource.InitForTest(t,
|
||||
resource.OptClusterClient(mockClusterClient),
|
||||
)
|
||||
|
||||
wal := mock_streaming.NewMockWALAccesser(t)
|
||||
streaming.SetWALForTest(wal)
|
||||
|
||||
// Create client which will start internal retry loop
|
||||
replicateInfo := &streamingpb.ReplicatePChannelMeta{
|
||||
key := "test-replicate-key"
|
||||
repMeta := &streamingpb.ReplicatePChannelMeta{
|
||||
SourceChannelName: "test-source-channel",
|
||||
TargetChannelName: "test-target-channel",
|
||||
TargetCluster: targetCluster,
|
||||
}
|
||||
replicateClient := NewReplicateStreamClient(ctx, replicateInfo)
|
||||
channel := &meta.ReplicateChannel{
|
||||
Key: key,
|
||||
Value: repMeta,
|
||||
ModRevision: 0,
|
||||
}
|
||||
replicateClient := NewReplicateStreamClient(ctx, mockMilvusClient, channel)
|
||||
defer replicateClient.Close()
|
||||
|
||||
// Replicate after reconnected
|
||||
const msgCount = 100
|
||||
@ -218,8 +217,10 @@ func TestReplicateStreamClient_Reconnect(t *testing.T) {
|
||||
mockStreamClient.ExpectRecv()
|
||||
}
|
||||
assert.Equal(t, msgCount, mockStreamClient.GetRecvCount())
|
||||
assert.Equal(t, 0, replicateClient.(*replicateStreamClient).pendingMessages.Len())
|
||||
replicateClient.Close()
|
||||
assert.Eventually(t, func() bool {
|
||||
return replicateClient.(*replicateStreamClient).pendingMessages.Len() == 0
|
||||
}, time.Second, 100*time.Millisecond)
|
||||
mockStreamClient.Close()
|
||||
}
|
||||
|
||||
// mockReplicateStreamClient implements the milvuspb.MilvusService_CreateReplicateStreamClient interface
|
||||
@ -234,7 +235,8 @@ type mockReplicateStreamClient struct {
|
||||
t *testing.T
|
||||
timeout time.Duration
|
||||
|
||||
closeCh chan struct{}
|
||||
closeOnce sync.Once
|
||||
closeCh chan struct{}
|
||||
}
|
||||
|
||||
func newMockReplicateStreamClient(t *testing.T) *mockReplicateStreamClient {
|
||||
@ -244,6 +246,7 @@ func newMockReplicateStreamClient(t *testing.T) *mockReplicateStreamClient {
|
||||
t: t,
|
||||
timeout: 10 * time.Second,
|
||||
closeCh: make(chan struct{}, 1),
|
||||
closeOnce: sync.Once{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,10 +316,18 @@ func (m *mockReplicateStreamClient) Trailer() metadata.MD {
|
||||
}
|
||||
|
||||
func (m *mockReplicateStreamClient) CloseSend() error {
|
||||
close(m.closeCh)
|
||||
m.closeOnce.Do(func() {
|
||||
close(m.closeCh)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockReplicateStreamClient) Context() context.Context {
|
||||
return context.Background()
|
||||
}
|
||||
|
||||
func (m *mockReplicateStreamClient) Close() {
|
||||
m.closeOnce.Do(func() {
|
||||
close(m.closeCh)
|
||||
})
|
||||
}
|
||||
|
||||
@ -19,12 +19,9 @@ package resource
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/cluster"
|
||||
"github.com/milvus-io/milvus/internal/cdc/controller"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/replication"
|
||||
"github.com/milvus-io/milvus/internal/metastore"
|
||||
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
|
||||
"github.com/milvus-io/milvus/pkg/v2/kv"
|
||||
)
|
||||
|
||||
var r *resourceImpl // singleton resource instance
|
||||
@ -32,10 +29,10 @@ var r *resourceImpl // singleton resource instance
|
||||
// optResourceInit is the option to initialize the resource.
|
||||
type optResourceInit func(r *resourceImpl)
|
||||
|
||||
// OptMetaKV provides the meta kv to the resource.
|
||||
func OptMetaKV(metaKV kv.MetaKv) optResourceInit {
|
||||
// OptETCD provides the etcd client to the resource.
|
||||
func OptETCD(etcd *clientv3.Client) optResourceInit {
|
||||
return func(r *resourceImpl) {
|
||||
r.metaKV = metaKV
|
||||
r.etcdClient = etcd
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,27 +43,6 @@ func OptReplicateManagerClient(replicateManagerClient replication.ReplicateManag
|
||||
}
|
||||
}
|
||||
|
||||
// OptReplicationCatalog provides the replication catalog to the resource.
|
||||
func OptReplicationCatalog(catalog metastore.ReplicationCatalog) optResourceInit {
|
||||
return func(r *resourceImpl) {
|
||||
r.catalog = catalog
|
||||
}
|
||||
}
|
||||
|
||||
// OptClusterClient provides the cluster client to the resource.
|
||||
func OptClusterClient(clusterClient cluster.ClusterClient) optResourceInit {
|
||||
return func(r *resourceImpl) {
|
||||
r.clusterClient = clusterClient
|
||||
}
|
||||
}
|
||||
|
||||
// OptController provides the controller to the resource.
|
||||
func OptController(controller controller.Controller) optResourceInit {
|
||||
return func(r *resourceImpl) {
|
||||
r.controller = controller
|
||||
}
|
||||
}
|
||||
|
||||
// Done finish all initialization of resources.
|
||||
func Init(opts ...optResourceInit) {
|
||||
newR := &resourceImpl{}
|
||||
@ -74,14 +50,8 @@ func Init(opts ...optResourceInit) {
|
||||
opt(newR)
|
||||
}
|
||||
|
||||
newR.catalog = streamingcoord.NewReplicationCatalog(newR.MetaKV())
|
||||
newR.clusterClient = cluster.NewClusterClient()
|
||||
|
||||
assertNotNil(newR.MetaKV())
|
||||
assertNotNil(newR.ReplicationCatalog())
|
||||
assertNotNil(newR.ClusterClient())
|
||||
assertNotNil(newR.ETCD())
|
||||
assertNotNil(newR.ReplicateManagerClient())
|
||||
assertNotNil(newR.Controller())
|
||||
r = newR
|
||||
}
|
||||
|
||||
@ -96,26 +66,13 @@ func Resource() *resourceImpl {
|
||||
// resourceImpl is a basic resource dependency for streamingnode server.
|
||||
// All utility on it is concurrent-safe and singleton.
|
||||
type resourceImpl struct {
|
||||
metaKV kv.MetaKv
|
||||
catalog metastore.ReplicationCatalog
|
||||
clusterClient cluster.ClusterClient
|
||||
etcdClient *clientv3.Client
|
||||
replicateManagerClient replication.ReplicateManagerClient
|
||||
controller controller.Controller
|
||||
}
|
||||
|
||||
// MetaKV returns the meta kv.
|
||||
func (r *resourceImpl) MetaKV() kv.MetaKv {
|
||||
return r.metaKV
|
||||
}
|
||||
|
||||
// ReplicationCatalog returns the replication catalog.
|
||||
func (r *resourceImpl) ReplicationCatalog() metastore.ReplicationCatalog {
|
||||
return r.catalog
|
||||
}
|
||||
|
||||
// ClusterClient returns the cluster client.
|
||||
func (r *resourceImpl) ClusterClient() cluster.ClusterClient {
|
||||
return r.clusterClient
|
||||
// ETCD returns the etcd client.
|
||||
func (r *resourceImpl) ETCD() *clientv3.Client {
|
||||
return r.etcdClient
|
||||
}
|
||||
|
||||
// ReplicateManagerClient returns the replicate manager client.
|
||||
@ -123,11 +80,6 @@ func (r *resourceImpl) ReplicateManagerClient() replication.ReplicateManagerClie
|
||||
return r.replicateManagerClient
|
||||
}
|
||||
|
||||
// Controller returns the controller.
|
||||
func (r *resourceImpl) Controller() controller.Controller {
|
||||
return r.controller
|
||||
}
|
||||
|
||||
// assertNotNil panics if the resource is nil.
|
||||
func assertNotNil(v interface{}) {
|
||||
iv := reflect.ValueOf(v)
|
||||
|
||||
@ -6,11 +6,9 @@ package resource
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/cluster"
|
||||
"github.com/milvus-io/milvus/internal/cdc/controller"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/replication"
|
||||
"github.com/milvus-io/milvus/internal/mocks/mock_metastore"
|
||||
"github.com/milvus-io/milvus/pkg/v2/mocks/mock_kv"
|
||||
)
|
||||
|
||||
// InitForTest initializes the singleton of resources for test.
|
||||
@ -19,19 +17,10 @@ func InitForTest(t *testing.T, opts ...optResourceInit) {
|
||||
for _, opt := range opts {
|
||||
opt(r)
|
||||
}
|
||||
if r.metaKV == nil {
|
||||
r.metaKV = mock_kv.NewMockMetaKv(t)
|
||||
}
|
||||
if r.catalog == nil {
|
||||
r.catalog = mock_metastore.NewMockReplicationCatalog(t)
|
||||
}
|
||||
if r.clusterClient == nil {
|
||||
r.clusterClient = cluster.NewMockClusterClient(t)
|
||||
if r.etcdClient == nil {
|
||||
r.etcdClient = &clientv3.Client{}
|
||||
}
|
||||
if r.replicateManagerClient == nil {
|
||||
r.replicateManagerClient = replication.NewMockReplicateManagerClient(t)
|
||||
}
|
||||
if r.controller == nil {
|
||||
r.controller = controller.NewMockController(t)
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,37 +19,39 @@ package cdc
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/resource"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/cdc/controller"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
)
|
||||
|
||||
type CDCServer struct {
|
||||
ctx context.Context
|
||||
ctx context.Context
|
||||
controller controller.Controller
|
||||
}
|
||||
|
||||
// NewCDCServer will return a CDCServer.
|
||||
func NewCDCServer(ctx context.Context) *CDCServer {
|
||||
return &CDCServer{
|
||||
ctx: ctx,
|
||||
ctx: ctx,
|
||||
controller: controller.NewController(),
|
||||
}
|
||||
}
|
||||
|
||||
// Init initializes the CDCServer.
|
||||
func (svr *CDCServer) Init() error {
|
||||
log.Ctx(svr.ctx).Info("CDCServer init successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start starts CDCServer.
|
||||
func (svr *CDCServer) Start() error {
|
||||
resource.Resource().Controller().Start()
|
||||
err := svr.controller.Start()
|
||||
if err != nil {
|
||||
log.Ctx(svr.ctx).Error("start CDC controller failed", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
log.Ctx(svr.ctx).Info("CDCServer start successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop stops CDCServer.
|
||||
func (svr *CDCServer) Stop() error {
|
||||
resource.Resource().Controller().Stop()
|
||||
svr.controller.Stop()
|
||||
log.Ctx(svr.ctx).Info("CDCServer stop successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
23
internal/cdc/util/util.go
Normal file
23
internal/cdc/util/util.go
Normal file
@ -0,0 +1,23 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
|
||||
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/replicateutil"
|
||||
)
|
||||
|
||||
func IsReplicationRemovedByAlterReplicateConfigMessage(msg message.ImmutableMessage, replicateInfo *streamingpb.ReplicatePChannelMeta) (replicationRemoved bool) {
|
||||
prcMsg := message.MustAsImmutableAlterReplicateConfigMessageV2(msg)
|
||||
replicateConfig := prcMsg.Header().ReplicateConfiguration
|
||||
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
|
||||
currentCluster := replicateutil.MustNewConfigHelper(currentClusterID, replicateConfig).GetCurrentCluster()
|
||||
_, err := currentCluster.GetTargetChannel(replicateInfo.GetSourceChannelName(),
|
||||
replicateInfo.GetTargetCluster().GetClusterId())
|
||||
if err != nil {
|
||||
// Cannot find the target channel, it means that the `current->target` topology edge is removed,
|
||||
// it means that the replication is removed.
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -113,14 +113,14 @@ func (s *mixCoordImpl) Register() error {
|
||||
afterRegister := func() {
|
||||
metrics.NumNodes.WithLabelValues(fmt.Sprint(paramtable.GetNodeID()), typeutil.MixCoordRole).Inc()
|
||||
log.Info("MixCoord Register Finished")
|
||||
s.session.LivenessCheck(s.ctx, func() {
|
||||
log.Error("MixCoord disconnected from etcd, process will exit", zap.Int64("serverID", s.session.GetServerID()))
|
||||
os.Exit(1)
|
||||
})
|
||||
}
|
||||
if s.enableActiveStandBy {
|
||||
go func() {
|
||||
if err := s.session.ProcessActiveStandBy(s.activateFunc); err != nil {
|
||||
if s.ctx.Err() == context.Canceled {
|
||||
log.Info("standby process canceled due to server shutdown")
|
||||
return
|
||||
}
|
||||
log.Error("failed to activate standby server", zap.Error(err))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/pingcap/log"
|
||||
"github.com/samber/lo"
|
||||
"go.uber.org/zap"
|
||||
|
||||
@ -18,6 +17,7 @@ import (
|
||||
"github.com/milvus-io/milvus/internal/distributed/streaming"
|
||||
management "github.com/milvus-io/milvus/internal/http"
|
||||
"github.com/milvus-io/milvus/internal/json"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
|
||||
"github.com/milvus-io/milvus/pkg/v2/proto/querypb"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/commonpbutil"
|
||||
|
||||
@ -67,6 +67,7 @@ type StreamingNodeManager struct {
|
||||
cond *syncutil.ContextCond
|
||||
latestAssignments map[string]types.PChannelInfoAssigned // The latest assignments info got from streaming coord balance module.
|
||||
nodeChangedNotifier *syncutil.VersionedNotifier // used to notify that node in streaming node manager has been changed.
|
||||
previousNodeIDs typeutil.UniqueSet // used to store the previous node ids.
|
||||
}
|
||||
|
||||
// GetBalancer returns the balancer of the streaming node manager.
|
||||
@ -78,6 +79,15 @@ func (s *StreamingNodeManager) GetBalancer() balancer.Balancer {
|
||||
return b
|
||||
}
|
||||
|
||||
// AllocVirtualChannels allocates virtual channels for a collection.
|
||||
func (s *StreamingNodeManager) AllocVirtualChannels(ctx context.Context, param balancer.AllocVChannelParam) ([]string, error) {
|
||||
balancer, err := balance.GetWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return balancer.AllocVirtualChannels(ctx, param)
|
||||
}
|
||||
|
||||
// GetLatestWALLocated returns the server id of the node that the wal of the vChannel is located.
|
||||
// Return -1 and error if the vchannel is not found or context is canceled.
|
||||
func (s *StreamingNodeManager) GetLatestWALLocated(ctx context.Context, vchannel string) (int64, error) {
|
||||
@ -142,12 +152,15 @@ func (s *StreamingNodeManager) GetStreamingQueryNodeIDs() typeutil.UniqueSet {
|
||||
}
|
||||
streamingNodes, err := balancer.GetAllStreamingNodes(context.Background())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
// when the streaming coord is on shutdown, the balancer will return an error,
|
||||
// causing panic, so we need to return the previous node ids.
|
||||
return s.previousNodeIDs
|
||||
}
|
||||
streamingNodeIDs := typeutil.NewUniqueSet()
|
||||
for _, streamingNode := range streamingNodes {
|
||||
streamingNodeIDs.Insert(streamingNode.ServerID)
|
||||
}
|
||||
s.previousNodeIDs = streamingNodeIDs
|
||||
return streamingNodeIDs
|
||||
}
|
||||
|
||||
|
||||
@ -189,6 +189,7 @@ test_run() {
|
||||
std::string root_path = "/tmp/test-kmeans-clustering/";
|
||||
auto storage_config = gen_local_storage_config(root_path);
|
||||
auto cm = storage::CreateChunkManager(storage_config);
|
||||
auto fs = storage::InitArrowFileSystem(storage_config);
|
||||
|
||||
std::vector<T> data_gen(nb * dim);
|
||||
for (int64_t i = 0; i < nb * dim; ++i) {
|
||||
@ -216,7 +217,7 @@ test_run() {
|
||||
auto log_path = get_binlog_path(0);
|
||||
auto cm_w = ChunkManagerWrapper(cm);
|
||||
cm_w.Write(log_path, serialized_bytes.data(), serialized_bytes.size());
|
||||
storage::FileManagerContext ctx(field_meta, index_meta, cm);
|
||||
storage::FileManagerContext ctx(field_meta, index_meta, cm, fs);
|
||||
|
||||
std::map<int64_t, std::vector<std::string>> remote_files;
|
||||
std::map<int64_t, int64_t> num_rows;
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "types.h"
|
||||
#include "index/Utils.h"
|
||||
#include "index/Meta.h"
|
||||
#include "storage/StorageV2FSCache.h"
|
||||
#include "storage/Util.h"
|
||||
#include "pb/clustering.pb.h"
|
||||
#include "monitor/scope_metric.h"
|
||||
@ -48,6 +49,8 @@ get_storage_config(const milvus::proto::clustering::StorageConfig& config) {
|
||||
storage_config.requestTimeoutMs = config.request_timeout_ms();
|
||||
storage_config.gcp_credential_json =
|
||||
std::string(config.gcpcredentialjson());
|
||||
storage_config.max_connections = config.max_connections();
|
||||
|
||||
return storage_config;
|
||||
}
|
||||
|
||||
@ -78,9 +81,30 @@ Analyze(CAnalyze* res_analyze,
|
||||
get_storage_config(analyze_info->storage_config());
|
||||
auto chunk_manager =
|
||||
milvus::storage::CreateChunkManager(storage_config);
|
||||
auto fs = milvus::storage::StorageV2FSCache::Instance().Get({
|
||||
storage_config.address,
|
||||
storage_config.bucket_name,
|
||||
storage_config.access_key_id,
|
||||
storage_config.access_key_value,
|
||||
storage_config.root_path,
|
||||
storage_config.storage_type,
|
||||
storage_config.cloud_provider,
|
||||
storage_config.iam_endpoint,
|
||||
storage_config.log_level,
|
||||
storage_config.region,
|
||||
storage_config.useSSL,
|
||||
storage_config.sslCACert,
|
||||
storage_config.useIAM,
|
||||
storage_config.useVirtualHost,
|
||||
storage_config.requestTimeoutMs,
|
||||
false,
|
||||
storage_config.gcp_credential_json,
|
||||
false,
|
||||
storage_config.max_connections,
|
||||
});
|
||||
|
||||
milvus::storage::FileManagerContext fileManagerContext(
|
||||
field_meta, index_meta, chunk_manager);
|
||||
field_meta, index_meta, chunk_manager, fs);
|
||||
|
||||
if (field_type != DataType::VECTOR_FLOAT) {
|
||||
throw SegcoreError(
|
||||
|
||||
@ -296,11 +296,12 @@ class Array {
|
||||
return offsets_ptr_.get();
|
||||
}
|
||||
|
||||
ScalarFieldProto
|
||||
output_data() const {
|
||||
ScalarFieldProto data_array;
|
||||
void
|
||||
output_data(ScalarFieldProto& data_array) const {
|
||||
switch (element_type_) {
|
||||
case DataType::BOOL: {
|
||||
data_array.mutable_bool_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<bool>(j);
|
||||
data_array.mutable_bool_data()->add_data(element);
|
||||
@ -310,6 +311,7 @@ class Array {
|
||||
case DataType::INT8:
|
||||
case DataType::INT16:
|
||||
case DataType::INT32: {
|
||||
data_array.mutable_int_data()->mutable_data()->Reserve(length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<int>(j);
|
||||
data_array.mutable_int_data()->add_data(element);
|
||||
@ -317,6 +319,8 @@ class Array {
|
||||
break;
|
||||
}
|
||||
case DataType::INT64: {
|
||||
data_array.mutable_long_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<int64_t>(j);
|
||||
data_array.mutable_long_data()->add_data(element);
|
||||
@ -325,13 +329,18 @@ class Array {
|
||||
}
|
||||
case DataType::STRING:
|
||||
case DataType::VARCHAR: {
|
||||
data_array.mutable_string_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<std::string>(j);
|
||||
data_array.mutable_string_data()->add_data(element);
|
||||
auto element = get_data<std::string_view>(j);
|
||||
data_array.mutable_string_data()->add_data(element.data(),
|
||||
element.size());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::FLOAT: {
|
||||
data_array.mutable_float_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<float>(j);
|
||||
data_array.mutable_float_data()->add_data(element);
|
||||
@ -339,6 +348,8 @@ class Array {
|
||||
break;
|
||||
}
|
||||
case DataType::DOUBLE: {
|
||||
data_array.mutable_double_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<double>(j);
|
||||
data_array.mutable_double_data()->add_data(element);
|
||||
@ -346,9 +357,12 @@ class Array {
|
||||
break;
|
||||
}
|
||||
case DataType::GEOMETRY: {
|
||||
data_array.mutable_geometry_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<std::string>(j);
|
||||
data_array.mutable_geometry_data()->add_data(element);
|
||||
auto element = get_data<std::string_view>(j);
|
||||
data_array.mutable_geometry_data()->add_data(
|
||||
element.data(), element.size());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -356,6 +370,12 @@ class Array {
|
||||
// empty array
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScalarFieldProto
|
||||
output_data() const {
|
||||
ScalarFieldProto data_array;
|
||||
output_data(data_array);
|
||||
return data_array;
|
||||
}
|
||||
|
||||
@ -541,11 +561,12 @@ class ArrayView {
|
||||
return reinterpret_cast<T*>(data_)[index];
|
||||
}
|
||||
|
||||
ScalarFieldProto
|
||||
output_data() const {
|
||||
ScalarFieldProto data_array;
|
||||
void
|
||||
output_data(ScalarFieldProto& data_array) const {
|
||||
switch (element_type_) {
|
||||
case DataType::BOOL: {
|
||||
data_array.mutable_bool_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<bool>(j);
|
||||
data_array.mutable_bool_data()->add_data(element);
|
||||
@ -555,6 +576,7 @@ class ArrayView {
|
||||
case DataType::INT8:
|
||||
case DataType::INT16:
|
||||
case DataType::INT32: {
|
||||
data_array.mutable_int_data()->mutable_data()->Reserve(length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<int>(j);
|
||||
data_array.mutable_int_data()->add_data(element);
|
||||
@ -562,6 +584,8 @@ class ArrayView {
|
||||
break;
|
||||
}
|
||||
case DataType::INT64: {
|
||||
data_array.mutable_long_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<int64_t>(j);
|
||||
data_array.mutable_long_data()->add_data(element);
|
||||
@ -570,13 +594,18 @@ class ArrayView {
|
||||
}
|
||||
case DataType::STRING:
|
||||
case DataType::VARCHAR: {
|
||||
data_array.mutable_string_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<std::string>(j);
|
||||
data_array.mutable_string_data()->add_data(element);
|
||||
auto element = get_data<std::string_view>(j);
|
||||
data_array.mutable_string_data()->add_data(element.data(),
|
||||
element.size());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::FLOAT: {
|
||||
data_array.mutable_float_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<float>(j);
|
||||
data_array.mutable_float_data()->add_data(element);
|
||||
@ -584,6 +613,8 @@ class ArrayView {
|
||||
break;
|
||||
}
|
||||
case DataType::DOUBLE: {
|
||||
data_array.mutable_double_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<double>(j);
|
||||
data_array.mutable_double_data()->add_data(element);
|
||||
@ -591,9 +622,12 @@ class ArrayView {
|
||||
break;
|
||||
}
|
||||
case DataType::GEOMETRY: {
|
||||
data_array.mutable_geometry_data()->mutable_data()->Reserve(
|
||||
length_);
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<std::string>(j);
|
||||
data_array.mutable_geometry_data()->add_data(element);
|
||||
auto element = get_data<std::string_view>(j);
|
||||
data_array.mutable_geometry_data()->add_data(
|
||||
element.data(), element.size());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -601,6 +635,12 @@ class ArrayView {
|
||||
// empty array
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScalarFieldProto
|
||||
output_data() const {
|
||||
ScalarFieldProto data_array;
|
||||
output_data(data_array);
|
||||
return data_array;
|
||||
}
|
||||
|
||||
|
||||
@ -38,6 +38,39 @@ namespace milvus {
|
||||
constexpr uint64_t MMAP_STRING_PADDING = 1;
|
||||
constexpr uint64_t MMAP_GEOMETRY_PADDING = 1;
|
||||
constexpr uint64_t MMAP_ARRAY_PADDING = 1;
|
||||
|
||||
// Shared mmap region manager for group chunks
|
||||
class ChunkMmapGuard {
|
||||
public:
|
||||
ChunkMmapGuard(char* mmap_ptr, size_t mmap_size, std::string file_path)
|
||||
: mmap_ptr_(mmap_ptr), mmap_size_(mmap_size), file_path_(file_path) {
|
||||
}
|
||||
|
||||
~ChunkMmapGuard() {
|
||||
if (mmap_ptr_ != nullptr) {
|
||||
munmap(mmap_ptr_, mmap_size_);
|
||||
}
|
||||
if (!file_path_.empty()) {
|
||||
unlink(file_path_.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
get_ptr() const {
|
||||
return mmap_ptr_;
|
||||
}
|
||||
|
||||
bool
|
||||
is_file_backed() const {
|
||||
return !file_path_.empty();
|
||||
}
|
||||
|
||||
private:
|
||||
char* mmap_ptr_;
|
||||
size_t mmap_size_;
|
||||
const std::string file_path_;
|
||||
};
|
||||
|
||||
class Chunk {
|
||||
public:
|
||||
Chunk() = default;
|
||||
@ -45,12 +78,12 @@ class Chunk {
|
||||
char* data,
|
||||
uint64_t size,
|
||||
bool nullable,
|
||||
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
|
||||
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
|
||||
: data_(data),
|
||||
row_nums_(row_nums),
|
||||
size_(size),
|
||||
nullable_(nullable),
|
||||
mmap_file_raii_(std::move(mmap_file_raii)) {
|
||||
chunk_mmap_guard_(chunk_mmap_guard) {
|
||||
if (nullable) {
|
||||
valid_.reserve(row_nums);
|
||||
for (int i = 0; i < row_nums; i++) {
|
||||
@ -59,7 +92,7 @@ class Chunk {
|
||||
}
|
||||
}
|
||||
virtual ~Chunk() {
|
||||
munmap(data_, size_);
|
||||
// The ChunkMmapGuard will handle the unmapping and unlinking of the file if it is file backed
|
||||
}
|
||||
|
||||
uint64_t
|
||||
@ -69,7 +102,7 @@ class Chunk {
|
||||
|
||||
cachinglayer::ResourceUsage
|
||||
CellByteSize() const {
|
||||
if (mmap_file_raii_) {
|
||||
if (chunk_mmap_guard_ && chunk_mmap_guard_->is_file_backed()) {
|
||||
return cachinglayer::ResourceUsage(0, static_cast<int64_t>(size_));
|
||||
}
|
||||
return cachinglayer::ResourceUsage(static_cast<int64_t>(size_), 0);
|
||||
@ -109,7 +142,7 @@ class Chunk {
|
||||
FixedVector<bool>
|
||||
valid_; // parse null bitmap to valid_ to be compatible with SpanBase
|
||||
|
||||
std::unique_ptr<MmapFileRAII> mmap_file_raii_;
|
||||
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard_{nullptr};
|
||||
};
|
||||
|
||||
// for fixed size data, includes fixed size array
|
||||
@ -121,8 +154,8 @@ class FixedWidthChunk : public Chunk {
|
||||
uint64_t size,
|
||||
uint64_t element_size,
|
||||
bool nullable,
|
||||
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
|
||||
: Chunk(row_nums, data, size, nullable, std::move(mmap_file_raii)),
|
||||
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
|
||||
: Chunk(row_nums, data, size, nullable, chunk_mmap_guard),
|
||||
dim_(dim),
|
||||
element_size_(element_size) {
|
||||
auto null_bitmap_bytes_num = nullable_ ? (row_nums_ + 7) / 8 : 0;
|
||||
@ -181,8 +214,8 @@ class StringChunk : public Chunk {
|
||||
char* data,
|
||||
uint64_t size,
|
||||
bool nullable,
|
||||
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
|
||||
: Chunk(row_nums, data, size, nullable, std::move(mmap_file_raii)) {
|
||||
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
|
||||
: Chunk(row_nums, data, size, nullable, chunk_mmap_guard) {
|
||||
auto null_bitmap_bytes_num = nullable_ ? (row_nums_ + 7) / 8 : 0;
|
||||
offsets_ = reinterpret_cast<uint32_t*>(data + null_bitmap_bytes_num);
|
||||
}
|
||||
@ -314,8 +347,8 @@ class ArrayChunk : public Chunk {
|
||||
uint64_t size,
|
||||
milvus::DataType element_type,
|
||||
bool nullable,
|
||||
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
|
||||
: Chunk(row_nums, data, size, nullable, std::move(mmap_file_raii)),
|
||||
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
|
||||
: Chunk(row_nums, data, size, nullable, chunk_mmap_guard),
|
||||
element_type_(element_type) {
|
||||
auto null_bitmap_bytes_num = 0;
|
||||
if (nullable) {
|
||||
@ -431,18 +464,18 @@ class VectorArrayChunk : public Chunk {
|
||||
char* data,
|
||||
uint64_t size,
|
||||
milvus::DataType element_type,
|
||||
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
|
||||
: Chunk(row_nums, data, size, false, std::move(mmap_file_raii)),
|
||||
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
|
||||
: Chunk(row_nums, data, size, false, chunk_mmap_guard),
|
||||
dim_(dim),
|
||||
element_type_(element_type) {
|
||||
offsets_lens_ = reinterpret_cast<uint32_t*>(data);
|
||||
|
||||
auto offset = 0;
|
||||
lims_.reserve(row_nums_ + 1);
|
||||
lims_.push_back(offset);
|
||||
offsets_.reserve(row_nums_ + 1);
|
||||
offsets_.push_back(offset);
|
||||
for (int64_t i = 0; i < row_nums_; i++) {
|
||||
offset += offsets_lens_[i * 2 + 1];
|
||||
lims_.push_back(offset);
|
||||
offsets_.push_back(offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,30 +540,27 @@ class VectorArrayChunk : public Chunk {
|
||||
}
|
||||
|
||||
const size_t*
|
||||
Lims() const {
|
||||
return lims_.data();
|
||||
Offsets() const {
|
||||
return offsets_.data();
|
||||
}
|
||||
|
||||
private:
|
||||
int64_t dim_;
|
||||
uint32_t* offsets_lens_;
|
||||
milvus::DataType element_type_;
|
||||
// The name 'Lims' is consistent with knowhere::DataSet::SetLims which describes the number of vectors
|
||||
// in each vector array (embedding list). This is needed as vectors are flattened in the chunk.
|
||||
std::vector<size_t> lims_;
|
||||
std::vector<size_t> offsets_;
|
||||
};
|
||||
|
||||
class SparseFloatVectorChunk : public Chunk {
|
||||
public:
|
||||
SparseFloatVectorChunk(
|
||||
int32_t row_nums,
|
||||
char* data,
|
||||
uint64_t size,
|
||||
bool nullable,
|
||||
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
|
||||
: Chunk(row_nums, data, size, nullable, std::move(mmap_file_raii)) {
|
||||
SparseFloatVectorChunk(int32_t row_nums,
|
||||
char* data,
|
||||
uint64_t size,
|
||||
bool nullable,
|
||||
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
|
||||
: Chunk(row_nums, data, size, nullable, chunk_mmap_guard) {
|
||||
vec_.resize(row_nums);
|
||||
auto null_bitmap_bytes_num = (row_nums + 7) / 8;
|
||||
auto null_bitmap_bytes_num = nullable ? (row_nums + 7) / 8 : 0;
|
||||
auto offsets_ptr =
|
||||
reinterpret_cast<uint64_t*>(data + null_bitmap_bytes_num);
|
||||
for (int i = 0; i < row_nums; i++) {
|
||||
|
||||
@ -27,9 +27,9 @@ MemChunkTarget::write(const void* data, size_t size) {
|
||||
size_ += size;
|
||||
}
|
||||
|
||||
std::pair<char*, size_t>
|
||||
MemChunkTarget::get() {
|
||||
return {data_, cap_};
|
||||
char*
|
||||
MemChunkTarget::release() {
|
||||
return data_;
|
||||
}
|
||||
|
||||
size_t
|
||||
@ -39,6 +39,11 @@ MemChunkTarget::tell() {
|
||||
|
||||
void
|
||||
MmapChunkTarget::flush() {
|
||||
if (cap_ > size_) {
|
||||
std::string padding(cap_ - size_, 0);
|
||||
file_writer_->Write(padding.data(), cap_ - size_);
|
||||
size_ = cap_;
|
||||
}
|
||||
file_writer_->Finish();
|
||||
}
|
||||
|
||||
@ -48,17 +53,17 @@ MmapChunkTarget::write(const void* data, size_t size) {
|
||||
size_ += size;
|
||||
}
|
||||
|
||||
std::pair<char*, size_t>
|
||||
MmapChunkTarget::get() {
|
||||
char*
|
||||
MmapChunkTarget::release() {
|
||||
flush();
|
||||
|
||||
auto file = File::Open(file_path_, O_RDWR);
|
||||
auto m = mmap(nullptr, size_, PROT_READ, MAP_SHARED, file.Descriptor(), 0);
|
||||
auto m = mmap(nullptr, cap_, PROT_READ, MAP_SHARED, file.Descriptor(), 0);
|
||||
AssertInfo(m != MAP_FAILED,
|
||||
"failed to map: {}, map_size={}",
|
||||
strerror(errno),
|
||||
size_);
|
||||
return {static_cast<char*>(m), size_};
|
||||
cap_);
|
||||
return static_cast<char*>(m);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@ -23,46 +23,66 @@
|
||||
namespace milvus {
|
||||
class ChunkTarget {
|
||||
public:
|
||||
virtual void
|
||||
write(const void* data, size_t size) = 0;
|
||||
|
||||
virtual std::pair<char*, size_t>
|
||||
get() = 0;
|
||||
static constexpr size_t ALIGNED_SIZE = 4096; // 4KB
|
||||
|
||||
virtual ~ChunkTarget() = default;
|
||||
|
||||
/**
|
||||
* @brief write data to the target at the current position
|
||||
* @param data the data to write
|
||||
* @param size the size of the data to write
|
||||
*/
|
||||
virtual void
|
||||
write(const void* data, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* @brief release the data pointer to the caller
|
||||
* @note no write() should be called after release()
|
||||
* @return the data pointer
|
||||
*/
|
||||
virtual char*
|
||||
release() = 0;
|
||||
|
||||
/**
|
||||
* @brief get the current position of the target
|
||||
* @return the current position
|
||||
*/
|
||||
virtual size_t
|
||||
tell() = 0;
|
||||
};
|
||||
|
||||
class MmapChunkTarget : public ChunkTarget {
|
||||
public:
|
||||
explicit MmapChunkTarget(std::string file_path)
|
||||
: file_path_(std::move(file_path)) {
|
||||
file_writer_ = std::make_unique<storage::FileWriter>(file_path_);
|
||||
explicit MmapChunkTarget(std::string file_path,
|
||||
size_t cap,
|
||||
storage::io::Priority io_prio)
|
||||
: file_path_(std::move(file_path)), cap_(cap) {
|
||||
file_writer_ =
|
||||
std::make_unique<storage::FileWriter>(file_path_, io_prio);
|
||||
}
|
||||
|
||||
void
|
||||
flush();
|
||||
|
||||
void
|
||||
write(const void* data, size_t size) override;
|
||||
|
||||
std::pair<char*, size_t>
|
||||
get() override;
|
||||
char*
|
||||
release() override;
|
||||
|
||||
size_t
|
||||
tell() override;
|
||||
|
||||
private:
|
||||
void
|
||||
flush();
|
||||
|
||||
std::unique_ptr<storage::FileWriter> file_writer_{nullptr};
|
||||
std::string file_path_{};
|
||||
size_t size_ = 0;
|
||||
size_t cap_{0};
|
||||
size_t size_{0};
|
||||
};
|
||||
|
||||
class MemChunkTarget : public ChunkTarget {
|
||||
public:
|
||||
MemChunkTarget(size_t cap) : cap_(cap) {
|
||||
explicit MemChunkTarget(size_t cap) : cap_(cap) {
|
||||
auto m = mmap(nullptr,
|
||||
cap,
|
||||
PROT_READ | PROT_WRITE,
|
||||
@ -79,8 +99,8 @@ class MemChunkTarget : public ChunkTarget {
|
||||
void
|
||||
write(const void* data, size_t size) override;
|
||||
|
||||
std::pair<char*, size_t>
|
||||
get() override;
|
||||
char*
|
||||
release() override;
|
||||
|
||||
size_t
|
||||
tell() override;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,6 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "arrow/array/array_primitive.h"
|
||||
@ -21,37 +20,26 @@
|
||||
#include "common/ChunkTarget.h"
|
||||
#include "arrow/record_batch.h"
|
||||
#include "common/Chunk.h"
|
||||
#include "common/EasyAssert.h"
|
||||
#include "common/FieldDataInterface.h"
|
||||
|
||||
#include "storage/FileWriter.h"
|
||||
|
||||
#include "common/Geometry.h"
|
||||
namespace milvus {
|
||||
class ChunkWriterBase {
|
||||
public:
|
||||
explicit ChunkWriterBase(bool nullable) : nullable_(nullable) {
|
||||
}
|
||||
|
||||
ChunkWriterBase(std::string file_path, bool nullable)
|
||||
: file_path_(std::move(file_path)), nullable_(nullable) {
|
||||
}
|
||||
virtual std::pair<size_t, size_t>
|
||||
calculate_size(const arrow::ArrayVector& data) = 0;
|
||||
|
||||
virtual void
|
||||
write(const arrow::ArrayVector& data) = 0;
|
||||
|
||||
virtual std::unique_ptr<Chunk>
|
||||
finish() = 0;
|
||||
|
||||
std::pair<char*, size_t>
|
||||
get_data() {
|
||||
return target_->get();
|
||||
}
|
||||
write_to_target(const arrow::ArrayVector& array_vec,
|
||||
const std::shared_ptr<ChunkTarget>& target) = 0;
|
||||
|
||||
protected:
|
||||
void
|
||||
write_null_bit_maps(
|
||||
const std::vector<std::tuple<const uint8_t*, int64_t, int64_t>>&
|
||||
null_bitmaps) {
|
||||
null_bitmaps,
|
||||
const std::shared_ptr<ChunkTarget>& target) {
|
||||
if (nullable_) {
|
||||
// merge all null bitmaps in case of multiple chunk null bitmap dislocation
|
||||
// say [0xFF, 0x00] with size [7, 8] cannot be treated as [0xFF, 0x00] after merged but
|
||||
@ -81,15 +69,13 @@ class ChunkWriterBase {
|
||||
}
|
||||
size_total_bit += size_bits;
|
||||
}
|
||||
target_->write(merged_null_bitmap.data(), (size_total_bit + 7) / 8);
|
||||
target->write(merged_null_bitmap.data(), (size_total_bit + 7) / 8);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
int row_nums_ = 0;
|
||||
std::string file_path_{""};
|
||||
size_t row_nums_ = 0;
|
||||
bool nullable_ = false;
|
||||
std::shared_ptr<ChunkTarget> target_;
|
||||
};
|
||||
|
||||
template <typename ArrowType, typename T>
|
||||
@ -98,30 +84,25 @@ class ChunkWriter final : public ChunkWriterBase {
|
||||
ChunkWriter(int dim, bool nullable) : ChunkWriterBase(nullable), dim_(dim) {
|
||||
}
|
||||
|
||||
ChunkWriter(int dim, std::string file_path, bool nullable)
|
||||
: ChunkWriterBase(std::move(file_path), nullable), dim_(dim){};
|
||||
|
||||
void
|
||||
write(const arrow::ArrayVector& array_vec) override {
|
||||
auto size = 0;
|
||||
auto row_nums = 0;
|
||||
|
||||
std::pair<size_t, size_t>
|
||||
calculate_size(const arrow::ArrayVector& array_vec) override {
|
||||
size_t size = 0;
|
||||
size_t row_nums = 0;
|
||||
for (const auto& data : array_vec) {
|
||||
row_nums += data->length();
|
||||
auto array = std::static_pointer_cast<ArrowType>(data);
|
||||
if (nullable_) {
|
||||
auto null_bitmap_n = (data->length() + 7) / 8;
|
||||
size += null_bitmap_n;
|
||||
}
|
||||
size += array->length() * dim_ * sizeof(T);
|
||||
}
|
||||
|
||||
row_nums_ = row_nums;
|
||||
if (!file_path_.empty()) {
|
||||
target_ = std::make_shared<MmapChunkTarget>(file_path_);
|
||||
} else {
|
||||
target_ = std::make_shared<MemChunkTarget>(size);
|
||||
if (nullable_) {
|
||||
size += (row_nums + 7) / 8;
|
||||
}
|
||||
row_nums_ = row_nums;
|
||||
return {size, row_nums};
|
||||
}
|
||||
|
||||
void
|
||||
write_to_target(const arrow::ArrayVector& array_vec,
|
||||
const std::shared_ptr<ChunkTarget>& target) override {
|
||||
// Chunk layout:
|
||||
// 1. Null bitmap (if nullable_=true): Indicates which values are null
|
||||
// 2. Data values: Contiguous storage of data elements in the order:
|
||||
@ -134,55 +115,25 @@ class ChunkWriter final : public ChunkWriterBase {
|
||||
null_bitmaps.emplace_back(
|
||||
data->null_bitmap_data(), data->length(), data->offset());
|
||||
}
|
||||
write_null_bit_maps(null_bitmaps);
|
||||
write_null_bit_maps(null_bitmaps, target);
|
||||
}
|
||||
|
||||
for (const auto& data : array_vec) {
|
||||
auto array = std::static_pointer_cast<ArrowType>(data);
|
||||
auto data_ptr = array->raw_values();
|
||||
target_->write(data_ptr, array->length() * dim_ * sizeof(T));
|
||||
target->write(data_ptr, array->length() * dim_ * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Chunk>
|
||||
finish() override {
|
||||
auto [data, size] = target_->get();
|
||||
auto mmap_file_raii = file_path_.empty()
|
||||
? nullptr
|
||||
: std::make_unique<MmapFileRAII>(file_path_);
|
||||
return std::make_unique<FixedWidthChunk>(row_nums_,
|
||||
dim_,
|
||||
data,
|
||||
size,
|
||||
sizeof(T),
|
||||
nullable_,
|
||||
std::move(mmap_file_raii));
|
||||
}
|
||||
|
||||
private:
|
||||
int dim_;
|
||||
const int64_t dim_;
|
||||
};
|
||||
|
||||
template <>
|
||||
inline void
|
||||
ChunkWriter<arrow::BooleanArray, bool>::write(
|
||||
const arrow::ArrayVector& array_vec) {
|
||||
auto size = 0;
|
||||
auto row_nums = 0;
|
||||
|
||||
for (const auto& data : array_vec) {
|
||||
row_nums += data->length();
|
||||
auto array = std::dynamic_pointer_cast<arrow::BooleanArray>(data);
|
||||
size += array->length() * dim_;
|
||||
size += (data->length() + 7) / 8;
|
||||
}
|
||||
row_nums_ = row_nums;
|
||||
if (!file_path_.empty()) {
|
||||
target_ = std::make_shared<MmapChunkTarget>(file_path_);
|
||||
} else {
|
||||
target_ = std::make_shared<MemChunkTarget>(size);
|
||||
}
|
||||
|
||||
ChunkWriter<arrow::BooleanArray, bool>::write_to_target(
|
||||
const arrow::ArrayVector& array_vec,
|
||||
const std::shared_ptr<ChunkTarget>& target) {
|
||||
if (nullable_) {
|
||||
// tuple <data, size, offset>
|
||||
std::vector<std::tuple<const uint8_t*, int64_t, int64_t>> null_bitmaps;
|
||||
@ -190,14 +141,14 @@ ChunkWriter<arrow::BooleanArray, bool>::write(
|
||||
null_bitmaps.emplace_back(
|
||||
data->null_bitmap_data(), data->length(), data->offset());
|
||||
}
|
||||
write_null_bit_maps(null_bitmaps);
|
||||
write_null_bit_maps(null_bitmaps, target);
|
||||
}
|
||||
|
||||
for (const auto& data : array_vec) {
|
||||
auto array = std::dynamic_pointer_cast<arrow::BooleanArray>(data);
|
||||
for (int i = 0; i < array->length(); i++) {
|
||||
auto value = array->Value(i);
|
||||
target_->write(&value, sizeof(bool));
|
||||
target->write(&value, sizeof(bool));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,32 +157,39 @@ class StringChunkWriter : public ChunkWriterBase {
|
||||
public:
|
||||
using ChunkWriterBase::ChunkWriterBase;
|
||||
|
||||
void
|
||||
write(const arrow::ArrayVector& array_vec) override;
|
||||
std::pair<size_t, size_t>
|
||||
calculate_size(const arrow::ArrayVector& array_vec) override;
|
||||
|
||||
std::unique_ptr<Chunk>
|
||||
finish() override;
|
||||
void
|
||||
write_to_target(const arrow::ArrayVector& array_vec,
|
||||
const std::shared_ptr<ChunkTarget>& target) override;
|
||||
|
||||
private:
|
||||
std::vector<std::string_view> strs_;
|
||||
};
|
||||
|
||||
class JSONChunkWriter : public ChunkWriterBase {
|
||||
public:
|
||||
using ChunkWriterBase::ChunkWriterBase;
|
||||
|
||||
void
|
||||
write(const arrow::ArrayVector& array_vec) override;
|
||||
std::pair<size_t, size_t>
|
||||
calculate_size(const arrow::ArrayVector& array_vec) override;
|
||||
|
||||
std::unique_ptr<Chunk>
|
||||
finish() override;
|
||||
void
|
||||
write_to_target(const arrow::ArrayVector& array_vec,
|
||||
const std::shared_ptr<ChunkTarget>& target) override;
|
||||
};
|
||||
|
||||
class GeometryChunkWriter : public ChunkWriterBase {
|
||||
public:
|
||||
using ChunkWriterBase::ChunkWriterBase;
|
||||
void
|
||||
write(const arrow::ArrayVector& array_vec) override;
|
||||
|
||||
std::unique_ptr<Chunk>
|
||||
finish() override;
|
||||
std::pair<size_t, size_t>
|
||||
calculate_size(const arrow::ArrayVector& array_vec) override;
|
||||
|
||||
void
|
||||
write_to_target(const arrow::ArrayVector& array_vec,
|
||||
const std::shared_ptr<ChunkTarget>& target) override;
|
||||
};
|
||||
|
||||
class ArrayChunkWriter : public ChunkWriterBase {
|
||||
@ -239,18 +197,13 @@ class ArrayChunkWriter : public ChunkWriterBase {
|
||||
ArrayChunkWriter(const milvus::DataType element_type, bool nullable)
|
||||
: ChunkWriterBase(nullable), element_type_(element_type) {
|
||||
}
|
||||
ArrayChunkWriter(const milvus::DataType element_type,
|
||||
std::string file_path,
|
||||
bool nullable)
|
||||
: ChunkWriterBase(std::move(file_path), nullable),
|
||||
element_type_(element_type) {
|
||||
}
|
||||
|
||||
std::pair<size_t, size_t>
|
||||
calculate_size(const arrow::ArrayVector& array_vec) override;
|
||||
|
||||
void
|
||||
write(const arrow::ArrayVector& array_vec) override;
|
||||
|
||||
std::unique_ptr<Chunk>
|
||||
finish() override;
|
||||
write_to_target(const arrow::ArrayVector& array_vec,
|
||||
const std::shared_ptr<ChunkTarget>& target) override;
|
||||
|
||||
private:
|
||||
const milvus::DataType element_type_;
|
||||
@ -258,49 +211,48 @@ class ArrayChunkWriter : public ChunkWriterBase {
|
||||
|
||||
class VectorArrayChunkWriter : public ChunkWriterBase {
|
||||
public:
|
||||
VectorArrayChunkWriter(int64_t dim,
|
||||
const milvus::DataType element_type,
|
||||
std::string file_path = "")
|
||||
: ChunkWriterBase(std::move(file_path), false),
|
||||
element_type_(element_type),
|
||||
dim_(dim) {
|
||||
VectorArrayChunkWriter(int64_t dim, const milvus::DataType element_type)
|
||||
: ChunkWriterBase(false), element_type_(element_type), dim_(dim) {
|
||||
}
|
||||
|
||||
void
|
||||
write(const arrow::ArrayVector& array_vec) override;
|
||||
std::pair<size_t, size_t>
|
||||
calculate_size(const arrow::ArrayVector& array_vec) override;
|
||||
|
||||
std::unique_ptr<Chunk>
|
||||
finish() override;
|
||||
void
|
||||
write_to_target(const arrow::ArrayVector& array_vec,
|
||||
const std::shared_ptr<ChunkTarget>& target) override;
|
||||
|
||||
private:
|
||||
void
|
||||
writeFloatVectorArray(const arrow::ArrayVector& array_vec);
|
||||
|
||||
size_t
|
||||
calculateTotalSize(const arrow::ArrayVector& array_vec);
|
||||
|
||||
const milvus::DataType element_type_;
|
||||
int64_t dim_;
|
||||
const int64_t dim_;
|
||||
};
|
||||
|
||||
class SparseFloatVectorChunkWriter : public ChunkWriterBase {
|
||||
public:
|
||||
using ChunkWriterBase::ChunkWriterBase;
|
||||
|
||||
std::pair<size_t, size_t>
|
||||
calculate_size(const arrow::ArrayVector& array_vec) override;
|
||||
|
||||
void
|
||||
write(const arrow::ArrayVector& array_vec) override;
|
||||
|
||||
std::unique_ptr<Chunk>
|
||||
finish() override;
|
||||
write_to_target(const arrow::ArrayVector& array_vec,
|
||||
const std::shared_ptr<ChunkTarget>& target) override;
|
||||
};
|
||||
|
||||
std::unique_ptr<Chunk>
|
||||
create_chunk(const FieldMeta& field_meta, const arrow::ArrayVector& array_vec);
|
||||
|
||||
std::unique_ptr<Chunk>
|
||||
create_chunk(const FieldMeta& field_meta,
|
||||
const arrow::ArrayVector& array_vec,
|
||||
const std::string& file_path);
|
||||
const std::string& file_path = "",
|
||||
proto::common::LoadPriority load_priority =
|
||||
proto::common::LoadPriority::HIGH);
|
||||
|
||||
std::unordered_map<FieldId, std::shared_ptr<Chunk>>
|
||||
create_group_chunk(const std::vector<FieldId>& field_ids,
|
||||
const std::vector<FieldMeta>& field_metas,
|
||||
const std::vector<arrow::ArrayVector>& array_vec,
|
||||
const std::string& file_path = "",
|
||||
proto::common::LoadPriority load_priority =
|
||||
proto::common::LoadPriority::HIGH);
|
||||
|
||||
arrow::ArrayVector
|
||||
read_single_column_batches(std::shared_ptr<arrow::RecordBatchReader> reader);
|
||||
|
||||
@ -123,3 +123,6 @@ const int64_t DEFAULT_SHORT_COLUMN_GROUP_ID = 0;
|
||||
|
||||
// VectorArray related, used for fetch metadata from Arrow schema
|
||||
const std::string ELEMENT_TYPE_KEY_FOR_ARROW = "elementType";
|
||||
|
||||
// EPSILON value for comparing float numbers
|
||||
const float EPSILON = 0.0000000119;
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "common/Exception.h"
|
||||
#include "common/FieldDataInterface.h"
|
||||
#include "common/Json.h"
|
||||
#include "index/Utils.h"
|
||||
#include "simdjson/padded_string.h"
|
||||
|
||||
namespace milvus {
|
||||
@ -348,46 +349,47 @@ FieldDataImpl<Type, is_type_entire_row>::FillFieldData(
|
||||
std::vector<VectorArray> values(element_count);
|
||||
|
||||
switch (element_type) {
|
||||
case DataType::VECTOR_FLOAT: {
|
||||
auto float_array =
|
||||
std::dynamic_pointer_cast<arrow::FloatArray>(
|
||||
case DataType::VECTOR_FLOAT:
|
||||
case DataType::VECTOR_BINARY:
|
||||
case DataType::VECTOR_FLOAT16:
|
||||
case DataType::VECTOR_BFLOAT16:
|
||||
case DataType::VECTOR_INT8: {
|
||||
// All vector types use FixedSizeBinaryArray and have the same serialization logic
|
||||
auto binary_array =
|
||||
std::dynamic_pointer_cast<arrow::FixedSizeBinaryArray>(
|
||||
values_array);
|
||||
AssertInfo(
|
||||
float_array != nullptr,
|
||||
"Expected FloatArray for VECTOR_FLOAT element type");
|
||||
AssertInfo(binary_array != nullptr,
|
||||
"Expected FixedSizeBinaryArray for VectorArray "
|
||||
"element");
|
||||
|
||||
// Calculate bytes per vector using the unified function
|
||||
auto bytes_per_vec =
|
||||
milvus::vector_bytes_per_element(element_type, dim);
|
||||
|
||||
for (size_t index = 0; index < element_count; ++index) {
|
||||
int64_t start_offset = list_array->value_offset(index);
|
||||
int64_t end_offset =
|
||||
list_array->value_offset(index + 1);
|
||||
int64_t num_floats = end_offset - start_offset;
|
||||
AssertInfo(num_floats % dim == 0,
|
||||
"Invalid data: number of floats ({}) not "
|
||||
"divisible by "
|
||||
"dimension ({})",
|
||||
num_floats,
|
||||
dim);
|
||||
int64_t num_vectors = end_offset - start_offset;
|
||||
|
||||
int num_vectors = num_floats / dim;
|
||||
const float* data_ptr =
|
||||
float_array->raw_values() + start_offset;
|
||||
values[index] =
|
||||
VectorArray(static_cast<const void*>(data_ptr),
|
||||
num_vectors,
|
||||
dim,
|
||||
element_type);
|
||||
auto data_size = num_vectors * bytes_per_vec;
|
||||
auto data_ptr = std::make_unique<uint8_t[]>(data_size);
|
||||
|
||||
for (int64_t i = 0; i < num_vectors; i++) {
|
||||
const uint8_t* binary_data =
|
||||
binary_array->GetValue(start_offset + i);
|
||||
uint8_t* dest = data_ptr.get() + i * bytes_per_vec;
|
||||
std::memcpy(dest, binary_data, bytes_per_vec);
|
||||
}
|
||||
|
||||
values[index] = VectorArray(
|
||||
static_cast<const void*>(data_ptr.get()),
|
||||
num_vectors,
|
||||
dim,
|
||||
element_type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::VECTOR_BINARY:
|
||||
case DataType::VECTOR_FLOAT16:
|
||||
case DataType::VECTOR_BFLOAT16:
|
||||
case DataType::VECTOR_INT8:
|
||||
ThrowInfo(
|
||||
NotImplemented,
|
||||
"Element type {} in VectorArray not implemented yet",
|
||||
GetDataTypeName(element_type));
|
||||
break;
|
||||
default:
|
||||
ThrowInfo(DataTypeInvalid,
|
||||
"Unsupported element type {} in VectorArray",
|
||||
|
||||
@ -40,9 +40,6 @@
|
||||
#include "common/TypeTraits.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
using DataType = milvus::DataType;
|
||||
|
||||
class FieldDataBase {
|
||||
public:
|
||||
explicit FieldDataBase(DataType data_type, bool nullable)
|
||||
@ -727,21 +724,32 @@ class FieldDataJsonImpl : public FieldDataImpl<Json, true> {
|
||||
void
|
||||
FillFieldData(const std::optional<DefaultValueType> default_value,
|
||||
ssize_t element_count) override {
|
||||
// todo: add json default_value
|
||||
AssertInfo(!default_value.has_value(),
|
||||
"json type not support default_value");
|
||||
if (element_count == 0) {
|
||||
return;
|
||||
}
|
||||
null_count_ = element_count;
|
||||
|
||||
std::lock_guard lck(tell_mutex_);
|
||||
if (length_ + element_count > get_num_rows()) {
|
||||
resize_field_data(length_ + element_count);
|
||||
}
|
||||
|
||||
bitset::detail::ElementWiseBitsetPolicy<uint8_t>::op_fill(
|
||||
valid_data_.data(), length_, element_count, false);
|
||||
if (default_value.has_value()) {
|
||||
AssertInfo(default_value->has_bytes_data(),
|
||||
"json type default_value shall be bytes data");
|
||||
|
||||
auto data = default_value->bytes_data();
|
||||
Json default_json = Json(data.data(), data.size());
|
||||
std::fill(data_.data() + length_,
|
||||
data_.data() + length_ + element_count,
|
||||
default_json);
|
||||
bitset::detail::ElementWiseBitsetPolicy<uint8_t>::op_fill(
|
||||
valid_data_.data(), length_, element_count, true);
|
||||
} else {
|
||||
null_count_ = element_count;
|
||||
bitset::detail::ElementWiseBitsetPolicy<uint8_t>::op_fill(
|
||||
valid_data_.data(), length_, element_count, false);
|
||||
}
|
||||
|
||||
length_ += element_count;
|
||||
}
|
||||
|
||||
|
||||
@ -68,6 +68,65 @@ FieldMeta::get_analyzer_params() const {
|
||||
return ParseTokenizerParams(params);
|
||||
}
|
||||
|
||||
milvus::proto::schema::FieldSchema
|
||||
FieldMeta::ToProto() const {
|
||||
milvus::proto::schema::FieldSchema proto;
|
||||
proto.set_fieldid(id_.get());
|
||||
proto.set_name(name_.get());
|
||||
proto.set_data_type(ToProtoDataType(type_));
|
||||
proto.set_nullable(nullable_);
|
||||
|
||||
if (has_default_value()) {
|
||||
*proto.mutable_default_value() = *default_value_;
|
||||
}
|
||||
|
||||
if (element_type_ != DataType::NONE) {
|
||||
proto.set_element_type(ToProtoDataType(element_type_));
|
||||
}
|
||||
|
||||
auto add_type_param = [&proto](const std::string& key,
|
||||
const std::string& value) {
|
||||
auto* param = proto.add_type_params();
|
||||
param->set_key(key);
|
||||
param->set_value(value);
|
||||
};
|
||||
auto add_index_param = [&proto](const std::string& key,
|
||||
const std::string& value) {
|
||||
auto* param = proto.add_index_params();
|
||||
param->set_key(key);
|
||||
param->set_value(value);
|
||||
};
|
||||
|
||||
if (type_ == DataType::VECTOR_ARRAY) {
|
||||
add_type_param("dim", std::to_string(get_dim()));
|
||||
if (auto metric = get_metric_type(); metric.has_value()) {
|
||||
add_index_param("metric_type", metric.value());
|
||||
}
|
||||
} else if (IsVectorDataType(type_)) {
|
||||
if (!IsSparseFloatVectorDataType(type_)) {
|
||||
add_type_param("dim", std::to_string(get_dim()));
|
||||
}
|
||||
if (auto metric = get_metric_type(); metric.has_value()) {
|
||||
add_index_param("metric_type", metric.value());
|
||||
}
|
||||
} else if (IsStringDataType(type_)) {
|
||||
std::map<std::string, std::string> params;
|
||||
if (string_info_.has_value()) {
|
||||
params = string_info_->params;
|
||||
}
|
||||
params[MAX_LENGTH] = std::to_string(get_max_len());
|
||||
params["enable_match"] = enable_match() ? "true" : "false";
|
||||
params["enable_analyzer"] = enable_analyzer() ? "true" : "false";
|
||||
for (const auto& [key, value] : params) {
|
||||
add_type_param(key, value);
|
||||
}
|
||||
} else if (IsArrayDataType(type_)) {
|
||||
// element_type already populated above
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
FieldMeta
|
||||
FieldMeta::ParseFrom(const milvus::proto::schema::FieldSchema& schema_proto) {
|
||||
auto field_id = FieldId(schema_proto.fieldid());
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
@ -251,6 +252,9 @@ class FieldMeta {
|
||||
return default_value_;
|
||||
}
|
||||
|
||||
milvus::proto::schema::FieldSchema
|
||||
ToProto() const;
|
||||
|
||||
size_t
|
||||
get_sizeof() const {
|
||||
AssertInfo(!IsSparseFloatVectorDataType(type_),
|
||||
|
||||
@ -114,7 +114,7 @@ class SimpleGeometryCacheManager {
|
||||
SimpleGeometryCacheManager() = default;
|
||||
|
||||
SimpleGeometryCache&
|
||||
GetCache(int64_t segment_id, FieldId field_id) {
|
||||
GetOrCreateCache(int64_t segment_id, FieldId field_id) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto key = MakeCacheKey(segment_id, field_id);
|
||||
auto it = caches_.find(key);
|
||||
@ -128,6 +128,17 @@ class SimpleGeometryCacheManager {
|
||||
return *cache_ptr;
|
||||
}
|
||||
|
||||
SimpleGeometryCache*
|
||||
GetCache(int64_t segment_id, FieldId field_id) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto key = MakeCacheKey(segment_id, field_id);
|
||||
auto it = caches_.find(key);
|
||||
if (it != caches_.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
RemoveCache(GEOSContextHandle_t ctx, int64_t segment_id, FieldId field_id) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
@ -184,26 +195,4 @@ class SimpleGeometryCacheManager {
|
||||
|
||||
} // namespace exec
|
||||
|
||||
// Convenient global functions for direct access to geometry cache
|
||||
inline const Geometry*
|
||||
GetGeometryByOffset(int64_t segment_id, FieldId field_id, size_t offset) {
|
||||
auto& cache = exec::SimpleGeometryCacheManager::Instance().GetCache(
|
||||
segment_id, field_id);
|
||||
return cache.GetByOffset(offset);
|
||||
}
|
||||
|
||||
inline void
|
||||
RemoveGeometryCache(GEOSContextHandle_t ctx,
|
||||
int64_t segment_id,
|
||||
FieldId field_id) {
|
||||
exec::SimpleGeometryCacheManager::Instance().RemoveCache(
|
||||
ctx, segment_id, field_id);
|
||||
}
|
||||
|
||||
inline void
|
||||
RemoveSegmentGeometryCaches(GEOSContextHandle_t ctx, int64_t segment_id) {
|
||||
exec::SimpleGeometryCacheManager::Instance().RemoveSegmentCaches(
|
||||
ctx, segment_id);
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
|
||||
@ -98,4 +98,9 @@ class GroupChunk {
|
||||
std::unordered_map<FieldId, std::shared_ptr<Chunk>> chunks_;
|
||||
};
|
||||
|
||||
enum class GroupChunkType : uint8_t {
|
||||
DEFAULT = 0,
|
||||
JSON_KEY_STATS = 1,
|
||||
};
|
||||
|
||||
} // namespace milvus
|
||||
@ -94,8 +94,8 @@ Schema::ConvertToArrowSchema() const {
|
||||
std::shared_ptr<arrow::DataType> arrow_data_type = nullptr;
|
||||
auto data_type = meta.get_data_type();
|
||||
if (data_type == DataType::VECTOR_ARRAY) {
|
||||
arrow_data_type =
|
||||
GetArrowDataTypeForVectorArray(meta.get_element_type());
|
||||
arrow_data_type = GetArrowDataTypeForVectorArray(
|
||||
meta.get_element_type(), meta.get_dim());
|
||||
} else {
|
||||
arrow_data_type = GetArrowDataType(data_type, dim);
|
||||
}
|
||||
@ -111,6 +111,29 @@ Schema::ConvertToArrowSchema() const {
|
||||
return arrow::schema(arrow_fields);
|
||||
}
|
||||
|
||||
proto::schema::CollectionSchema
|
||||
Schema::ToProto() const {
|
||||
proto::schema::CollectionSchema schema_proto;
|
||||
schema_proto.set_enable_dynamic_field(dynamic_field_id_opt_.has_value());
|
||||
|
||||
for (const auto& field_id : field_ids_) {
|
||||
const auto& meta = fields_.at(field_id);
|
||||
auto* field_proto = schema_proto.add_fields();
|
||||
*field_proto = meta.ToProto();
|
||||
|
||||
if (primary_field_id_opt_.has_value() &&
|
||||
field_id == primary_field_id_opt_.value()) {
|
||||
field_proto->set_is_primary_key(true);
|
||||
}
|
||||
if (dynamic_field_id_opt_.has_value() &&
|
||||
field_id == dynamic_field_id_opt_.value()) {
|
||||
field_proto->set_is_dynamic(true);
|
||||
}
|
||||
}
|
||||
|
||||
return schema_proto;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::vector<FieldMeta>>
|
||||
Schema::AbsentFields(Schema& old_schema) const {
|
||||
std::vector<FieldMeta> result;
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@ -126,6 +127,31 @@ class Schema {
|
||||
return field_id;
|
||||
}
|
||||
|
||||
// string type
|
||||
FieldId
|
||||
AddDebugVarcharField(const FieldName& name,
|
||||
DataType data_type,
|
||||
int64_t max_length,
|
||||
bool nullable,
|
||||
bool enable_match,
|
||||
bool enable_analyzer,
|
||||
std::map<std::string, std::string>& params,
|
||||
std::optional<DefaultValueType> default_value) {
|
||||
auto field_id = FieldId(debug_id);
|
||||
debug_id++;
|
||||
auto field_meta = FieldMeta(name,
|
||||
field_id,
|
||||
data_type,
|
||||
max_length,
|
||||
nullable,
|
||||
enable_match,
|
||||
enable_analyzer,
|
||||
params,
|
||||
std::move(default_value));
|
||||
this->AddField(std::move(field_meta));
|
||||
return field_id;
|
||||
}
|
||||
|
||||
// scalar type
|
||||
void
|
||||
AddField(const FieldName& name,
|
||||
@ -293,6 +319,9 @@ class Schema {
|
||||
const ArrowSchemaPtr
|
||||
ConvertToArrowSchema() const;
|
||||
|
||||
proto::schema::CollectionSchema
|
||||
ToProto() const;
|
||||
|
||||
void
|
||||
UpdateLoadFields(const std::vector<int64_t>& field_ids) {
|
||||
load_fields_.clear();
|
||||
@ -358,5 +387,5 @@ class Schema {
|
||||
};
|
||||
|
||||
using SchemaPtr = std::shared_ptr<Schema>;
|
||||
|
||||
using SafeSchemaPtr = std::atomic<SchemaPtr*>;
|
||||
} // namespace milvus
|
||||
|
||||
@ -156,6 +156,67 @@ GetDataTypeSize(DataType data_type, int dim = 1) {
|
||||
}
|
||||
}
|
||||
|
||||
// Convert internal DataType to proto schema DataType
|
||||
inline proto::schema::DataType
|
||||
ToProtoDataType(DataType data_type) {
|
||||
switch (data_type) {
|
||||
case DataType::NONE:
|
||||
return proto::schema::DataType::None;
|
||||
case DataType::BOOL:
|
||||
return proto::schema::DataType::Bool;
|
||||
case DataType::INT8:
|
||||
return proto::schema::DataType::Int8;
|
||||
case DataType::INT16:
|
||||
return proto::schema::DataType::Int16;
|
||||
case DataType::INT32:
|
||||
return proto::schema::DataType::Int32;
|
||||
case DataType::INT64:
|
||||
return proto::schema::DataType::Int64;
|
||||
|
||||
case DataType::FLOAT:
|
||||
return proto::schema::DataType::Float;
|
||||
case DataType::DOUBLE:
|
||||
return proto::schema::DataType::Double;
|
||||
|
||||
case DataType::STRING:
|
||||
return proto::schema::DataType::String;
|
||||
case DataType::VARCHAR:
|
||||
return proto::schema::DataType::VarChar;
|
||||
case DataType::ARRAY:
|
||||
return proto::schema::DataType::Array;
|
||||
case DataType::JSON:
|
||||
return proto::schema::DataType::JSON;
|
||||
case DataType::TEXT:
|
||||
return proto::schema::DataType::Text;
|
||||
case DataType::TIMESTAMPTZ:
|
||||
return proto::schema::DataType::Timestamptz;
|
||||
|
||||
case DataType::VECTOR_BINARY:
|
||||
return proto::schema::DataType::BinaryVector;
|
||||
case DataType::VECTOR_FLOAT:
|
||||
return proto::schema::DataType::FloatVector;
|
||||
case DataType::VECTOR_FLOAT16:
|
||||
return proto::schema::DataType::Float16Vector;
|
||||
case DataType::VECTOR_BFLOAT16:
|
||||
return proto::schema::DataType::BFloat16Vector;
|
||||
case DataType::VECTOR_SPARSE_U32_F32:
|
||||
return proto::schema::DataType::SparseFloatVector;
|
||||
case DataType::VECTOR_INT8:
|
||||
return proto::schema::DataType::Int8Vector;
|
||||
case DataType::VECTOR_ARRAY:
|
||||
return proto::schema::DataType::ArrayOfVector;
|
||||
|
||||
// Internal-only or unsupported mappings
|
||||
case DataType::ROW:
|
||||
default:
|
||||
ThrowInfo(
|
||||
DataTypeInvalid,
|
||||
fmt::format(
|
||||
"failed to convert to proto data type, invalid type {}",
|
||||
data_type));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::shared_ptr<arrow::DataType>
|
||||
GetArrowDataType(DataType data_type, int dim = 1) {
|
||||
switch (data_type) {
|
||||
@ -205,10 +266,23 @@ GetArrowDataType(DataType data_type, int dim = 1) {
|
||||
}
|
||||
|
||||
inline std::shared_ptr<arrow::DataType>
|
||||
GetArrowDataTypeForVectorArray(DataType elem_type) {
|
||||
GetArrowDataTypeForVectorArray(DataType elem_type, int dim) {
|
||||
if (dim <= 0) {
|
||||
ThrowInfo(DataTypeInvalid, "dim must be provided for VectorArray");
|
||||
}
|
||||
// VectorArray stores vectors as FixedSizeBinaryArray
|
||||
// We must have dim to create the correct fixed_size_binary type
|
||||
switch (elem_type) {
|
||||
case DataType::VECTOR_FLOAT:
|
||||
return arrow::list(arrow::float32());
|
||||
return arrow::list(arrow::fixed_size_binary(dim * sizeof(float)));
|
||||
case DataType::VECTOR_BINARY:
|
||||
return arrow::list(arrow::fixed_size_binary((dim + 7) / 8));
|
||||
case DataType::VECTOR_FLOAT16:
|
||||
return arrow::list(arrow::fixed_size_binary(dim * 2));
|
||||
case DataType::VECTOR_BFLOAT16:
|
||||
return arrow::list(arrow::fixed_size_binary(dim * 2));
|
||||
case DataType::VECTOR_INT8:
|
||||
return arrow::list(arrow::fixed_size_binary(dim));
|
||||
default: {
|
||||
ThrowInfo(DataTypeInvalid,
|
||||
fmt::format("failed to get arrow type for vector array, "
|
||||
@ -384,6 +458,7 @@ IsPrimitiveType(proto::schema::DataType type) {
|
||||
case proto::schema::DataType::Double:
|
||||
case proto::schema::DataType::String:
|
||||
case proto::schema::DataType::VarChar:
|
||||
case proto::schema::DataType::Timestamptz:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -534,7 +609,10 @@ IsFloatVectorMetricType(const MetricType& metric_type) {
|
||||
metric_type == knowhere::metric::IP ||
|
||||
metric_type == knowhere::metric::COSINE ||
|
||||
metric_type == knowhere::metric::BM25 ||
|
||||
metric_type == knowhere::metric::MAX_SIM;
|
||||
metric_type == knowhere::metric::MAX_SIM ||
|
||||
metric_type == knowhere::metric::MAX_SIM_COSINE ||
|
||||
metric_type == knowhere::metric::MAX_SIM_IP ||
|
||||
metric_type == knowhere::metric::MAX_SIM_L2;
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -543,14 +621,20 @@ IsBinaryVectorMetricType(const MetricType& metric_type) {
|
||||
metric_type == knowhere::metric::JACCARD ||
|
||||
metric_type == knowhere::metric::SUPERSTRUCTURE ||
|
||||
metric_type == knowhere::metric::SUBSTRUCTURE ||
|
||||
metric_type == knowhere::metric::MHJACCARD;
|
||||
metric_type == knowhere::metric::MHJACCARD ||
|
||||
metric_type == knowhere::metric::MAX_SIM_HAMMING ||
|
||||
metric_type == knowhere::metric::MAX_SIM_JACCARD;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsIntVectorMetricType(const MetricType& metric_type) {
|
||||
return metric_type == knowhere::metric::L2 ||
|
||||
metric_type == knowhere::metric::IP ||
|
||||
metric_type == knowhere::metric::COSINE;
|
||||
metric_type == knowhere::metric::COSINE ||
|
||||
metric_type == knowhere::metric::MAX_SIM ||
|
||||
metric_type == knowhere::metric::MAX_SIM_COSINE ||
|
||||
metric_type == knowhere::metric::MAX_SIM_IP ||
|
||||
metric_type == knowhere::metric::MAX_SIM_L2;
|
||||
}
|
||||
|
||||
// Plus 1 because we can't use greater(>) symbol
|
||||
@ -746,6 +830,30 @@ FromValCase(milvus::proto::plan::GenericValue::ValCase val_case) {
|
||||
return DataType::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate bytes per vector element for different vector types
|
||||
// Used by VectorArray and storage utilities
|
||||
inline size_t
|
||||
vector_bytes_per_element(const DataType data_type, int64_t dim) {
|
||||
switch (data_type) {
|
||||
case DataType::VECTOR_BINARY:
|
||||
// Binary vector stores bits, so dim represents bit count
|
||||
// Need (dim + 7) / 8 bytes to store dim bits
|
||||
return (dim + 7) / 8;
|
||||
case DataType::VECTOR_FLOAT:
|
||||
return dim * sizeof(float);
|
||||
case DataType::VECTOR_FLOAT16:
|
||||
return dim * sizeof(float16);
|
||||
case DataType::VECTOR_BFLOAT16:
|
||||
return dim * sizeof(bfloat16);
|
||||
case DataType::VECTOR_INT8:
|
||||
return dim * sizeof(int8);
|
||||
default:
|
||||
ThrowInfo(UnexpectedError,
|
||||
fmt::format("invalid data type: {}", data_type));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
template <>
|
||||
struct fmt::formatter<milvus::DataType> : formatter<string_view> {
|
||||
@ -935,6 +1043,9 @@ struct fmt::formatter<milvus::proto::schema::DataType>
|
||||
case milvus::proto::schema::DataType::Geometry:
|
||||
name = "Geometry";
|
||||
break;
|
||||
case milvus::proto::schema::DataType::Timestamptz:
|
||||
name = "Timestamptz";
|
||||
break;
|
||||
case milvus::proto::schema::DataType::Text:
|
||||
name = "Text";
|
||||
break;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user