mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-02 12:42:13 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cf9b8d621 | ||
|
|
b3f94feede | ||
|
|
d74348048a | ||
|
|
0361c321b4 | ||
|
|
0f8168c0c9 | ||
|
|
a1292d8730 | ||
|
|
1df4223195 | ||
|
|
76a62859ff | ||
|
|
10ac25f857 | ||
|
|
c43238b30a | ||
|
|
322af1fc04 | ||
|
|
0414b68a4f | ||
|
|
9ba4639a27 | ||
|
|
186b1f029b | ||
|
|
fa8e9ef03c | ||
|
|
80d61ebba5 | ||
|
|
248b16bc09 | ||
|
|
c0bb87e036 | ||
|
|
181e6f2f42 | ||
|
|
0c8f16d8bd | ||
|
|
2df70ce95f | ||
|
|
3e23421608 | ||
|
|
49a470bcdf | ||
|
|
750a0ba1b2 | ||
|
|
8b2c39f2c0 | ||
|
|
1494221b08 | ||
|
|
b388957340 | ||
|
|
31fc165715 | ||
|
|
7669852241 | ||
|
|
e3b1bacf3f | ||
|
|
a46f873edd | ||
|
|
d8b424d123 | ||
|
|
411bdda08d | ||
|
|
440ebd7b6d | ||
|
|
6eededee10 | ||
|
|
d531b7cbbf | ||
|
|
b18112ae10 | ||
|
|
6c6655de9d | ||
|
|
cf28108ea4 | ||
|
|
27af11f1e8 | ||
|
|
0bb97709d4 | ||
|
|
8cb42c39ad | ||
|
|
2e5aa06026 | ||
|
|
4d414f54a2 | ||
|
|
a04bd4d26f | ||
|
|
a0b60dd641 | ||
|
|
6c77ff8426 | ||
|
|
c32bc7ef2e | ||
|
|
18d2f50a58 | ||
|
|
8e8b42786a | ||
|
|
e3dc3c5b3b | ||
|
|
22023680d8 | ||
|
|
48e817d3e7 | ||
|
|
d95a4561e0 | ||
|
|
b64fc44e8d | ||
|
|
340aea9b34 | ||
|
|
0d390ec882 | ||
|
|
d83107efe5 | ||
|
|
91cbaef02b | ||
|
|
4e17d399a6 | ||
|
|
7a49d3541a | ||
|
|
a65088d739 | ||
|
|
a1cb49d078 | ||
|
|
b590a68e75 | ||
|
|
4650c4c65f | ||
|
|
fa62926347 | ||
|
|
89a1fd1751 | ||
|
|
4827425146 | ||
|
|
3b50139f68 | ||
|
|
7f685ce7ba | ||
|
|
436d99443b | ||
|
|
9e5b1eef9b | ||
|
|
b771fefa37 | ||
|
|
8908810376 | ||
|
|
9b666a53ed | ||
|
|
962461fc33 | ||
|
|
b28595d8db | ||
|
|
d99d99a911 | ||
|
|
324f3fbb15 | ||
|
|
c097994f63 | ||
|
|
e3a7c503c3 | ||
|
|
0a851ec00b | ||
|
|
39941edc0b | ||
|
|
875f562779 | ||
|
|
984b6c54cf | ||
|
|
2492a45499 | ||
|
|
ba67e6ca29 | ||
|
|
9e4f985698 | ||
|
|
cb470d44df | ||
|
|
1eb2da46d5 | ||
|
|
504ae8383a | ||
|
|
dbcba75271 | ||
|
|
c9caf33119 | ||
|
|
4d6c18d86f | ||
|
|
4eb8e8624d | ||
|
|
1990456670 | ||
|
|
905911853d |
@@ -53,7 +53,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed-large-disk
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
release_tag: dev
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed-normal-disk
|
||||
@@ -102,7 +102,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed-large-disk
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
release_tag: dev
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed-normal-disk
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
build_flags: -tags elastic,ydb,gocdk,tikv
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset,elastic,ydb,gocdk,tikv
|
||||
ldflags: -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v3
|
||||
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -33,30 +33,30 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v1
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v1
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v1
|
||||
with:
|
||||
buildkitd-flags: "--debug"
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v1
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v1
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.GHCR_USERNAME }}
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v2
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v3
|
||||
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -34,30 +34,30 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v1
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v1
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v1
|
||||
with:
|
||||
buildkitd-flags: "--debug"
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v1
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v1
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.GHCR_USERNAME }}
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v2
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v3
|
||||
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -34,20 +34,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v1
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v1
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v1
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v2
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v3
|
||||
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -35,20 +35,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v1
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v1
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v1
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v2
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v3
|
||||
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -35,20 +35,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v1
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v1
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v1
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v2
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v3
|
||||
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -34,20 +34,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v1
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v1
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v1
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v2
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v3
|
||||
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -34,20 +34,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v1
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v1
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v1
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v2
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -11,4 +11,4 @@ jobs:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@f6fff72a3217f580d5afd49a46826795305b63c7
|
||||
uses: actions/dependency-review-action@6c5ccdad469c9f8a2996bfecaec55a631a347034
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
e2e:
|
||||
name: FUSE Mount
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 15
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v2
|
||||
@@ -41,20 +41,20 @@ jobs:
|
||||
timeout-minutes: 5
|
||||
run: make build_e2e && docker compose -f ./compose/e2e-mount.yml up --wait
|
||||
|
||||
- name: Run FIO
|
||||
- name: Run FIO 4k
|
||||
timeout-minutes: 15
|
||||
run: |
|
||||
echo "Starting FIO at: $(date)"
|
||||
# Concurrent r/w
|
||||
echo 'Run randrw with size=16M bs=4k'
|
||||
docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randrw --bs=4k --direct=1 --numjobs=8 --ioengine=libaio --iodepth=32 --group_reporting --runtime=30 --time_based=1
|
||||
docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randrw --bs=4k --direct=1 --numjobs=8 --ioengine=libaio --group_reporting --runtime=30 --time_based=1
|
||||
|
||||
echo "Verify FIO at: $(date)"
|
||||
# Verified write
|
||||
echo 'Run randwrite with size=16M bs=4k'
|
||||
docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randwrite --bs=4k --direct=1 --numjobs=8 --ioengine=libaio --iodepth=32 --group_reporting --runtime=30 --time_based=1 --do_verify=0 --verify=crc32c --verify_backlog=1
|
||||
|
||||
- name: Run FIO
|
||||
- name: Run FIO 128k
|
||||
timeout-minutes: 15
|
||||
run: |
|
||||
echo "Starting FIO at: $(date)"
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
echo 'Run randwrite with size=16M bs=128k'
|
||||
docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randwrite --bs=128k --direct=1 --numjobs=8 --ioengine=libaio --iodepth=32 --group_reporting --runtime=30 --time_based=1 --do_verify=0 --verify=crc32c --verify_backlog=1
|
||||
|
||||
- name: Run FIO
|
||||
- name: Run FIO 1MB
|
||||
timeout-minutes: 15
|
||||
run: |
|
||||
echo "Starting FIO at: $(date)"
|
||||
|
||||
@@ -87,3 +87,4 @@ other/java/hdfs/dependency-reduced-pom.xml
|
||||
|
||||
# binary file
|
||||
weed/weed
|
||||
weed/mq/client/cmd/weed_pub/weed_pub
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ cgo ?= 0
|
||||
binary:
|
||||
export SWCOMMIT=$(shell git rev-parse --short HEAD)
|
||||
export SWLDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=$(SWCOMMIT)"
|
||||
cd ../weed && CGO_ENABLED=$(cgo) GOOS=linux go build $(options) -tags "$(tags)" -ldflags "-extldflags -static $(SWLDFLAGS)" && mv weed ../docker/
|
||||
cd ../weed && CGO_ENABLED=$(cgo) GOOS=linux go build $(options) -tags "$(tags)" -ldflags "-s -w -extldflags -static $(SWLDFLAGS)" && mv weed ../docker/
|
||||
|
||||
binary_race: options = -race
|
||||
binary_race: cgo = 1
|
||||
|
||||
@@ -18,10 +18,10 @@ bucket prefix = yournamehere-{random}-
|
||||
|
||||
[s3 main]
|
||||
# main display_name set in vstart.sh
|
||||
display_name = M. Tester
|
||||
display_name = s3_tests
|
||||
|
||||
# main user_idname set in vstart.sh
|
||||
user_id = testid
|
||||
user_id = s3_tests
|
||||
|
||||
# main email set in vstart.sh
|
||||
email = tester@ceph.com
|
||||
|
||||
@@ -42,7 +42,7 @@ require (
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.2
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0
|
||||
@@ -112,26 +112,26 @@ require (
|
||||
gocloud.dev v0.34.0
|
||||
gocloud.dev/pubsub/natspubsub v0.33.0
|
||||
gocloud.dev/pubsub/rabbitpubsub v0.33.0
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
|
||||
golang.org/x/image v0.11.0
|
||||
golang.org/x/net v0.14.0
|
||||
golang.org/x/oauth2 v0.10.0 // indirect
|
||||
golang.org/x/net v0.15.0
|
||||
golang.org/x/oauth2 v0.12.0 // indirect
|
||||
golang.org/x/sys v0.12.0
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/tools v0.11.0
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.134.0
|
||||
google.golang.org/api v0.141.0
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230731193218-e0aa005b6bdf // indirect
|
||||
google.golang.org/grpc v1.57.0
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||
google.golang.org/grpc v1.58.0
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
modernc.org/b v1.0.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.24.1 // indirect
|
||||
modernc.org/mathutil v1.5.0
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.6.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.25.0
|
||||
@@ -144,20 +144,22 @@ require (
|
||||
github.com/arangodb/go-driver v1.6.0
|
||||
github.com/armon/go-metrics v0.4.1
|
||||
github.com/aws/aws-sdk-go-v2 v1.21.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.33
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.35
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.2
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.39
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.37
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5
|
||||
github.com/fluent/fluent-logger-golang v1.9.0
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0
|
||||
github.com/google/flatbuffers/go v0.0.0-20230108230133-3b8644d32c50
|
||||
github.com/hanwen/go-fuse/v2 v2.3.0
|
||||
github.com/hanwen/go-fuse/v2 v2.4.0
|
||||
github.com/hashicorp/raft v1.5.0
|
||||
github.com/hashicorp/raft-boltdb/v2 v2.2.2
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1
|
||||
github.com/puzpuzpuz/xsync/v2 v2.5.0
|
||||
github.com/rabbitmq/amqp091-go v1.8.1
|
||||
github.com/rclone/rclone v1.63.1
|
||||
github.com/rdleal/intervalst v0.0.0-20221028215511-a098aa0d2cb8
|
||||
github.com/schollz/progressbar/v3 v3.13.1
|
||||
github.com/shirou/gopsutil/v3 v3.23.5
|
||||
github.com/tikv/client-go/v2 v2.0.7
|
||||
github.com/ydb-platform/ydb-go-sdk-auth-environ v0.2.0
|
||||
github.com/ydb-platform/ydb-go-sdk/v3 v3.48.8
|
||||
@@ -179,20 +181,20 @@ require (
|
||||
github.com/Unknwon/goconfig v1.0.0 // indirect
|
||||
github.com/abbot/go-http-auth v0.4.0 // indirect
|
||||
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.39 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.33 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.21.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.24.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 // indirect
|
||||
github.com/aws/smithy-go v1.14.2 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
@@ -215,7 +217,7 @@ require (
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/s2a-go v0.1.4 // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.5.0 // indirect
|
||||
@@ -266,9 +268,9 @@ require (
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/putdotio/go-putio/putio v0.0.0-20200123120452-16d982cac2b8 // indirect
|
||||
github.com/rclone/ftp v0.0.0-20230327202000-dadc1f64e87d // indirect
|
||||
github.com/rdleal/intervalst v0.0.0-20221028215511-a098aa0d2cb8 // indirect
|
||||
github.com/rfjakob/eme v1.1.2 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.5 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
||||
github.com/smartystreets/goconvey v1.8.1 // indirect
|
||||
@@ -301,10 +303,10 @@ require (
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/term v0.11.0 // indirect
|
||||
golang.org/x/term v0.12.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230731193218-e0aa005b6bdf // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
@@ -114,57 +114,47 @@ github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+
|
||||
github.com/aws/aws-sdk-go v1.44.314 h1:d/5Jyk/Fb+PBd/4nzQg0JuC2W4A0knrDIzBgK/ggAow=
|
||||
github.com/aws/aws-sdk-go v1.44.314/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDLLf2NmHZoy4=
|
||||
github.com/aws/aws-sdk-go-v2 v1.20.1/go.mod h1:NU06lETsFm8fUC6ZjhgDpVBcGZTFQ6XM+LZWZxMI4ac=
|
||||
github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc=
|
||||
github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.12 h1:lN6L3LrYHeZ6xCxaIYtoWCx4GMLk4nRknsh29OMSqHY=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.12/go.mod h1:TDCkEAkMTXxTs0oLBGBKpBZbk3NLh8EvAfF0Q3x8/0c=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.33 h1:JKcw5SFxFW/rpM4mOPjv0VQ11E2kxW13F3exWOy7VZU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.33/go.mod h1:hXO/l9pgY3K5oZJldamP0pbZHdPqqk+4/maa7DSD3cA=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.32/go.mod h1:lL8U3v/Y79YRG69WlAho0OHIKUXCyFvSXaIvfo81sls=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.35 h1:QpsNitYJu0GgvMBLUIYu9H4yryA5kMksjeIVQfgXrt8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.35/go.mod h1:o7rCaLtvK0hUggAGclf76mNGGkaG5a9KWlp+d9IpcV8=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.8/go.mod h1:ce7BgLQfYr5hQFdy67oX2svto3ufGtm6oBvmsHScI1Q=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.39 h1:oPVyh6fuu/u4OiW4qcuQyEtk7U7uuNBmHmJSLg1AJsQ=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.39/go.mod h1:+NH/ZigdPckFpgB1TRcRuWCB/Kbbvkxc/iNAKTq5RhE=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.37 h1:BvEdm09+ZEh2XtN+PVHPcYwKY3wIeB6pw7vPRM4M9/U=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.37/go.mod h1:ACLrdkd4CLZyXOghZ8IYumQbcooAcp2jo/s2xsFH8IM=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 h1:uDZJF1hu0EVT/4bogChk8DyjSF6fof6uL/0Y26Ma7Fg=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11/go.mod h1:TEPP4tENqBGO99KwVpV9MlOX4NSrSLP8u3KRy2CDwA8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.37/go.mod h1:Pdn4j43v49Kk6+82spO3Tu5gSeQXRsxo56ePPQAvFiA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.38/go.mod h1:qggunOChCMu9ZF/UkAfhTz25+U2rLVb3ya0Ua6TTfCA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.31/go.mod h1:fTJDMe8LOFYtqiFFFeHA+SVMAwqLhoq0kcInYoLa9Js=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.32/go.mod h1:0ZXSqrty4FtQ7p8TEuRde/SZm9X05KT18LAUlR40Ln0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.39 h1:fc0ukRAiP1syoSGZYu+DaE+FulSYhTiJ8WpVu5jElU4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.39/go.mod h1:WLAW8PT7+JhjZfLSWe7WEJaJu0GNo0cKc2Zyo003RBs=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.1 h1:vUh7dBFNS3oFCtVv6CiYKh5hP9ls8+kIpKLeFruIBLk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.1/go.mod h1:sFMeinkhj/SZKQM8BxtvNtSPjJEo0Xrz+w3g2e4FSKI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.13 h1:iV/W5OMBys+66OeXJi/7xIRrKZNsu0ylsLGu+6nbmQE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.13/go.mod h1:ReJb6xYmtGyu9KoFtRreWegbN9dZqvZIIv4vWnhcsyI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.33 h1:QviNkc+vGSuEHx8P+pVNKOdWLXBPIwMFv7p0fphgE4U=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.33/go.mod h1:fABTUmOrAgAalG2i9WJpjBvlnk7UK8YmnYaxN+Q2CwE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.32/go.mod h1:4jwAWKEkCR0anWk5+1RbfSg1R5Gzld7NLiuaq5bTR/Y=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 h1:GPUcE/Yq7Ur8YSUk6lVkoIMWnJNO0HT18GUzCWCgCI0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42/go.mod h1:rzfdUlfA+jdgLDmPKjd3Chq9V7LVLYo1Nz++Wb91aRo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 h1:6lJvvkQ9HmbHZ4h/IEwclwv2mrTW8Uq1SOB/kXy0mfw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4/go.mod h1:1PrKYwxTM+zjpw9Y41KFtoJCQrJ34Z47Y4VgVbfndjo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 h1:m0QTSI6pZYJTk5WSKx3fm5cNW/DCicVzULBgU/6IyD0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14/go.mod h1:dDilntgHy9WnHXsh7dDtUPgHKEfTJIBUTHM8OWm0f/0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 h1:eev2yZX7esGRjqRbnVk1UxMLw4CyVZDpZXRCcy75oQk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36/go.mod h1:lGnOkH9NJATw0XEPcAknFBj3zzNTEGRHtSw+CwC1YTg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.1 h1:PT6PBCycRwhpEW5hJnRiceCeoWJ+r3bdgXtV+VKG7Pk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.1/go.mod h1:TqoxCLwT2nrxrBGA+z7t6OWM7LBkgRckK3gOjYE+7JA=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.2 h1:v346f1h8sUBKXnEbrv43L37MTBlFHyKXQPIZHNAaghA=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.2/go.mod h1:cwCATiyNrXK9P2FsWdZ89g9mpsYv2rhk0UA/KByl5fY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 h1:v0jkRigbSD6uOdwcaUQmgEwG1BkPfAPDqaeNt/29ghg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4/go.mod h1:LhTyt8J04LL+9cIt7pYJ5lbS/U98ZmXovLOR/4LUsk8=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5 h1:A42xdtStObqy7NGvzZKpnyNXvoOmm+FENobZ0/ssHWk=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5/go.mod h1:rDGMZA7f4pbmTtPOk5v5UM2lmX6UAbRnMDJeDvnH7AM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.21.1 h1:Q01Dph/7FaB41Z7EY+SoVPa/kMpLGFiQPmF2PpVzaCE=
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.21.1/go.mod h1:laHbYFVzphXdCiT3gitfuCDA2Oukrt9p40jWK7OJLgc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.24.1 h1:KbGaxApdPOT2ZWqJiQY5ApnpNhUGbGTjYiKAidlFwp8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.24.1/go.mod h1:+phkm4aFvcM4jbsDRGoZ+mD8MMvksHF459Xpy5Z90f0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.2/go.mod h1:ju+nNXUunfIFamXUIZQiICjnO/TPlOmWcYhZcSy7xaE=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.5 h1:oCvTFSDi67AX0pOX3PuPdGFewvLRU2zzFSrTsgURNo0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.5/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.2/go.mod h1:ubDBBaDFs1GHijSOTi8ljppML15GLG0HxhILtbjNNYQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 h1:dnInJb4S0oy8aQuri1mV6ipLlnZPfnsDNB9BGO9PDNY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5/go.mod h1:yygr8ACQRY2PrEcy3xsUI357stq2AxnFM6DIsR9lij4=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.21.2/go.mod h1:FQ/DQcOfESELfJi5ED+IPPAjI5xC6nxtSolVVB773jM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.6 h1:2PylFCfKCEDv6PeSN09pC/VUiRd10wi1VfHG5FrW0/g=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.6/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.6 h1:pSB560BbVj9ZlJZF4WYj5zsytWHWKxg+NgyGV4B2L58=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.6/go.mod h1:yygr8ACQRY2PrEcy3xsUI357stq2AxnFM6DIsR9lij4=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 h1:CQBFElb0LS8RojMJlxRSo/HXipvTZW2S44Lt9Mk2aYQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.21.5/go.mod h1:VC7JDqsqiwXukYEDjoHh9U0fOJtNWh04FPQz4ct4GGU=
|
||||
github.com/aws/smithy-go v1.14.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/aws/smithy-go v1.14.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ=
|
||||
github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
@@ -422,13 +412,14 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
|
||||
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
|
||||
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
|
||||
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
|
||||
@@ -450,8 +441,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hanwen/go-fuse/v2 v2.3.0 h1:t5ivNIH2PK+zw4OBul/iJjsoG9K6kXo4nMDoBpciC8A=
|
||||
github.com/hanwen/go-fuse/v2 v2.3.0/go.mod h1:xKwi1cF7nXAOBCXujD5ie0ZKsxc8GGSA1rlMJc+8IJs=
|
||||
github.com/hanwen/go-fuse/v2 v2.4.0 h1:12OhD7CkXXQdvxG2osIdBQLdXh+nmLXY9unkUIe/xaU=
|
||||
github.com/hanwen/go-fuse/v2 v2.4.0/go.mod h1:xKwi1cF7nXAOBCXujD5ie0ZKsxc8GGSA1rlMJc+8IJs=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -756,6 +747,8 @@ github.com/rclone/rclone v1.63.1 h1:iITCUNBfAXnguHjRPFq+w/gGIW0L0las78h4H5CH2Ms=
|
||||
github.com/rclone/rclone v1.63.1/go.mod h1:eUQaKsf1wJfHKB0RDoM8RaPAeRB2eI/Qw+Vc9Ho5FGM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rdleal/intervalst v0.0.0-20221028215511-a098aa0d2cb8 h1:5jSBlCYQYquRF8Zch4QrimJcX7/H1qbWQEAzYNxMubc=
|
||||
github.com/rdleal/intervalst v0.0.0-20221028215511-a098aa0d2cb8/go.mod h1:xO89Z6BC+LQDH+IPQQw/OESt5UADgFD41tYMUINGpxQ=
|
||||
github.com/redis/go-redis/v9 v9.0.2 h1:BA426Zqe/7r56kCcvxYLWe1mkaz71LKF77GwgFzSxfE=
|
||||
github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps=
|
||||
github.com/rekby/fixenv v0.3.2/go.mod h1:/b5LRc06BYJtslRtHKxsPWFT/ySpHV+rWvzTg+XWk4c=
|
||||
@@ -986,13 +979,12 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
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-20220314234659-1baeb1ce4c0b/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.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
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=
|
||||
@@ -1094,8 +1086,8 @@ golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
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=
|
||||
@@ -1105,8 +1097,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
|
||||
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
|
||||
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
|
||||
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -1215,8 +1207,8 @@ golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
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=
|
||||
@@ -1231,8 +1223,9 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -1329,8 +1322,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.134.0 h1:ktL4Goua+UBgoP1eL1/60LwZJqa1sIzkLmvoR3hR6Gw=
|
||||
google.golang.org/api v0.134.0/go.mod h1:sjRL3UnjTx5UqNQS9EWr9N8p7xbHpy1k0XGRLCf3Spk=
|
||||
google.golang.org/api v0.141.0 h1:Df6vfMgDoIM6ss0m7H4MPwFwY87WNXHfBIda/Bmfl4E=
|
||||
google.golang.org/api v0.141.0/go.mod h1:iZqLkdPlXKyG0b90eu6KxVSE4D/ccRF2e/doKD2CnQQ=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -1380,12 +1373,12 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/genproto v0.0.0-20230731193218-e0aa005b6bdf h1:v5Cf4E9+6tawYrs/grq1q1hFpGtzlGFzgWHqwt6NFiU=
|
||||
google.golang.org/genproto v0.0.0-20230731193218-e0aa005b6bdf/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230731193218-e0aa005b6bdf h1:xkVZ5FdZJF4U82Q/JS+DcZA83s/GRVL+QrFMlexk9Yo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230731193218-e0aa005b6bdf/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf h1:guOdSPaeFgN+jEJwTo1dQ71hdBm+yKSCCKuTRkJzcVo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 h1:nIgk/EEq3/YlnmVVXVnm14rC2oxgs1o0ong4sD/rd44=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832 h1:o4LtQxebKIJ4vkzyhtD2rfUNZ20Zf0ik5YVP5E7G7VE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -1411,8 +1404,8 @@ google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
|
||||
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
|
||||
google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o=
|
||||
google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/grpc/examples v0.0.0-20201112215255-90f1b3ee835b h1:NuxyvVZoDfHZwYW9LD4GJiF5/nhiSyP4/InTrvw9Ibk=
|
||||
google.golang.org/grpc/examples v0.0.0-20201112215255-90f1b3ee835b/go.mod h1:IBqQ7wSUJ2Ep09a8rMWFsg4fmI2r38zwsq8a0GgxXpM=
|
||||
google.golang.org/grpc/security/advancedtls v0.0.0-20220622233350-5cdb09fa29c1 h1:0emxaJWaG6CfrA9Nbe4aHWbFz5AXw2QPEJP0/f42LCE=
|
||||
@@ -1484,8 +1477,8 @@ modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
|
||||
modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
|
||||
modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
apiVersion: v1
|
||||
description: SeaweedFS
|
||||
name: seaweedfs
|
||||
appVersion: "3.56"
|
||||
version: "3.56"
|
||||
appVersion: "3.57"
|
||||
version: 3.57.0
|
||||
|
||||
@@ -280,7 +280,7 @@ volume:
|
||||
# should map directly to the value of the resources field for a PodSpec,
|
||||
# formatted as a multi-line string. By default no direct resource request
|
||||
# is made.
|
||||
resources: {}
|
||||
resources: null
|
||||
|
||||
# Toleration Settings for server pods
|
||||
# This should be a multi-line string matching the Toleration array
|
||||
|
||||
@@ -69,10 +69,13 @@ service SeaweedFiler {
|
||||
rpc CacheRemoteObjectToLocalCluster (CacheRemoteObjectToLocalClusterRequest) returns (CacheRemoteObjectToLocalClusterResponse) {
|
||||
}
|
||||
|
||||
rpc Lock(LockRequest) returns (LockResponse) {
|
||||
rpc DistributedLock(LockRequest) returns (LockResponse) {
|
||||
}
|
||||
rpc Unlock(UnlockRequest) returns (UnlockResponse) {
|
||||
rpc DistributedUnlock(UnlockRequest) returns (UnlockResponse) {
|
||||
}
|
||||
rpc FindLockOwner(FindLockOwnerRequest) returns (FindLockOwnerResponse) {
|
||||
}
|
||||
// distributed lock management internal use only
|
||||
rpc TransferLocks(TransferLocksRequest) returns (TransferLocksResponse) {
|
||||
}
|
||||
}
|
||||
@@ -444,6 +447,7 @@ message LockRequest {
|
||||
int64 seconds_to_lock = 2;
|
||||
string renew_token = 3;
|
||||
bool is_moved = 4;
|
||||
string owner = 5;
|
||||
}
|
||||
message LockResponse {
|
||||
string renew_token = 1;
|
||||
@@ -459,10 +463,18 @@ message UnlockResponse {
|
||||
string error = 1;
|
||||
string moved_to = 2;
|
||||
}
|
||||
message FindLockOwnerRequest {
|
||||
string name = 1;
|
||||
bool is_moved = 2;
|
||||
}
|
||||
message FindLockOwnerResponse {
|
||||
string owner = 1;
|
||||
}
|
||||
message Lock {
|
||||
string name = 1;
|
||||
string renew_token = 2;
|
||||
int64 expired_at_ns = 3;
|
||||
string owner = 4;
|
||||
}
|
||||
message TransferLocksRequest {
|
||||
repeated Lock locks = 1;
|
||||
|
||||
+5
-1
@@ -7,7 +7,7 @@ all: install
|
||||
.PHONY : clean debug_mount
|
||||
|
||||
install:
|
||||
go install
|
||||
go install -ldflags="-s -w"
|
||||
|
||||
clean:
|
||||
go clean $(SOURCE_DIR)
|
||||
@@ -37,6 +37,10 @@ debug_s3:
|
||||
go build -gcflags="all=-N -l"
|
||||
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./weed -- -v=4 s3
|
||||
|
||||
debug_mq:
|
||||
go build -gcflags="all=-N -l"
|
||||
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./weed -- -v=4 mq.broker
|
||||
|
||||
debug_filer_copy:
|
||||
go build -gcflags="all=-N -l"
|
||||
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./weed -- -v=4 filer.backup -filer=localhost:8888 -filerProxy -timeAgo=10h
|
||||
|
||||
+65
-17
@@ -16,13 +16,15 @@ type LockClient struct {
|
||||
grpcDialOption grpc.DialOption
|
||||
maxLockDuration time.Duration
|
||||
sleepDuration time.Duration
|
||||
seedFiler pb.ServerAddress
|
||||
}
|
||||
|
||||
func NewLockClient(grpcDialOption grpc.DialOption) *LockClient {
|
||||
func NewLockClient(grpcDialOption grpc.DialOption, seedFiler pb.ServerAddress) *LockClient {
|
||||
return &LockClient{
|
||||
grpcDialOption: grpcDialOption,
|
||||
maxLockDuration: 5 * time.Second,
|
||||
sleepDuration: 4 * time.Millisecond,
|
||||
sleepDuration: 2473 * time.Millisecond,
|
||||
seedFiler: seedFiler,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,25 +36,62 @@ type LiveLock struct {
|
||||
cancelCh chan struct{}
|
||||
grpcDialOption grpc.DialOption
|
||||
isLocked bool
|
||||
}
|
||||
|
||||
// NewLockWithTimeout locks the key with the given duration
|
||||
func (lc *LockClient) NewLockWithTimeout(filer pb.ServerAddress, key string, lockDuration time.Duration) (lock *LiveLock) {
|
||||
return lc.doNewLock(filer, key, lockDuration)
|
||||
owner string
|
||||
lc *LockClient
|
||||
}
|
||||
|
||||
// NewLock creates a lock with a very long duration
|
||||
func (lc *LockClient) NewLock(filer pb.ServerAddress, key string) (lock *LiveLock) {
|
||||
return lc.doNewLock(filer, key, lock_manager.MaxDuration)
|
||||
func (lc *LockClient) NewLock(key string, owner string) (lock *LiveLock) {
|
||||
return lc.doNewLock(key, lock_manager.MaxDuration, owner)
|
||||
}
|
||||
|
||||
func (lc *LockClient) doNewLock(filer pb.ServerAddress, key string, lockDuration time.Duration) (lock *LiveLock) {
|
||||
// StartLock starts a goroutine to lock the key and returns immediately.
|
||||
func (lc *LockClient) StartLock(key string, owner string) (lock *LiveLock) {
|
||||
lock = &LiveLock{
|
||||
key: key,
|
||||
filer: filer,
|
||||
filer: lc.seedFiler,
|
||||
cancelCh: make(chan struct{}),
|
||||
expireAtNs: time.Now().Add(lock_manager.MaxDuration).UnixNano(),
|
||||
grpcDialOption: lc.grpcDialOption,
|
||||
owner: owner,
|
||||
lc: lc,
|
||||
}
|
||||
go func() {
|
||||
util.RetryForever("create lock:"+key, func() error {
|
||||
errorMessage, err := lock.doLock(lock_manager.MaxDuration)
|
||||
if err != nil {
|
||||
glog.Infof("create lock %s: %s", key, err)
|
||||
time.Sleep(time.Second)
|
||||
return err
|
||||
}
|
||||
if errorMessage != "" {
|
||||
glog.Infof("create lock %s: %s", key, errorMessage)
|
||||
time.Sleep(time.Second)
|
||||
return fmt.Errorf("%v", errorMessage)
|
||||
}
|
||||
lock.isLocked = true
|
||||
return nil
|
||||
}, func(err error) (shouldContinue bool) {
|
||||
if err != nil {
|
||||
glog.Warningf("create lock %s: %s", key, err)
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
return lock.renewToken == ""
|
||||
})
|
||||
lc.keepLock(lock)
|
||||
}()
|
||||
return
|
||||
}
|
||||
|
||||
func (lc *LockClient) doNewLock(key string, lockDuration time.Duration, owner string) (lock *LiveLock) {
|
||||
lock = &LiveLock{
|
||||
key: key,
|
||||
filer: lc.seedFiler,
|
||||
cancelCh: make(chan struct{}),
|
||||
expireAtNs: time.Now().Add(lockDuration).UnixNano(),
|
||||
grpcDialOption: lc.grpcDialOption,
|
||||
owner: owner,
|
||||
lc: lc,
|
||||
}
|
||||
var needRenewal bool
|
||||
if lockDuration > lc.maxLockDuration {
|
||||
@@ -62,11 +101,14 @@ func (lc *LockClient) doNewLock(filer pb.ServerAddress, key string, lockDuration
|
||||
util.RetryForever("create lock:"+key, func() error {
|
||||
errorMessage, err := lock.doLock(lockDuration)
|
||||
if err != nil {
|
||||
time.Sleep(time.Second)
|
||||
return err
|
||||
}
|
||||
if errorMessage != "" {
|
||||
time.Sleep(time.Second)
|
||||
return fmt.Errorf("%v", errorMessage)
|
||||
}
|
||||
lock.isLocked = true
|
||||
return nil
|
||||
}, func(err error) (shouldContinue bool) {
|
||||
if err != nil {
|
||||
@@ -75,8 +117,6 @@ func (lc *LockClient) doNewLock(filer pb.ServerAddress, key string, lockDuration
|
||||
return lock.renewToken == ""
|
||||
})
|
||||
|
||||
lock.isLocked = true
|
||||
|
||||
if needRenewal {
|
||||
go lc.keepLock(lock)
|
||||
}
|
||||
@@ -88,10 +128,13 @@ func (lock *LiveLock) IsLocked() bool {
|
||||
return lock.isLocked
|
||||
}
|
||||
|
||||
func (lock *LiveLock) Unlock() error {
|
||||
func (lock *LiveLock) StopLock() error {
|
||||
close(lock.cancelCh)
|
||||
if !lock.isLocked {
|
||||
return nil
|
||||
}
|
||||
return pb.WithFilerClient(false, 0, lock.filer, lock.grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
|
||||
_, err := client.Unlock(context.Background(), &filer_pb.UnlockRequest{
|
||||
_, err := client.DistributedUnlock(context.Background(), &filer_pb.UnlockRequest{
|
||||
Name: lock.key,
|
||||
RenewToken: lock.renewToken,
|
||||
})
|
||||
@@ -100,9 +143,10 @@ func (lock *LiveLock) Unlock() error {
|
||||
}
|
||||
|
||||
func (lc *LockClient) keepLock(lock *LiveLock) {
|
||||
ticker := time.Tick(lc.sleepDuration)
|
||||
for {
|
||||
select {
|
||||
case <-time.After(lc.sleepDuration):
|
||||
case <-ticker:
|
||||
// renew the lock if lock.expireAtNs is still greater than now
|
||||
util.RetryForever("keep lock:"+lock.key, func() error {
|
||||
lockDuration := time.Duration(lock.expireAtNs-time.Now().UnixNano()) * time.Nanosecond
|
||||
@@ -116,10 +160,12 @@ func (lc *LockClient) keepLock(lock *LiveLock) {
|
||||
errorMessage, err := lock.doLock(lockDuration)
|
||||
if err != nil {
|
||||
lock.isLocked = false
|
||||
time.Sleep(time.Second)
|
||||
return err
|
||||
}
|
||||
if errorMessage != "" {
|
||||
lock.isLocked = false
|
||||
time.Sleep(time.Second)
|
||||
return fmt.Errorf("%v", errorMessage)
|
||||
}
|
||||
return nil
|
||||
@@ -141,11 +187,12 @@ func (lc *LockClient) keepLock(lock *LiveLock) {
|
||||
|
||||
func (lock *LiveLock) doLock(lockDuration time.Duration) (errorMessage string, err error) {
|
||||
err = pb.WithFilerClient(false, 0, lock.filer, lock.grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
|
||||
resp, err := client.Lock(context.Background(), &filer_pb.LockRequest{
|
||||
resp, err := client.DistributedLock(context.Background(), &filer_pb.LockRequest{
|
||||
Name: lock.key,
|
||||
SecondsToLock: int64(lockDuration.Seconds()),
|
||||
RenewToken: lock.renewToken,
|
||||
IsMoved: false,
|
||||
Owner: lock.owner,
|
||||
})
|
||||
if err == nil {
|
||||
lock.renewToken = resp.RenewToken
|
||||
@@ -154,6 +201,7 @@ func (lock *LiveLock) doLock(lockDuration time.Duration) (errorMessage string, e
|
||||
errorMessage = resp.Error
|
||||
if resp.MovedTo != "" {
|
||||
lock.filer = pb.ServerAddress(resp.MovedTo)
|
||||
lock.lc.seedFiler = lock.filer
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -24,23 +24,38 @@ func NewDistributedLockManager(host pb.ServerAddress) *DistributedLockManager {
|
||||
}
|
||||
}
|
||||
|
||||
func (dlm *DistributedLockManager) Lock(key string, token string) (renewToken string, movedTo pb.ServerAddress, err error) {
|
||||
return dlm.LockWithTimeout(key, MaxDuration, token)
|
||||
func (dlm *DistributedLockManager) LockWithTimeout(key string, expiredAtNs int64, token string, owner string) (renewToken string, movedTo pb.ServerAddress, err error) {
|
||||
movedTo, err = dlm.findLockOwningFiler(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if movedTo != dlm.Host {
|
||||
return
|
||||
}
|
||||
renewToken, err = dlm.lockManager.Lock(key, expiredAtNs, token, owner)
|
||||
return
|
||||
}
|
||||
|
||||
func (dlm *DistributedLockManager) LockWithTimeout(key string, expiredAtNs int64, token string) (renewToken string, movedTo pb.ServerAddress, err error) {
|
||||
func (dlm *DistributedLockManager) findLockOwningFiler(key string) (movedTo pb.ServerAddress, err error) {
|
||||
servers := dlm.LockRing.GetSnapshot()
|
||||
if servers == nil {
|
||||
err = NoLockServerError
|
||||
return
|
||||
}
|
||||
|
||||
server := hashKeyToServer(key, servers)
|
||||
if server != dlm.Host {
|
||||
movedTo = server
|
||||
movedTo = hashKeyToServer(key, servers)
|
||||
return
|
||||
}
|
||||
|
||||
func (dlm *DistributedLockManager) FindLockOwner(key string) (owner string, movedTo pb.ServerAddress, err error) {
|
||||
movedTo, err = dlm.findLockOwningFiler(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
renewToken, err = dlm.lockManager.Lock(key, expiredAtNs, token)
|
||||
if movedTo != dlm.Host {
|
||||
return
|
||||
}
|
||||
owner, err = dlm.lockManager.GetLockOwner(key)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -62,8 +77,8 @@ func (dlm *DistributedLockManager) Unlock(key string, token string) (movedTo pb.
|
||||
|
||||
// InsertLock is used to insert a lock to a server unconditionally
|
||||
// It is used when a server is down and the lock is moved to another server
|
||||
func (dlm *DistributedLockManager) InsertLock(key string, expiredAtNs int64, token string) {
|
||||
dlm.lockManager.InsertLock(key, expiredAtNs, token)
|
||||
func (dlm *DistributedLockManager) InsertLock(key string, expiredAtNs int64, token string, owner string) {
|
||||
dlm.lockManager.InsertLock(key, expiredAtNs, token, owner)
|
||||
}
|
||||
func (dlm *DistributedLockManager) SelectNotOwnedLocks(servers []pb.ServerAddress) (locks []*Lock) {
|
||||
return dlm.lockManager.SelectLocks(func(key string) bool {
|
||||
|
||||
@@ -12,7 +12,7 @@ var LockErrorNonEmptyTokenOnExpiredLock = fmt.Errorf("lock: non-empty token on a
|
||||
var LockErrorTokenMismatch = fmt.Errorf("lock: token mismatch")
|
||||
var UnlockErrorTokenMismatch = fmt.Errorf("unlock: token mismatch")
|
||||
|
||||
// LockManager lock manager
|
||||
// LockManager local lock manager, used by distributed lock manager
|
||||
type LockManager struct {
|
||||
locks *xsync.MapOf[string, *Lock]
|
||||
}
|
||||
@@ -20,6 +20,7 @@ type Lock struct {
|
||||
Token string
|
||||
ExpiredAtNs int64
|
||||
Key string // only used for moving locks
|
||||
Owner string
|
||||
}
|
||||
|
||||
func NewLockManager() *LockManager {
|
||||
@@ -30,7 +31,7 @@ func NewLockManager() *LockManager {
|
||||
return t
|
||||
}
|
||||
|
||||
func (lm *LockManager) Lock(path string, expiredAtNs int64, token string) (renewToken string, err error) {
|
||||
func (lm *LockManager) Lock(path string, expiredAtNs int64, token string, owner string) (renewToken string, err error) {
|
||||
lm.locks.Compute(path, func(oldValue *Lock, loaded bool) (newValue *Lock, delete bool) {
|
||||
if oldValue != nil {
|
||||
if oldValue.ExpiredAtNs > 0 && oldValue.ExpiredAtNs < time.Now().UnixNano() {
|
||||
@@ -41,14 +42,14 @@ func (lm *LockManager) Lock(path string, expiredAtNs int64, token string) (renew
|
||||
} else {
|
||||
// new lock
|
||||
renewToken = uuid.New().String()
|
||||
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs}, false
|
||||
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs, Owner: owner}, false
|
||||
}
|
||||
}
|
||||
// not expired
|
||||
if oldValue.Token == token {
|
||||
// token matches, renew the lock
|
||||
renewToken = uuid.New().String()
|
||||
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs}, false
|
||||
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs, Owner: owner}, false
|
||||
} else {
|
||||
err = LockErrorTokenMismatch
|
||||
return oldValue, false
|
||||
@@ -57,7 +58,7 @@ func (lm *LockManager) Lock(path string, expiredAtNs int64, token string) (renew
|
||||
if token == "" {
|
||||
// new lock
|
||||
renewToken = uuid.New().String()
|
||||
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs}, false
|
||||
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs, Owner: owner}, false
|
||||
} else {
|
||||
err = LockErrorNonEmptyTokenOnNewLock
|
||||
return nil, false
|
||||
@@ -132,6 +133,18 @@ func (lm *LockManager) SelectLocks(selectFn func(key string) bool) (locks []*Loc
|
||||
}
|
||||
|
||||
// InsertLock inserts a lock unconditionally
|
||||
func (lm *LockManager) InsertLock(path string, expiredAtNs int64, token string) {
|
||||
lm.locks.Store(path, &Lock{Token: token, ExpiredAtNs: expiredAtNs})
|
||||
func (lm *LockManager) InsertLock(path string, expiredAtNs int64, token string, owner string) {
|
||||
lm.locks.Store(path, &Lock{Token: token, ExpiredAtNs: expiredAtNs, Owner: owner})
|
||||
}
|
||||
|
||||
func (lm *LockManager) GetLockOwner(key string) (owner string, err error) {
|
||||
lm.locks.Range(func(k string, lock *Lock) bool {
|
||||
if k == key && lock != nil {
|
||||
owner = lock.Owner
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
@@ -292,10 +292,8 @@ func (fsw *FilerStoreWrapper) prefixFilterEntries(ctx context.Context, dirPath u
|
||||
|
||||
count := int64(0)
|
||||
for count < limit && len(notPrefixed) > 0 {
|
||||
var isLastItemHasPrefix bool
|
||||
for _, entry := range notPrefixed {
|
||||
if strings.HasPrefix(entry.Name(), prefix) {
|
||||
isLastItemHasPrefix = true
|
||||
count++
|
||||
if !eachEntryFunc(entry) {
|
||||
return
|
||||
@@ -303,11 +301,9 @@ func (fsw *FilerStoreWrapper) prefixFilterEntries(ctx context.Context, dirPath u
|
||||
if count >= limit {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
isLastItemHasPrefix = false
|
||||
}
|
||||
}
|
||||
if count < limit && isLastItemHasPrefix && len(notPrefixed) == int(limit) {
|
||||
if count < limit && lastFileName <= prefix && len(notPrefixed) == int(limit) {
|
||||
notPrefixed = notPrefixed[:0]
|
||||
lastFileName, err = actualStore.ListDirectoryEntries(ctx, dirPath, lastFileName, false, limit, func(entry *Entry) bool {
|
||||
notPrefixed = append(notPrefixed, entry)
|
||||
|
||||
@@ -21,14 +21,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
charsetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
charset = charsetUpper + "abcdefghijklmnopqrstuvwxyz/"
|
||||
policyDocumentVersion = "2012-10-17"
|
||||
StatementActionAdmin = "*"
|
||||
StatementActionWrite = "Put*"
|
||||
StatementActionRead = "Get*"
|
||||
StatementActionList = "List*"
|
||||
StatementActionTagging = "Tagging*"
|
||||
charsetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
charset = charsetUpper + "abcdefghijklmnopqrstuvwxyz/"
|
||||
policyDocumentVersion = "2012-10-17"
|
||||
StatementActionAdmin = "*"
|
||||
StatementActionWrite = "Put*"
|
||||
StatementActionWriteAcp = "PutBucketAcl"
|
||||
StatementActionRead = "Get*"
|
||||
StatementActionReadAcp = "GetBucketAcl"
|
||||
StatementActionList = "List*"
|
||||
StatementActionTagging = "Tagging*"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -44,8 +46,12 @@ func MapToStatementAction(action string) string {
|
||||
return s3_constants.ACTION_ADMIN
|
||||
case StatementActionWrite:
|
||||
return s3_constants.ACTION_WRITE
|
||||
case StatementActionWriteAcp:
|
||||
return s3_constants.ACTION_WRITE_ACP
|
||||
case StatementActionRead:
|
||||
return s3_constants.ACTION_READ
|
||||
case StatementActionReadAcp:
|
||||
return s3_constants.ACTION_READ_ACP
|
||||
case StatementActionList:
|
||||
return s3_constants.ACTION_LIST
|
||||
case StatementActionTagging:
|
||||
@@ -61,8 +67,12 @@ func MapToIdentitiesAction(action string) string {
|
||||
return StatementActionAdmin
|
||||
case s3_constants.ACTION_WRITE:
|
||||
return StatementActionWrite
|
||||
case s3_constants.ACTION_WRITE_ACP:
|
||||
return StatementActionWriteAcp
|
||||
case s3_constants.ACTION_READ:
|
||||
return StatementActionRead
|
||||
case s3_constants.ACTION_READ_ACP:
|
||||
return StatementActionReadAcp
|
||||
case s3_constants.ACTION_LIST:
|
||||
return StatementActionList
|
||||
case s3_constants.ACTION_TAGGING:
|
||||
|
||||
@@ -52,7 +52,10 @@ func NewIamApiServer(router *mux.Router, option *IamServerOption) (iamApiServer
|
||||
option: option,
|
||||
masterClient: wdclient.NewMasterClient(option.GrpcDialOption, "", "iam", "", "", "", *pb.NewServiceDiscoveryFromMap(option.Masters)),
|
||||
}
|
||||
s3Option := s3api.S3ApiServerOption{Filer: option.Filer}
|
||||
s3Option := s3api.S3ApiServerOption{
|
||||
Filer: option.Filer,
|
||||
GrpcDialOption: option.GrpcDialOption,
|
||||
}
|
||||
iamApiServer = &IamApiServer{
|
||||
s3ApiConfig: s3ApiConfigure,
|
||||
iam: s3api.NewIdentityAccessManagement(&s3Option),
|
||||
|
||||
@@ -2,11 +2,12 @@ package mount
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mount/page_writer"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type ChunkedDirtyPages struct {
|
||||
@@ -82,7 +83,7 @@ func (pages *ChunkedDirtyPages) saveChunkedFileIntervalToStorage(reader io.Reade
|
||||
|
||||
}
|
||||
|
||||
func (pages ChunkedDirtyPages) Destroy() {
|
||||
func (pages *ChunkedDirtyPages) Destroy() {
|
||||
pages.uploadPipeline.Shutdown()
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ type FileHandle struct {
|
||||
dirtyPages *PageWriter
|
||||
reader *filer.ChunkReadAt
|
||||
contentType string
|
||||
sync.RWMutex
|
||||
|
||||
isDeleted bool
|
||||
|
||||
@@ -102,8 +101,9 @@ func (fh *FileHandle) AddChunks(chunks []*filer_pb.FileChunk) {
|
||||
}
|
||||
|
||||
func (fh *FileHandle) ReleaseHandle() {
|
||||
fh.Lock()
|
||||
defer fh.Unlock()
|
||||
|
||||
fhActiveLock := fh.wfs.fhLockTable.AcquireLock("ReleaseHandle", fh.fh, util.ExclusiveLock)
|
||||
defer fh.wfs.fhLockTable.ReleaseLock(fh.fh, fhActiveLock)
|
||||
|
||||
fh.entryLock.Lock()
|
||||
defer fh.entryLock.Unlock()
|
||||
|
||||
@@ -78,6 +78,7 @@ type WFS struct {
|
||||
dhmap *DirectoryHandleToInode
|
||||
fuseServer *fuse.Server
|
||||
IsOverQuota bool
|
||||
fhLockTable *util.LockTable[FileHandleId]
|
||||
}
|
||||
|
||||
func NewSeaweedFileSystem(option *Option) *WFS {
|
||||
@@ -88,6 +89,7 @@ func NewSeaweedFileSystem(option *Option) *WFS {
|
||||
inodeToPath: NewInodeToPath(util.FullPath(option.FilerMountRootPath)),
|
||||
fhmap: NewFileHandleToInode(),
|
||||
dhmap: NewDirectoryHandleToInode(),
|
||||
fhLockTable: util.NewLockTable[FileHandleId](),
|
||||
}
|
||||
|
||||
wfs.option.filerIndex = int32(rand.Intn(len(option.FilerAddresses)))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mount
|
||||
|
||||
import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -44,16 +45,16 @@ func (wfs *WFS) CopyFileRange(cancel <-chan struct{}, in *fuse.CopyFileRangeIn)
|
||||
}
|
||||
|
||||
// lock source and target file handles
|
||||
fhOut.Lock()
|
||||
defer fhOut.Unlock()
|
||||
fhOutActiveLock := fhOut.wfs.fhLockTable.AcquireLock("CopyFileRange", fhOut.fh, util.ExclusiveLock)
|
||||
defer fhOut.wfs.fhLockTable.ReleaseLock(fhOut.fh, fhOutActiveLock)
|
||||
|
||||
if fhOut.entry == nil {
|
||||
return 0, fuse.ENOENT
|
||||
}
|
||||
|
||||
if fhIn.fh != fhOut.fh {
|
||||
fhIn.RLock()
|
||||
defer fhIn.RUnlock()
|
||||
fhInActiveLock := fhIn.wfs.fhLockTable.AcquireLock("CopyFileRange", fhIn.fh, util.SharedLock)
|
||||
defer fhIn.wfs.fhLockTable.ReleaseLock(fhIn.fh, fhInActiveLock)
|
||||
}
|
||||
|
||||
// directories are not supported
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mount
|
||||
|
||||
import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
"syscall"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
@@ -35,8 +36,8 @@ func (wfs *WFS) Lseek(cancel <-chan struct{}, in *fuse.LseekIn, out *fuse.LseekO
|
||||
}
|
||||
|
||||
// lock the file until the proper offset was calculated
|
||||
fh.RLock()
|
||||
defer fh.RUnlock()
|
||||
fhActiveLock := fh.wfs.fhLockTable.AcquireLock("Lseek", fh.fh, util.SharedLock)
|
||||
defer fh.wfs.fhLockTable.ReleaseLock(fh.fh, fhActiveLock)
|
||||
fh.entryLock.RLock()
|
||||
defer fh.entryLock.RUnlock()
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package mount
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
"io"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
@@ -41,8 +42,8 @@ func (wfs *WFS) Read(cancel <-chan struct{}, in *fuse.ReadIn, buff []byte) (fuse
|
||||
return nil, fuse.ENOENT
|
||||
}
|
||||
|
||||
fh.RLock()
|
||||
defer fh.RUnlock()
|
||||
fhActiveLock := fh.wfs.fhLockTable.AcquireLock("Read", fh.fh, util.SharedLock)
|
||||
defer fh.wfs.fhLockTable.ReleaseLock(fh.fh, fhActiveLock)
|
||||
|
||||
offset := int64(in.Offset)
|
||||
totalRead, err := readDataByFileHandle(buff, fh, offset)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/filer"
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
@@ -89,8 +90,6 @@ func (wfs *WFS) Fsync(cancel <-chan struct{}, in *fuse.FsyncIn) (code fuse.Statu
|
||||
}
|
||||
|
||||
func (wfs *WFS) doFlush(fh *FileHandle, uid, gid uint32) fuse.Status {
|
||||
fh.Lock()
|
||||
defer fh.Unlock()
|
||||
|
||||
// flush works at fh level
|
||||
fileFullPath := fh.FullPath()
|
||||
@@ -105,6 +104,9 @@ func (wfs *WFS) doFlush(fh *FileHandle, uid, gid uint32) fuse.Status {
|
||||
}
|
||||
}
|
||||
|
||||
fhActiveLock := fh.wfs.fhLockTable.AcquireLock("doFlush", fh.fh, util.ExclusiveLock)
|
||||
defer fh.wfs.fhLockTable.ReleaseLock(fh.fh, fhActiveLock)
|
||||
|
||||
if !fh.dirtyMetadata {
|
||||
return fuse.OK
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package mount
|
||||
|
||||
import (
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
"net/http"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -48,8 +49,8 @@ func (wfs *WFS) Write(cancel <-chan struct{}, in *fuse.WriteIn, data []byte) (wr
|
||||
|
||||
tsNs := time.Now().UnixNano()
|
||||
|
||||
fh.Lock()
|
||||
defer fh.Unlock()
|
||||
fhActiveLock := fh.wfs.fhLockTable.AcquireLock("Write", fh.fh, util.ExclusiveLock)
|
||||
defer fh.wfs.fhLockTable.ReleaseLock(fh.fh, fhActiveLock)
|
||||
|
||||
entry := fh.GetEntry()
|
||||
if entry == nil {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package balancer
|
||||
|
||||
import (
|
||||
cmap "github.com/orcaman/concurrent-map/v2"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
func allocateTopicPartitions(brokers cmap.ConcurrentMap[string, *BrokerStats], partitionCount int32) (assignments []*mq_pb.BrokerPartitionAssignment) {
|
||||
// divide the ring into partitions
|
||||
rangeSize := MaxPartitionCount / partitionCount
|
||||
for i := int32(0); i < partitionCount; i++ {
|
||||
assignment := &mq_pb.BrokerPartitionAssignment{
|
||||
Partition: &mq_pb.Partition{
|
||||
RingSize: MaxPartitionCount,
|
||||
RangeStart: int32(i * rangeSize),
|
||||
RangeStop: int32((i + 1) * rangeSize),
|
||||
},
|
||||
}
|
||||
if i == partitionCount-1 {
|
||||
assignment.Partition.RangeStop = MaxPartitionCount
|
||||
}
|
||||
assignments = append(assignments, assignment)
|
||||
}
|
||||
|
||||
// pick the brokers
|
||||
pickedBrokers := pickBrokers(brokers, partitionCount)
|
||||
|
||||
// assign the partitions to brokers
|
||||
for i, assignment := range assignments {
|
||||
assignment.LeaderBroker = pickedBrokers[i]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// for now: randomly pick brokers
|
||||
// TODO pick brokers based on the broker stats
|
||||
func pickBrokers(brokers cmap.ConcurrentMap[string, *BrokerStats], count int32) []string {
|
||||
candidates := make([]string, 0, brokers.Count())
|
||||
for brokerStatsItem := range brokers.IterBuffered() {
|
||||
candidates = append(candidates, brokerStatsItem.Key)
|
||||
}
|
||||
pickedBrokers := make([]string, 0, count)
|
||||
for i := int32(0); i < count; i++ {
|
||||
p := rand.Int() % len(candidates)
|
||||
if p < 0 {
|
||||
p = -p
|
||||
}
|
||||
pickedBrokers = append(pickedBrokers, candidates[p])
|
||||
}
|
||||
return pickedBrokers
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package balancer
|
||||
|
||||
import (
|
||||
cmap "github.com/orcaman/concurrent-map/v2"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_allocateOneBroker(t *testing.T) {
|
||||
brokers := cmap.New[*BrokerStats]()
|
||||
brokers.SetIfAbsent("localhost:17777", &BrokerStats{
|
||||
TopicPartitionCount: 0,
|
||||
ConsumerCount: 0,
|
||||
CpuUsagePercent: 0,
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantAssignments []*mq_pb.BrokerPartitionAssignment
|
||||
}{
|
||||
{
|
||||
name: "test only one broker",
|
||||
args: args{
|
||||
brokers: brokers,
|
||||
partitionCount: 1,
|
||||
},
|
||||
wantAssignments: []*mq_pb.BrokerPartitionAssignment{
|
||||
{
|
||||
LeaderBroker: "localhost:17777",
|
||||
Partition: &mq_pb.Partition{
|
||||
RingSize: MaxPartitionCount,
|
||||
RangeStart: 0,
|
||||
RangeStop: MaxPartitionCount,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
testThem(t, tests)
|
||||
}
|
||||
|
||||
type args struct {
|
||||
brokers cmap.ConcurrentMap[string, *BrokerStats]
|
||||
partitionCount int
|
||||
}
|
||||
|
||||
func testThem(t *testing.T, tests []struct {
|
||||
name string
|
||||
args args
|
||||
wantAssignments []*mq_pb.BrokerPartitionAssignment
|
||||
}) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotAssignments := allocateTopicPartitions(tt.args.brokers, tt.args.partitionCount); !reflect.DeepEqual(gotAssignments, tt.wantAssignments) {
|
||||
t.Errorf("allocateTopicPartitions() = %v, want %v", gotAssignments, tt.wantAssignments)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package balancer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
cmap "github.com/orcaman/concurrent-map/v2"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
)
|
||||
|
||||
const (
|
||||
MaxPartitionCount = 8 * 9 * 5 * 7 //2520
|
||||
LockBrokerBalancer = "broker_balancer"
|
||||
)
|
||||
|
||||
type Balancer struct {
|
||||
Brokers cmap.ConcurrentMap[string, *BrokerStats]
|
||||
}
|
||||
|
||||
type BrokerStats struct {
|
||||
TopicPartitionCount int32
|
||||
ConsumerCount int32
|
||||
CpuUsagePercent int32
|
||||
Stats cmap.ConcurrentMap[string, *TopicPartitionStats]
|
||||
}
|
||||
|
||||
func (bs *BrokerStats) UpdateStats(stats *mq_pb.BrokerStats) {
|
||||
bs.TopicPartitionCount = int32(len(stats.Stats))
|
||||
bs.CpuUsagePercent = stats.CpuUsagePercent
|
||||
|
||||
var consumerCount int32
|
||||
currentTopicPartitions := bs.Stats.Items()
|
||||
for _, topicPartitionStats := range stats.Stats {
|
||||
tps := &TopicPartitionStats{
|
||||
TopicPartition: TopicPartition{
|
||||
Namespace: topicPartitionStats.Topic.Namespace,
|
||||
Topic: topicPartitionStats.Topic.Name,
|
||||
RangeStart: topicPartitionStats.Partition.RangeStart,
|
||||
RangeStop: topicPartitionStats.Partition.RangeStop,
|
||||
},
|
||||
ConsumerCount: topicPartitionStats.ConsumerCount,
|
||||
IsLeader: topicPartitionStats.IsLeader,
|
||||
}
|
||||
consumerCount += topicPartitionStats.ConsumerCount
|
||||
key := tps.TopicPartition.String()
|
||||
bs.Stats.Set(key, tps)
|
||||
delete(currentTopicPartitions, key)
|
||||
}
|
||||
// remove the topic partitions that are not in the stats
|
||||
for key := range currentTopicPartitions {
|
||||
bs.Stats.Remove(key)
|
||||
}
|
||||
bs.ConsumerCount = consumerCount
|
||||
|
||||
}
|
||||
|
||||
func (bs *BrokerStats) String() string {
|
||||
return fmt.Sprintf("BrokerStats{TopicPartitionCount:%d, ConsumerCount:%d, CpuUsagePercent:%d, Stats:%+v}",
|
||||
bs.TopicPartitionCount, bs.ConsumerCount, bs.CpuUsagePercent, bs.Stats.Items())
|
||||
}
|
||||
|
||||
type TopicPartition struct {
|
||||
Namespace string
|
||||
Topic string
|
||||
RangeStart int32
|
||||
RangeStop int32
|
||||
}
|
||||
|
||||
type TopicPartitionStats struct {
|
||||
TopicPartition
|
||||
ConsumerCount int32
|
||||
IsLeader bool
|
||||
}
|
||||
|
||||
func NewBalancer() *Balancer {
|
||||
return &Balancer{
|
||||
Brokers: cmap.New[*BrokerStats](),
|
||||
}
|
||||
}
|
||||
|
||||
func NewBrokerStats() *BrokerStats {
|
||||
return &BrokerStats{
|
||||
Stats: cmap.New[*TopicPartitionStats](),
|
||||
}
|
||||
}
|
||||
|
||||
func (tp *TopicPartition) String() string {
|
||||
return fmt.Sprintf("%v.%v-%04d-%04d", tp.Namespace, tp.Topic, tp.RangeStart, tp.RangeStop)
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package balancer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoBroker = errors.New("no broker")
|
||||
)
|
||||
|
||||
func (b *Balancer) LookupOrAllocateTopicPartitions(topic *mq_pb.Topic, publish bool, partitionCount int32) (assignments []*mq_pb.BrokerPartitionAssignment, err error) {
|
||||
// find existing topic partition assignments
|
||||
for brokerStatsItem := range b.Brokers.IterBuffered() {
|
||||
broker, brokerStats := brokerStatsItem.Key, brokerStatsItem.Val
|
||||
for topicPartitionStatsItem := range brokerStats.Stats.IterBuffered() {
|
||||
topicPartitionStat := topicPartitionStatsItem.Val
|
||||
if topicPartitionStat.TopicPartition.Namespace == topic.Namespace &&
|
||||
topicPartitionStat.TopicPartition.Topic == topic.Name {
|
||||
assignment := &mq_pb.BrokerPartitionAssignment{
|
||||
Partition: &mq_pb.Partition{
|
||||
RingSize: MaxPartitionCount,
|
||||
RangeStart: topicPartitionStat.RangeStart,
|
||||
RangeStop: topicPartitionStat.RangeStop,
|
||||
},
|
||||
}
|
||||
if topicPartitionStat.IsLeader {
|
||||
assignment.LeaderBroker = broker
|
||||
} else {
|
||||
assignment.FollowerBrokers = append(assignment.FollowerBrokers, broker)
|
||||
}
|
||||
assignments = append(assignments, assignment)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(assignments) > 0 {
|
||||
return assignments, nil
|
||||
}
|
||||
|
||||
// find the topic partitions on the filer
|
||||
// if the topic is not found
|
||||
// if the request is_for_publish
|
||||
// create the topic
|
||||
// if the request is_for_subscribe
|
||||
// return error not found
|
||||
// t := topic.FromPbTopic(request.Topic)
|
||||
if b.Brokers.IsEmpty() {
|
||||
return nil, ErrNoBroker
|
||||
}
|
||||
return allocateTopicPartitions(b.Brokers, partitionCount), nil
|
||||
}
|
||||
@@ -12,10 +12,6 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
MaxPartitionCount = 1024
|
||||
)
|
||||
|
||||
func (broker *MessageQueueBroker) FindBrokerLeader(c context.Context, request *mq_pb.FindBrokerLeaderRequest) (*mq_pb.FindBrokerLeaderResponse, error) {
|
||||
ret := &mq_pb.FindBrokerLeaderResponse{}
|
||||
err := broker.withMasterClient(false, broker.MasterClient.GetMaster(), func(client master_pb.SeaweedClient) error {
|
||||
@@ -88,69 +84,38 @@ func (broker *MessageQueueBroker) CheckBrokerLoad(c context.Context, request *mq
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// FindTopicBrokers returns the brokers that are serving the topic
|
||||
//
|
||||
// 1. lock the topic
|
||||
//
|
||||
// 2. find the topic partitions on the filer
|
||||
// 2.1 if the topic is not found, return error
|
||||
// 2.2 if the request is_for_publish, create the topic
|
||||
// 2.2.1 if the request is_for_subscribe, return error not found
|
||||
// 2.2.2 if the request is_for_publish, create the topic
|
||||
// 2.2 if the topic is found, return the brokers
|
||||
//
|
||||
// 3. unlock the topic
|
||||
func (broker *MessageQueueBroker) FindTopicBrokers(c context.Context, request *mq_pb.FindTopicBrokersRequest) (*mq_pb.FindTopicBrokersResponse, error) {
|
||||
ret := &mq_pb.FindTopicBrokersResponse{}
|
||||
// lock the topic
|
||||
|
||||
// find the topic partitions on the filer
|
||||
// if the topic is not found
|
||||
// if the request is_for_publish
|
||||
// create the topic
|
||||
// if the request is_for_subscribe
|
||||
// return error not found
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// CheckTopicPartitionsStatus check the topic partitions on the broker
|
||||
func (broker *MessageQueueBroker) CheckTopicPartitionsStatus(c context.Context, request *mq_pb.CheckTopicPartitionsStatusRequest) (*mq_pb.CheckTopicPartitionsStatusResponse, error) {
|
||||
ret := &mq_pb.CheckTopicPartitionsStatusResponse{}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// createOrUpdateTopicPartitions creates the topic partitions on the broker
|
||||
// 1. check
|
||||
func (broker *MessageQueueBroker) createOrUpdateTopicPartitions(topic *topic.Topic, prevAssignment *mq_pb.TopicPartitionsAssignment) (err error) {
|
||||
func (broker *MessageQueueBroker) createOrUpdateTopicPartitions(topic *topic.Topic, prevAssignments []*mq_pb.BrokerPartitionAssignment) (err error) {
|
||||
// create or update each partition
|
||||
if prevAssignment == nil {
|
||||
if prevAssignments == nil {
|
||||
broker.createOrUpdateTopicPartition(topic, nil)
|
||||
} else {
|
||||
for _, partitionAssignment := range prevAssignment.BrokerPartitions {
|
||||
broker.createOrUpdateTopicPartition(topic, partitionAssignment)
|
||||
for _, brokerPartitionAssignment := range prevAssignments {
|
||||
broker.createOrUpdateTopicPartition(topic, brokerPartitionAssignment)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (broker *MessageQueueBroker) createOrUpdateTopicPartition(topic *topic.Topic, oldAssignment *mq_pb.BrokerPartitionsAssignment) (newAssignment *mq_pb.BrokerPartitionsAssignment) {
|
||||
func (broker *MessageQueueBroker) createOrUpdateTopicPartition(topic *topic.Topic, oldAssignment *mq_pb.BrokerPartitionAssignment) (newAssignment *mq_pb.BrokerPartitionAssignment) {
|
||||
shouldCreate := broker.confirmBrokerPartitionAssignment(topic, oldAssignment)
|
||||
if !shouldCreate {
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
func (broker *MessageQueueBroker) confirmBrokerPartitionAssignment(topic *topic.Topic, oldAssignment *mq_pb.BrokerPartitionsAssignment) (shouldCreate bool) {
|
||||
func (broker *MessageQueueBroker) confirmBrokerPartitionAssignment(topic *topic.Topic, oldAssignment *mq_pb.BrokerPartitionAssignment) (shouldCreate bool) {
|
||||
if oldAssignment == nil {
|
||||
return true
|
||||
}
|
||||
for _, b := range oldAssignment.FollowerBrokers {
|
||||
pb.WithBrokerClient(false, pb.ServerAddress(b), broker.grpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
pb.WithBrokerGrpcClient(false, b, broker.grpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
_, err := client.CheckTopicPartitionsStatus(context.Background(), &mq_pb.CheckTopicPartitionsStatusRequest{
|
||||
Namespace: string(topic.Namespace),
|
||||
Topic: topic.Name,
|
||||
BrokerPartitionsAssignment: oldAssignment,
|
||||
ShouldCancelIfNotMatch: true,
|
||||
Namespace: string(topic.Namespace),
|
||||
Topic: topic.Name,
|
||||
BrokerPartitionAssignment: oldAssignment,
|
||||
ShouldCancelIfNotMatch: true,
|
||||
})
|
||||
if err != nil {
|
||||
shouldCreate = true
|
||||
@@ -0,0 +1,51 @@
|
||||
package broker
|
||||
|
||||
import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/balancer"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// BrokerConnectToBalancer receives connections from brokers and collects stats
|
||||
func (broker *MessageQueueBroker) ConnectToBalancer(stream mq_pb.SeaweedMessaging_ConnectToBalancerServer) error {
|
||||
if !broker.lockAsBalancer.IsLocked() {
|
||||
return status.Errorf(codes.Unavailable, "not current broker balancer")
|
||||
}
|
||||
req, err := stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// process init message
|
||||
initMessage := req.GetInit()
|
||||
brokerStats := balancer.NewBrokerStats()
|
||||
if initMessage != nil {
|
||||
broker.Balancer.Brokers.Set(initMessage.Broker, brokerStats)
|
||||
} else {
|
||||
return status.Errorf(codes.InvalidArgument, "balancer init message is empty")
|
||||
}
|
||||
defer func() {
|
||||
broker.Balancer.Brokers.Remove(initMessage.Broker)
|
||||
}()
|
||||
|
||||
// process stats message
|
||||
for {
|
||||
req, err := stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !broker.lockAsBalancer.IsLocked() {
|
||||
return status.Errorf(codes.Unavailable, "not current broker balancer")
|
||||
}
|
||||
if receivedStats := req.GetStats(); receivedStats != nil {
|
||||
brokerStats.UpdateStats(receivedStats)
|
||||
|
||||
glog.V(3).Infof("broker %s stats: %+v", initMessage.Broker, brokerStats)
|
||||
glog.V(3).Infof("received stats: %+v", receivedStats)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package broker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/topic"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// CreateTopic Runs on any broker, but proxied to the balancer if not the balancer
|
||||
func (broker *MessageQueueBroker) CreateTopic(ctx context.Context, request *mq_pb.CreateTopicRequest) (resp *mq_pb.CreateTopicResponse, err error) {
|
||||
if broker.currentBalancer == "" {
|
||||
return nil, status.Errorf(codes.Unavailable, "no balancer")
|
||||
}
|
||||
if !broker.lockAsBalancer.IsLocked() {
|
||||
proxyErr := broker.withBrokerClient(false, broker.currentBalancer, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
resp, err = client.CreateTopic(ctx, request)
|
||||
return nil
|
||||
})
|
||||
if proxyErr != nil {
|
||||
return nil, proxyErr
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
ret := &mq_pb.CreateTopicResponse{}
|
||||
ret.BrokerPartitionAssignments, err = broker.Balancer.LookupOrAllocateTopicPartitions(request.Topic, true, request.PartitionCount)
|
||||
|
||||
for _, bpa := range ret.BrokerPartitionAssignments {
|
||||
if doCreateErr := broker.withBrokerClient(false, pb.ServerAddress(bpa.LeaderBroker), func(client mq_pb.SeaweedMessagingClient) error {
|
||||
_, doCreateErr := client.DoCreateTopic(ctx, &mq_pb.DoCreateTopicRequest{
|
||||
Topic: request.Topic,
|
||||
Partition: bpa.Partition,
|
||||
})
|
||||
return doCreateErr
|
||||
}); doCreateErr != nil {
|
||||
return nil, doCreateErr
|
||||
}
|
||||
}
|
||||
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (broker *MessageQueueBroker) DoCreateTopic(ctx context.Context, req *mq_pb.DoCreateTopicRequest) (resp *mq_pb.DoCreateTopicResponse, err error) {
|
||||
ret := &mq_pb.DoCreateTopicResponse{}
|
||||
t, p := topic.FromPbTopic(req.Topic), topic.FromPbPartition(req.Partition)
|
||||
localTopicPartition := broker.localTopicManager.GetTopicPartition(t, p)
|
||||
if localTopicPartition == nil {
|
||||
localTopicPartition = topic.NewLocalPartition(t, p, true, nil)
|
||||
broker.localTopicManager.AddTopicPartition(t, localTopicPartition)
|
||||
}
|
||||
|
||||
return ret, err
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package broker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// FindTopicBrokers returns the brokers that are serving the topic
|
||||
//
|
||||
// 1. lock the topic
|
||||
//
|
||||
// 2. find the topic partitions on the filer
|
||||
// 2.1 if the topic is not found, return error
|
||||
// 2.2 if the request is_for_publish, create the topic
|
||||
// 2.2.1 if the request is_for_subscribe, return error not found
|
||||
// 2.2.2 if the request is_for_publish, create the topic
|
||||
// 2.2 if the topic is found, return the brokers
|
||||
//
|
||||
// 3. unlock the topic
|
||||
func (broker *MessageQueueBroker) LookupTopicBrokers(ctx context.Context, request *mq_pb.LookupTopicBrokersRequest) (resp *mq_pb.LookupTopicBrokersResponse, err error) {
|
||||
if broker.currentBalancer == "" {
|
||||
return nil, status.Errorf(codes.Unavailable, "no balancer")
|
||||
}
|
||||
if !broker.lockAsBalancer.IsLocked() {
|
||||
proxyErr := broker.withBrokerClient(false, broker.currentBalancer, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
resp, err = client.LookupTopicBrokers(ctx, request)
|
||||
return nil
|
||||
})
|
||||
if proxyErr != nil {
|
||||
return nil, proxyErr
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
ret := &mq_pb.LookupTopicBrokersResponse{}
|
||||
ret.Topic = request.Topic
|
||||
ret.BrokerPartitionAssignments, err = broker.Balancer.LookupOrAllocateTopicPartitions(ret.Topic, request.IsForPublish, 6)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// CheckTopicPartitionsStatus check the topic partitions on the broker
|
||||
func (broker *MessageQueueBroker) CheckTopicPartitionsStatus(c context.Context, request *mq_pb.CheckTopicPartitionsStatusRequest) (*mq_pb.CheckTopicPartitionsStatusResponse, error) {
|
||||
ret := &mq_pb.CheckTopicPartitionsStatusResponse{}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (broker *MessageQueueBroker) ListTopics(ctx context.Context, request *mq_pb.ListTopicsRequest) (resp *mq_pb.ListTopicsResponse, err error) {
|
||||
if broker.currentBalancer == "" {
|
||||
return nil, status.Errorf(codes.Unavailable, "no balancer")
|
||||
}
|
||||
if !broker.lockAsBalancer.IsLocked() {
|
||||
proxyErr := broker.withBrokerClient(false, broker.currentBalancer, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
resp, err = client.ListTopics(ctx, request)
|
||||
return nil
|
||||
})
|
||||
if proxyErr != nil {
|
||||
return nil, proxyErr
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
ret := &mq_pb.ListTopicsResponse{}
|
||||
knownTopics := make(map[*mq_pb.Topic]struct{})
|
||||
for brokerStatsItem := range broker.Balancer.Brokers.IterBuffered() {
|
||||
_, brokerStats := brokerStatsItem.Key, brokerStatsItem.Val
|
||||
for topicPartitionStatsItem := range brokerStats.Stats.IterBuffered() {
|
||||
topicPartitionStat := topicPartitionStatsItem.Val
|
||||
topic := &mq_pb.Topic{
|
||||
Namespace: topicPartitionStat.TopicPartition.Namespace,
|
||||
Name: topicPartitionStat.TopicPartition.Topic,
|
||||
}
|
||||
if _, found := knownTopics[topic]; found {
|
||||
continue
|
||||
}
|
||||
ret.Topics = append(ret.Topics, topic)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/topic"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
// For a new or re-configured topic, or one of the broker went offline,
|
||||
@@ -73,39 +75,89 @@ func (broker *MessageQueueBroker) Publish(stream mq_pb.SeaweedMessaging_PublishS
|
||||
// 3. write to the filer
|
||||
|
||||
var localTopicPartition *topic.LocalPartition
|
||||
req, err := stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response := &mq_pb.PublishResponse{}
|
||||
// TODO check whether current broker should be the leader for the topic partition
|
||||
ackInterval := 1
|
||||
initMessage := req.GetInit()
|
||||
if initMessage != nil {
|
||||
t, p := topic.FromPbTopic(initMessage.Topic), topic.FromPbPartition(initMessage.Partition)
|
||||
localTopicPartition = broker.localTopicManager.GetTopicPartition(t, p)
|
||||
if localTopicPartition == nil {
|
||||
localTopicPartition = topic.NewLocalPartition(t, p, true, nil)
|
||||
broker.localTopicManager.AddTopicPartition(t, localTopicPartition)
|
||||
}
|
||||
ackInterval = int(initMessage.AckInterval)
|
||||
stream.Send(response)
|
||||
} else {
|
||||
response.Error = fmt.Sprintf("topic %v partition %v not found", initMessage.Topic, initMessage.Partition)
|
||||
glog.Errorf("topic %v partition %v not found", initMessage.Topic, initMessage.Partition)
|
||||
return stream.Send(response)
|
||||
}
|
||||
|
||||
ackCounter := 0
|
||||
var ackSequence int64
|
||||
var isStopping int32
|
||||
respChan := make(chan *mq_pb.PublishResponse, 128)
|
||||
defer func() {
|
||||
atomic.StoreInt32(&isStopping, 1)
|
||||
close(respChan)
|
||||
}()
|
||||
go func() {
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
for {
|
||||
select {
|
||||
case resp := <-respChan:
|
||||
if resp != nil {
|
||||
if err := stream.Send(resp); err != nil {
|
||||
glog.Errorf("Error sending response %v: %v", resp, err)
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
case <-ticker.C:
|
||||
if atomic.LoadInt32(&isStopping) == 0 {
|
||||
response := &mq_pb.PublishResponse{
|
||||
AckSequence: ackSequence,
|
||||
}
|
||||
respChan <- response
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// process each published messages
|
||||
for {
|
||||
// receive a message
|
||||
req, err := stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Process the received message
|
||||
sequence := req.GetSequence()
|
||||
response := &mq_pb.PublishResponse{
|
||||
AckSequence: sequence,
|
||||
}
|
||||
if dataMessage := req.GetData(); dataMessage != nil {
|
||||
if localTopicPartition == nil {
|
||||
response.Error = "topic partition not initialized"
|
||||
glog.Errorf("topic partition not found")
|
||||
} else {
|
||||
localTopicPartition.Publish(dataMessage)
|
||||
}
|
||||
} else if initMessage := req.GetInit(); initMessage != nil {
|
||||
localTopicPartition = broker.localTopicManager.GetTopicPartition(
|
||||
topic.NewTopic(topic.Namespace(initMessage.Segment.Namespace), initMessage.Segment.Topic),
|
||||
topic.FromPbPartition(initMessage.Segment.Partition),
|
||||
)
|
||||
if localTopicPartition == nil {
|
||||
response.Error = fmt.Sprintf("topic partition %v not found", initMessage.Segment)
|
||||
glog.Errorf("topic partition %v not found", initMessage.Segment)
|
||||
}
|
||||
localTopicPartition.Publish(dataMessage)
|
||||
}
|
||||
if err := stream.Send(response); err != nil {
|
||||
glog.Errorf("Error sending setup response: %v", err)
|
||||
|
||||
ackCounter++
|
||||
ackSequence++
|
||||
if ackCounter >= ackInterval {
|
||||
ackCounter = 0
|
||||
// send back the ack
|
||||
response := &mq_pb.PublishResponse{
|
||||
AckSequence: ackSequence,
|
||||
}
|
||||
respChan <- response
|
||||
}
|
||||
}
|
||||
|
||||
glog.Infof("publish stream closed")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -114,14 +166,14 @@ func (broker *MessageQueueBroker) AssignTopicPartitions(c context.Context, reque
|
||||
ret := &mq_pb.AssignTopicPartitionsResponse{}
|
||||
self := pb.ServerAddress(fmt.Sprintf("%s:%d", broker.option.Ip, broker.option.Port))
|
||||
|
||||
for _, partition := range request.TopicPartitionsAssignment.BrokerPartitions {
|
||||
localPartiton := topic.FromPbBrokerPartitionsAssignment(self, partition)
|
||||
for _, brokerPartition := range request.BrokerPartitionAssignments {
|
||||
localPartiton := topic.FromPbBrokerPartitionAssignment(self, brokerPartition)
|
||||
broker.localTopicManager.AddTopicPartition(
|
||||
topic.FromPbTopic(request.Topic),
|
||||
localPartiton)
|
||||
if request.IsLeader {
|
||||
for _, follower := range localPartiton.FollowerBrokers {
|
||||
err := pb.WithBrokerClient(false, follower, broker.grpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
err := pb.WithBrokerGrpcClient(false, follower.String(), broker.grpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
_, err := client.AssignTopicPartitions(context.Background(), request)
|
||||
return err
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
package broker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/topic"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (broker *MessageQueueBroker) Subscribe(req *mq_pb.SubscribeRequest, stream mq_pb.SeaweedMessaging_SubscribeServer) error {
|
||||
|
||||
localTopicPartition := broker.localTopicManager.GetTopicPartition(topic.FromPbTopic(req.Cursor.Topic),
|
||||
topic.FromPbPartition(req.Cursor.Partition))
|
||||
if localTopicPartition == nil {
|
||||
stream.Send(&mq_pb.SubscribeResponse{
|
||||
Message: &mq_pb.SubscribeResponse_Ctrl{
|
||||
Ctrl: &mq_pb.SubscribeResponse_CtrlMessage{
|
||||
Error: "not initialized",
|
||||
},
|
||||
},
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
clientName := fmt.Sprintf("%s/%s-%s", req.Consumer.ConsumerGroup, req.Consumer.ConsumerId, req.Consumer.ClientId)
|
||||
|
||||
localTopicPartition.Subscribe(clientName, time.Now(), func(logEntry *filer_pb.LogEntry) error {
|
||||
value := logEntry.GetData()
|
||||
if err := stream.Send(&mq_pb.SubscribeResponse{Message: &mq_pb.SubscribeResponse_Data{
|
||||
Data: &mq_pb.DataMessage{
|
||||
Key: []byte(fmt.Sprintf("key-%d", logEntry.PartitionKeyHash)),
|
||||
Value: value,
|
||||
},
|
||||
}}); err != nil {
|
||||
glog.Errorf("Error sending setup response: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package broker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/balancer"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/topic"
|
||||
"time"
|
||||
|
||||
@@ -34,6 +37,9 @@ type MessageQueueBroker struct {
|
||||
filers map[pb.ServerAddress]struct{}
|
||||
currentFiler pb.ServerAddress
|
||||
localTopicManager *topic.LocalTopicManager
|
||||
Balancer *balancer.Balancer
|
||||
lockAsBalancer *cluster.LiveLock
|
||||
currentBalancer pb.ServerAddress
|
||||
}
|
||||
|
||||
func NewMessageBroker(option *MessageQueueBrokerOption, grpcDialOption grpc.DialOption) (mqBroker *MessageQueueBroker, err error) {
|
||||
@@ -41,9 +47,10 @@ func NewMessageBroker(option *MessageQueueBrokerOption, grpcDialOption grpc.Dial
|
||||
mqBroker = &MessageQueueBroker{
|
||||
option: option,
|
||||
grpcDialOption: grpcDialOption,
|
||||
MasterClient: wdclient.NewMasterClient(grpcDialOption, option.FilerGroup, cluster.BrokerType, pb.NewServerAddress(option.Ip, option.Port, 0), option.DataCenter, option.Rack, *pb.NewServiceDiscoveryFromMap(option.Masters)),
|
||||
MasterClient: wdclient.NewMasterClient(grpcDialOption, option.FilerGroup, cluster.BrokerType, pb.NewServerAddress(option.Ip, option.Port, 0), option.DataCenter, option.Rack, *pb.NewServiceDiscoveryFromMap(option.Masters)),
|
||||
filers: make(map[pb.ServerAddress]struct{}),
|
||||
localTopicManager: topic.NewLocalTopicManager(),
|
||||
Balancer: balancer.NewBalancer(),
|
||||
}
|
||||
mqBroker.MasterClient.SetOnPeerUpdateFn(mqBroker.OnBrokerUpdate)
|
||||
|
||||
@@ -54,6 +61,25 @@ func NewMessageBroker(option *MessageQueueBrokerOption, grpcDialOption grpc.Dial
|
||||
mqBroker.OnBrokerUpdate(newNode, time.Now())
|
||||
}
|
||||
|
||||
// keep connecting to balancer
|
||||
go func() {
|
||||
for mqBroker.currentFiler == "" {
|
||||
time.Sleep(time.Millisecond * 237)
|
||||
}
|
||||
self := fmt.Sprintf("%s:%d", option.Ip, option.Port)
|
||||
glog.V(1).Infof("broker %s found filer %s", self, mqBroker.currentFiler)
|
||||
|
||||
lockClient := cluster.NewLockClient(grpcDialOption, mqBroker.currentFiler)
|
||||
mqBroker.lockAsBalancer = lockClient.StartLock(balancer.LockBrokerBalancer, self)
|
||||
for {
|
||||
err := mqBroker.BrokerConnectToBalancer(self)
|
||||
if err != nil {
|
||||
fmt.Printf("BrokerConnectToBalancer: %v\n", err)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}()
|
||||
|
||||
return mqBroker, nil
|
||||
}
|
||||
|
||||
@@ -112,7 +138,7 @@ func (broker *MessageQueueBroker) withMasterClient(streamingMode bool, master pb
|
||||
|
||||
func (broker *MessageQueueBroker) withBrokerClient(streamingMode bool, server pb.ServerAddress, fn func(client mq_pb.SeaweedMessagingClient) error) error {
|
||||
|
||||
return pb.WithBrokerClient(streamingMode, server, broker.grpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
return pb.WithBrokerGrpcClient(streamingMode, server.String(), broker.grpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
return fn(client)
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package broker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/balancer"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BrokerConnectToBalancer connects to the broker balancer and sends stats
|
||||
func (broker *MessageQueueBroker) BrokerConnectToBalancer(self string) error {
|
||||
// find the lock owner
|
||||
var brokerBalancer string
|
||||
err := broker.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
|
||||
resp, err := client.FindLockOwner(context.Background(), &filer_pb.FindLockOwnerRequest{
|
||||
Name: balancer.LockBrokerBalancer,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
brokerBalancer = resp.Owner
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
broker.currentBalancer = pb.ServerAddress(brokerBalancer)
|
||||
|
||||
glog.V(1).Infof("broker %s found balancer %s", self, brokerBalancer)
|
||||
|
||||
// connect to the lock owner
|
||||
err = pb.WithBrokerGrpcClient(false, brokerBalancer, broker.grpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
stream, err := client.ConnectToBalancer(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("connect to balancer %v: %v", brokerBalancer, err)
|
||||
}
|
||||
defer stream.CloseSend()
|
||||
err = stream.Send(&mq_pb.ConnectToBalancerRequest{
|
||||
Message: &mq_pb.ConnectToBalancerRequest_Init{
|
||||
Init: &mq_pb.ConnectToBalancerRequest_InitMessage{
|
||||
Broker: self,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("send init message: %v", err)
|
||||
}
|
||||
|
||||
for {
|
||||
stats := broker.localTopicManager.CollectStats(time.Second * 5)
|
||||
err = stream.Send(&mq_pb.ConnectToBalancerRequest{
|
||||
Message: &mq_pb.ConnectToBalancerRequest_Stats{
|
||||
Stats: stats,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("send stats message: %v", err)
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond*5000 + time.Duration(rand.Intn(1000))*time.Millisecond)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/client/pub_client"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
messageCount = flag.Int("n", 1000, "message count")
|
||||
concurrency = flag.Int("c", 4, "concurrency count")
|
||||
)
|
||||
|
||||
func doPublish(publisher *pub_client.TopicPublisher, id int) {
|
||||
startTime := time.Now()
|
||||
for i := 0; i < *messageCount / *concurrency; i++ {
|
||||
// Simulate publishing a message
|
||||
key := []byte(fmt.Sprintf("key-%d-%d", id, i))
|
||||
value := []byte(fmt.Sprintf("value-%d-%d", id, i))
|
||||
publisher.Publish(key, value) // Call your publisher function here
|
||||
// println("Published", string(key), string(value))
|
||||
}
|
||||
elapsed := time.Since(startTime)
|
||||
log.Printf("Publisher %d finished in %s", id, elapsed)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
publisher := pub_client.NewTopicPublisher(
|
||||
"test", "test")
|
||||
if err := publisher.Connect("localhost:17777"); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
// Start multiple publishers
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < *concurrency; i++ {
|
||||
wg.Add(1)
|
||||
go func(id int) {
|
||||
defer wg.Done()
|
||||
doPublish(publisher, id)
|
||||
}(i)
|
||||
}
|
||||
|
||||
// Wait for all publishers to finish
|
||||
wg.Wait()
|
||||
elapsed := time.Since(startTime)
|
||||
publisher.Shutdown()
|
||||
|
||||
log.Printf("Published %d messages in %s (%.2f msg/s)", *messageCount, elapsed, float64(*messageCount)/elapsed.Seconds())
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/client/sub_client"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
subscriberConfig := &sub_client.SubscriberConfiguration{
|
||||
ClientId: "testSubscriber",
|
||||
GroupId: "test",
|
||||
GroupInstanceId: "test",
|
||||
GrpcDialOption: grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
}
|
||||
|
||||
contentConfig := &sub_client.ContentConfiguration{
|
||||
Namespace: "test",
|
||||
Topic: "test",
|
||||
Filter: "",
|
||||
}
|
||||
|
||||
subscriber := sub_client.NewTopicSubscriber(subscriberConfig, contentConfig)
|
||||
if err := subscriber.Connect("localhost:17777"); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
subscriber.SetEachMessageFunc(func(key, value []byte) bool {
|
||||
println(string(key), "=>", string(value))
|
||||
return true
|
||||
})
|
||||
|
||||
subscriber.SetCompletionFunc(func() {
|
||||
println("done subscribing")
|
||||
})
|
||||
|
||||
if err := subscriber.Subscribe(); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package pub_client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func (p *TopicPublisher) doLookup(brokerAddress string) error {
|
||||
err := pb.WithBrokerGrpcClient(true,
|
||||
brokerAddress,
|
||||
p.grpcDialOption,
|
||||
func(client mq_pb.SeaweedMessagingClient) error {
|
||||
lookupResp, err := client.LookupTopicBrokers(context.Background(),
|
||||
&mq_pb.LookupTopicBrokersRequest{
|
||||
Topic: &mq_pb.Topic{
|
||||
Namespace: p.namespace,
|
||||
Name: p.topic,
|
||||
},
|
||||
IsForPublish: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, brokerPartitionAssignment := range lookupResp.BrokerPartitionAssignments {
|
||||
// partition => publishClient
|
||||
publishClient, redirectTo, err := p.doConnect(brokerPartitionAssignment.Partition, brokerPartitionAssignment.LeaderBroker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for redirectTo != "" {
|
||||
publishClient, redirectTo, err = p.doConnect(brokerPartitionAssignment.Partition, redirectTo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
p.partition2Broker.Insert(
|
||||
brokerPartitionAssignment.Partition.RangeStart,
|
||||
brokerPartitionAssignment.Partition.RangeStop,
|
||||
publishClient)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("lookup topic %s/%s: %v", p.namespace, p.topic, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// broker => publish client
|
||||
// send init message
|
||||
// save the publishing client
|
||||
func (p *TopicPublisher) doConnect(partition *mq_pb.Partition, brokerAddress string) (publishClient *PublishClient, redirectTo string, err error) {
|
||||
grpcConnection, err := pb.GrpcDial(context.Background(), brokerAddress, true, p.grpcDialOption)
|
||||
if err != nil {
|
||||
return publishClient, redirectTo, fmt.Errorf("dial broker %s: %v", brokerAddress, err)
|
||||
}
|
||||
brokerClient := mq_pb.NewSeaweedMessagingClient(grpcConnection)
|
||||
stream, err := brokerClient.Publish(context.Background())
|
||||
if err != nil {
|
||||
return publishClient, redirectTo, fmt.Errorf("create publish client: %v", err)
|
||||
}
|
||||
publishClient = &PublishClient{
|
||||
SeaweedMessaging_PublishClient: stream,
|
||||
Broker: brokerAddress,
|
||||
}
|
||||
if err = publishClient.Send(&mq_pb.PublishRequest{
|
||||
Message: &mq_pb.PublishRequest_Init{
|
||||
Init: &mq_pb.PublishRequest_InitMessage{
|
||||
Topic: &mq_pb.Topic{
|
||||
Namespace: p.namespace,
|
||||
Name: p.topic,
|
||||
},
|
||||
Partition: &mq_pb.Partition{
|
||||
RingSize: partition.RingSize,
|
||||
RangeStart: partition.RangeStart,
|
||||
RangeStop: partition.RangeStop,
|
||||
},
|
||||
AckInterval: 128,
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
return publishClient, redirectTo, fmt.Errorf("send init message: %v", err)
|
||||
}
|
||||
resp, err := stream.Recv()
|
||||
if err != nil {
|
||||
return publishClient, redirectTo, fmt.Errorf("recv init response: %v", err)
|
||||
}
|
||||
if resp.Error != "" {
|
||||
return publishClient, redirectTo, fmt.Errorf("init response error: %v", resp.Error)
|
||||
}
|
||||
if resp.RedirectToBroker != "" {
|
||||
redirectTo = resp.RedirectToBroker
|
||||
return publishClient, redirectTo, nil
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
_, err := publishClient.Recv()
|
||||
if err != nil {
|
||||
e, ok := status.FromError(err)
|
||||
if ok && e.Code() == codes.Unknown && e.Message() == "EOF" {
|
||||
return
|
||||
}
|
||||
publishClient.Err = err
|
||||
fmt.Printf("publish to %s error: %v\n", publishClient.Broker, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return publishClient, redirectTo, nil
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package pub_client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/balancer"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
)
|
||||
|
||||
func (p *TopicPublisher) Publish(key, value []byte) error {
|
||||
hashKey := util.HashToInt32(key) % balancer.MaxPartitionCount
|
||||
if hashKey < 0 {
|
||||
hashKey = -hashKey
|
||||
}
|
||||
publishClient, found := p.partition2Broker.Floor(hashKey, hashKey)
|
||||
if !found {
|
||||
return fmt.Errorf("no broker found for key %d", hashKey)
|
||||
}
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
// dead lock here
|
||||
//google.golang.org/grpc/internal/transport.(*writeQuota).get(flowcontrol.go:59)
|
||||
//google.golang.org/grpc/internal/transport.(*http2Client).Write(http2_client.go:1047)
|
||||
//google.golang.org/grpc.(*csAttempt).sendMsg(stream.go:1040)
|
||||
//google.golang.org/grpc.(*clientStream).SendMsg.func2(stream.go:892)
|
||||
//google.golang.org/grpc.(*clientStream).withRetry(stream.go:752)
|
||||
//google.golang.org/grpc.(*clientStream).SendMsg(stream.go:894)
|
||||
//github.com/seaweedfs/seaweedfs/weed/pb/mq_pb.(*seaweedMessagingPublishClient).Send(mq_grpc.pb.go:141)
|
||||
//github.com/seaweedfs/seaweedfs/weed/mq/client/pub_client.(*TopicPublisher).Publish(publish.go:19)
|
||||
if err := publishClient.Send(&mq_pb.PublishRequest{
|
||||
Message: &mq_pb.PublishRequest_Data{
|
||||
Data: &mq_pb.DataMessage{
|
||||
Key: key,
|
||||
Value: value,
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
return fmt.Errorf("send publish request: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package pub_client
|
||||
|
||||
import (
|
||||
"github.com/rdleal/intervalst/interval"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/balancer"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PublisherConfiguration struct {
|
||||
}
|
||||
|
||||
type PublishClient struct {
|
||||
mq_pb.SeaweedMessaging_PublishClient
|
||||
Broker string
|
||||
Err error
|
||||
}
|
||||
type TopicPublisher struct {
|
||||
namespace string
|
||||
topic string
|
||||
partition2Broker *interval.SearchTree[*PublishClient, int32]
|
||||
grpcDialOption grpc.DialOption
|
||||
sync.Mutex // protects grpc
|
||||
}
|
||||
|
||||
func NewTopicPublisher(namespace, topic string) *TopicPublisher {
|
||||
return &TopicPublisher{
|
||||
namespace: namespace,
|
||||
topic: topic,
|
||||
partition2Broker: interval.NewSearchTree[*PublishClient](func(a, b int32) int {
|
||||
return int(a - b)
|
||||
}),
|
||||
grpcDialOption: grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *TopicPublisher) Connect(bootstrapBroker string) error {
|
||||
if err := p.doLookup(bootstrapBroker); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *TopicPublisher) Shutdown() error {
|
||||
|
||||
if clients, found := p.partition2Broker.AllIntersections(0, balancer.MaxPartitionCount); found {
|
||||
for _, client := range clients {
|
||||
client.CloseSend()
|
||||
}
|
||||
}
|
||||
time.Sleep(1100 * time.Millisecond)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package sub_client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
)
|
||||
|
||||
func (sub *TopicSubscriber) doLookup(brokerAddress string) error {
|
||||
err := pb.WithBrokerGrpcClient(true,
|
||||
brokerAddress,
|
||||
sub.SubscriberConfig.GrpcDialOption,
|
||||
func(client mq_pb.SeaweedMessagingClient) error {
|
||||
lookupResp, err := client.LookupTopicBrokers(context.Background(),
|
||||
&mq_pb.LookupTopicBrokersRequest{
|
||||
Topic: &mq_pb.Topic{
|
||||
Namespace: sub.ContentConfig.Namespace,
|
||||
Name: sub.ContentConfig.Topic,
|
||||
},
|
||||
IsForPublish: false,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sub.brokerPartitionAssignments = lookupResp.BrokerPartitionAssignments
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("lookup topic %s/%s: %v", sub.ContentConfig.Namespace, sub.ContentConfig.Topic, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package sub_client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Subscribe subscribes to a topic's specified partitions.
|
||||
// If a partition is moved to another broker, the subscriber will automatically reconnect to the new broker.
|
||||
|
||||
func (sub *TopicSubscriber) Subscribe() error {
|
||||
var wg sync.WaitGroup
|
||||
for _, brokerPartitionAssignment := range sub.brokerPartitionAssignments {
|
||||
brokerAddress := brokerPartitionAssignment.LeaderBroker
|
||||
grpcConnection, err := pb.GrpcDial(context.Background(), brokerAddress, true, sub.SubscriberConfig.GrpcDialOption)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dial broker %s: %v", brokerAddress, err)
|
||||
}
|
||||
brokerClient := mq_pb.NewSeaweedMessagingClient(grpcConnection)
|
||||
subscribeClient, err := brokerClient.Subscribe(context.Background(), &mq_pb.SubscribeRequest{
|
||||
Consumer: &mq_pb.SubscribeRequest_Consumer{
|
||||
ConsumerGroup: sub.SubscriberConfig.GroupId,
|
||||
ConsumerId: sub.SubscriberConfig.GroupInstanceId,
|
||||
},
|
||||
Cursor: &mq_pb.SubscribeRequest_Cursor{
|
||||
Topic: &mq_pb.Topic{
|
||||
Namespace: sub.ContentConfig.Namespace,
|
||||
Name: sub.ContentConfig.Topic,
|
||||
},
|
||||
Partition: &mq_pb.Partition{
|
||||
RingSize: brokerPartitionAssignment.Partition.RingSize,
|
||||
RangeStart: brokerPartitionAssignment.Partition.RangeStart,
|
||||
RangeStop: brokerPartitionAssignment.Partition.RangeStop,
|
||||
},
|
||||
Filter: sub.ContentConfig.Filter,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("create subscribe client: %v", err)
|
||||
}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if sub.OnCompletionFunc != nil {
|
||||
defer sub.OnCompletionFunc()
|
||||
}
|
||||
for {
|
||||
resp, err := subscribeClient.Recv()
|
||||
if err != nil {
|
||||
fmt.Printf("subscribe error: %v\n", err)
|
||||
return
|
||||
}
|
||||
if resp.Message == nil {
|
||||
continue
|
||||
}
|
||||
switch m := resp.Message.(type) {
|
||||
case *mq_pb.SubscribeResponse_Data:
|
||||
if !sub.OnEachMessageFunc(m.Data.Key, m.Data.Value) {
|
||||
return
|
||||
}
|
||||
case *mq_pb.SubscribeResponse_Ctrl:
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package sub_client
|
||||
|
||||
import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type SubscriberConfiguration struct {
|
||||
ClientId string
|
||||
GroupId string
|
||||
GroupInstanceId string
|
||||
BootstrapServers []string
|
||||
GrpcDialOption grpc.DialOption
|
||||
}
|
||||
|
||||
type ContentConfiguration struct {
|
||||
Namespace string
|
||||
Topic string
|
||||
Filter string
|
||||
}
|
||||
|
||||
type OnEachMessageFunc func(key, value []byte) (shouldContinue bool)
|
||||
type OnCompletionFunc func()
|
||||
|
||||
type TopicSubscriber struct {
|
||||
SubscriberConfig *SubscriberConfiguration
|
||||
ContentConfig *ContentConfiguration
|
||||
brokerPartitionAssignments []*mq_pb.BrokerPartitionAssignment
|
||||
OnEachMessageFunc OnEachMessageFunc
|
||||
OnCompletionFunc OnCompletionFunc
|
||||
}
|
||||
|
||||
func NewTopicSubscriber(subscriber *SubscriberConfiguration, content *ContentConfiguration) *TopicSubscriber {
|
||||
return &TopicSubscriber{
|
||||
SubscriberConfig: subscriber,
|
||||
ContentConfig: content,
|
||||
}
|
||||
}
|
||||
|
||||
func (sub *TopicSubscriber) Connect(bootstrapBroker string) error {
|
||||
if err := sub.doLookup(bootstrapBroker); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sub *TopicSubscriber) SetEachMessageFunc(onEachMessageFn OnEachMessageFunc) {
|
||||
sub.OnEachMessageFunc = onEachMessageFn
|
||||
}
|
||||
|
||||
func (sub *TopicSubscriber) SetCompletionFunc(onCompeletionFn OnCompletionFunc) {
|
||||
sub.OnCompletionFunc = onCompeletionFn
|
||||
}
|
||||
@@ -2,6 +2,9 @@ package topic
|
||||
|
||||
import (
|
||||
cmap "github.com/orcaman/concurrent-map/v2"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
"time"
|
||||
)
|
||||
|
||||
// LocalTopicManager manages topics on local broker
|
||||
@@ -25,6 +28,7 @@ func (manager *LocalTopicManager) AddTopicPartition(topic Topic, localPartition
|
||||
Partitions: make([]*LocalPartition, 0),
|
||||
}
|
||||
}
|
||||
manager.topics.SetIfAbsent(topic.String(), localTopic)
|
||||
if localTopic.findPartition(localPartition.Partition) != nil {
|
||||
return
|
||||
}
|
||||
@@ -52,3 +56,34 @@ func (manager *LocalTopicManager) RemoveTopicPartition(topic Topic, partition Pa
|
||||
}
|
||||
return localTopic.removePartition(partition)
|
||||
}
|
||||
|
||||
func (manager *LocalTopicManager) CollectStats(duration time.Duration) *mq_pb.BrokerStats {
|
||||
stats := &mq_pb.BrokerStats{
|
||||
Stats: make(map[string]*mq_pb.TopicPartitionStats),
|
||||
}
|
||||
manager.topics.IterCb(func(topic string, localTopic *LocalTopic) {
|
||||
for _, localPartition := range localTopic.Partitions {
|
||||
stats.Stats[topic] = &mq_pb.TopicPartitionStats{
|
||||
Topic: &mq_pb.Topic{
|
||||
Namespace: string(localTopic.Namespace),
|
||||
Name: localTopic.Name,
|
||||
},
|
||||
Partition: &mq_pb.Partition{
|
||||
RingSize: localPartition.RingSize,
|
||||
RangeStart: localPartition.RangeStart,
|
||||
RangeStop: localPartition.RangeStop,
|
||||
},
|
||||
ConsumerCount: localPartition.ConsumerCount,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// collect current broker's cpu usage
|
||||
usages, err := cpu.Percent(duration, false)
|
||||
if err == nil && len(usages) > 0 {
|
||||
stats.CpuUsagePercent = int32(usages[0])
|
||||
}
|
||||
|
||||
return stats
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package topic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/log_buffer"
|
||||
"time"
|
||||
@@ -12,21 +14,44 @@ type LocalPartition struct {
|
||||
isLeader bool
|
||||
FollowerBrokers []pb.ServerAddress
|
||||
logBuffer *log_buffer.LogBuffer
|
||||
ConsumerCount int32
|
||||
}
|
||||
|
||||
func (p LocalPartition) Publish(message *mq_pb.PublishRequest_DataMessage) {
|
||||
func NewLocalPartition(topic Topic, partition Partition, isLeader bool, followerBrokers []pb.ServerAddress) *LocalPartition {
|
||||
return &LocalPartition{
|
||||
Partition: partition,
|
||||
isLeader: isLeader,
|
||||
FollowerBrokers: followerBrokers,
|
||||
logBuffer: log_buffer.NewLogBuffer(
|
||||
fmt.Sprintf("%s/%s/%4d-%4d", topic.Namespace, topic.Name, partition.RangeStart, partition.RangeStop),
|
||||
2*time.Minute,
|
||||
func(startTime, stopTime time.Time, buf []byte) {
|
||||
|
||||
},
|
||||
func() {
|
||||
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type OnEachMessageFn func(logEntry *filer_pb.LogEntry) error
|
||||
|
||||
func (p LocalPartition) Publish(message *mq_pb.DataMessage) {
|
||||
p.logBuffer.AddToBuffer(message.Key, message.Value, time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func FromPbBrokerPartitionsAssignment(self pb.ServerAddress, assignment *mq_pb.BrokerPartitionsAssignment) *LocalPartition {
|
||||
func (p LocalPartition) Subscribe(clientName string, startReadTime time.Time, eachMessageFn OnEachMessageFn) {
|
||||
p.logBuffer.LoopProcessLogData(clientName, startReadTime, 0, func() bool {
|
||||
return true
|
||||
}, eachMessageFn)
|
||||
}
|
||||
|
||||
func FromPbBrokerPartitionAssignment(self pb.ServerAddress, assignment *mq_pb.BrokerPartitionAssignment) *LocalPartition {
|
||||
isLeaer := assignment.LeaderBroker == string(self)
|
||||
localPartition := &LocalPartition{
|
||||
Partition: Partition{
|
||||
RangeStart: assignment.PartitionStart,
|
||||
RangeStop: assignment.PartitionStop,
|
||||
RingSize: PartitionCount,
|
||||
},
|
||||
isLeader: isLeaer,
|
||||
Partition: FromPbPartition(assignment.Partition),
|
||||
isLeader: isLeaer,
|
||||
}
|
||||
if !isLeaer {
|
||||
return localPartition
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
package topic_allocation
|
||||
|
||||
import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/topic"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"modernc.org/mathutil"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultBrokerCount = 4
|
||||
)
|
||||
|
||||
// AllocateBrokersForTopicPartitions allocate brokers for a topic's all partitions
|
||||
func AllocateBrokersForTopicPartitions(t topic.Topic, prevAssignment *mq_pb.TopicPartitionsAssignment, candidateBrokers []pb.ServerAddress) (assignment *mq_pb.TopicPartitionsAssignment, err error) {
|
||||
// create a previous assignment if not exists
|
||||
if prevAssignment == nil || len(prevAssignment.BrokerPartitions) == 0 {
|
||||
prevAssignment = &mq_pb.TopicPartitionsAssignment{
|
||||
PartitionCount: topic.PartitionCount,
|
||||
}
|
||||
partitionCountForEachBroker := topic.PartitionCount / DefaultBrokerCount
|
||||
for i := 0; i < DefaultBrokerCount; i++ {
|
||||
prevAssignment.BrokerPartitions = append(prevAssignment.BrokerPartitions, &mq_pb.BrokerPartitionsAssignment{
|
||||
PartitionStart: int32(i * partitionCountForEachBroker),
|
||||
PartitionStop: mathutil.MaxInt32(int32((i+1)*partitionCountForEachBroker), topic.PartitionCount),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// create a new assignment
|
||||
assignment = &mq_pb.TopicPartitionsAssignment{
|
||||
PartitionCount: prevAssignment.PartitionCount,
|
||||
}
|
||||
|
||||
// allocate partitions for each partition range
|
||||
for _, brokerPartition := range prevAssignment.BrokerPartitions {
|
||||
// allocate partitions for each partition range
|
||||
leader, followers, err := allocateBrokersForOneTopicPartition(t, brokerPartition, candidateBrokers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
followerBrokers := make([]string, len(followers))
|
||||
for i, follower := range followers {
|
||||
followerBrokers[i] = string(follower)
|
||||
}
|
||||
|
||||
assignment.BrokerPartitions = append(assignment.BrokerPartitions, &mq_pb.BrokerPartitionsAssignment{
|
||||
PartitionStart: brokerPartition.PartitionStart,
|
||||
PartitionStop: brokerPartition.PartitionStop,
|
||||
LeaderBroker: string(leader),
|
||||
FollowerBrokers: followerBrokers,
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func allocateBrokersForOneTopicPartition(t topic.Topic, brokerPartition *mq_pb.BrokerPartitionsAssignment, candidateBrokers []pb.ServerAddress) (leader pb.ServerAddress, followers []pb.ServerAddress, err error) {
|
||||
// allocate leader
|
||||
leader, err = allocateLeaderForOneTopicPartition(t, brokerPartition, candidateBrokers)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// allocate followers
|
||||
followers, err = allocateFollowersForOneTopicPartition(t, brokerPartition, candidateBrokers)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func allocateFollowersForOneTopicPartition(t topic.Topic, partition *mq_pb.BrokerPartitionsAssignment, brokers []pb.ServerAddress) (followers []pb.ServerAddress, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func allocateLeaderForOneTopicPartition(t topic.Topic, partition *mq_pb.BrokerPartitionsAssignment, brokers []pb.ServerAddress) (leader pb.ServerAddress, err error) {
|
||||
return
|
||||
}
|
||||
+14
-2
@@ -69,10 +69,13 @@ service SeaweedFiler {
|
||||
rpc CacheRemoteObjectToLocalCluster (CacheRemoteObjectToLocalClusterRequest) returns (CacheRemoteObjectToLocalClusterResponse) {
|
||||
}
|
||||
|
||||
rpc Lock(LockRequest) returns (LockResponse) {
|
||||
rpc DistributedLock(LockRequest) returns (LockResponse) {
|
||||
}
|
||||
rpc Unlock(UnlockRequest) returns (UnlockResponse) {
|
||||
rpc DistributedUnlock(UnlockRequest) returns (UnlockResponse) {
|
||||
}
|
||||
rpc FindLockOwner(FindLockOwnerRequest) returns (FindLockOwnerResponse) {
|
||||
}
|
||||
// distributed lock management internal use only
|
||||
rpc TransferLocks(TransferLocksRequest) returns (TransferLocksResponse) {
|
||||
}
|
||||
}
|
||||
@@ -444,6 +447,7 @@ message LockRequest {
|
||||
int64 seconds_to_lock = 2;
|
||||
string renew_token = 3;
|
||||
bool is_moved = 4;
|
||||
string owner = 5;
|
||||
}
|
||||
message LockResponse {
|
||||
string renew_token = 1;
|
||||
@@ -459,10 +463,18 @@ message UnlockResponse {
|
||||
string error = 1;
|
||||
string moved_to = 2;
|
||||
}
|
||||
message FindLockOwnerRequest {
|
||||
string name = 1;
|
||||
bool is_moved = 2;
|
||||
}
|
||||
message FindLockOwnerResponse {
|
||||
string owner = 1;
|
||||
}
|
||||
message Lock {
|
||||
string name = 1;
|
||||
string renew_token = 2;
|
||||
int64 expired_at_ns = 3;
|
||||
string owner = 4;
|
||||
}
|
||||
message TransferLocksRequest {
|
||||
repeated Lock locks = 1;
|
||||
|
||||
+375
-213
@@ -3621,6 +3621,7 @@ type LockRequest struct {
|
||||
SecondsToLock int64 `protobuf:"varint,2,opt,name=seconds_to_lock,json=secondsToLock,proto3" json:"seconds_to_lock,omitempty"`
|
||||
RenewToken string `protobuf:"bytes,3,opt,name=renew_token,json=renewToken,proto3" json:"renew_token,omitempty"`
|
||||
IsMoved bool `protobuf:"varint,4,opt,name=is_moved,json=isMoved,proto3" json:"is_moved,omitempty"`
|
||||
Owner string `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty"`
|
||||
}
|
||||
|
||||
func (x *LockRequest) Reset() {
|
||||
@@ -3683,6 +3684,13 @@ func (x *LockRequest) GetIsMoved() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *LockRequest) GetOwner() string {
|
||||
if x != nil {
|
||||
return x.Owner
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type LockResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -3864,6 +3872,108 @@ func (x *UnlockResponse) GetMovedTo() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type FindLockOwnerRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
IsMoved bool `protobuf:"varint,2,opt,name=is_moved,json=isMoved,proto3" json:"is_moved,omitempty"`
|
||||
}
|
||||
|
||||
func (x *FindLockOwnerRequest) Reset() {
|
||||
*x = FindLockOwnerRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_filer_proto_msgTypes[59]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *FindLockOwnerRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*FindLockOwnerRequest) ProtoMessage() {}
|
||||
|
||||
func (x *FindLockOwnerRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_filer_proto_msgTypes[59]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use FindLockOwnerRequest.ProtoReflect.Descriptor instead.
|
||||
func (*FindLockOwnerRequest) Descriptor() ([]byte, []int) {
|
||||
return file_filer_proto_rawDescGZIP(), []int{59}
|
||||
}
|
||||
|
||||
func (x *FindLockOwnerRequest) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *FindLockOwnerRequest) GetIsMoved() bool {
|
||||
if x != nil {
|
||||
return x.IsMoved
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type FindLockOwnerResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"`
|
||||
}
|
||||
|
||||
func (x *FindLockOwnerResponse) Reset() {
|
||||
*x = FindLockOwnerResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_filer_proto_msgTypes[60]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *FindLockOwnerResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*FindLockOwnerResponse) ProtoMessage() {}
|
||||
|
||||
func (x *FindLockOwnerResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_filer_proto_msgTypes[60]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use FindLockOwnerResponse.ProtoReflect.Descriptor instead.
|
||||
func (*FindLockOwnerResponse) Descriptor() ([]byte, []int) {
|
||||
return file_filer_proto_rawDescGZIP(), []int{60}
|
||||
}
|
||||
|
||||
func (x *FindLockOwnerResponse) GetOwner() string {
|
||||
if x != nil {
|
||||
return x.Owner
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Lock struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -3872,12 +3982,13 @@ type Lock struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
RenewToken string `protobuf:"bytes,2,opt,name=renew_token,json=renewToken,proto3" json:"renew_token,omitempty"`
|
||||
ExpiredAtNs int64 `protobuf:"varint,3,opt,name=expired_at_ns,json=expiredAtNs,proto3" json:"expired_at_ns,omitempty"`
|
||||
Owner string `protobuf:"bytes,4,opt,name=owner,proto3" json:"owner,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Lock) Reset() {
|
||||
*x = Lock{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_filer_proto_msgTypes[59]
|
||||
mi := &file_filer_proto_msgTypes[61]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -3890,7 +4001,7 @@ func (x *Lock) String() string {
|
||||
func (*Lock) ProtoMessage() {}
|
||||
|
||||
func (x *Lock) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_filer_proto_msgTypes[59]
|
||||
mi := &file_filer_proto_msgTypes[61]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -3903,7 +4014,7 @@ func (x *Lock) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Lock.ProtoReflect.Descriptor instead.
|
||||
func (*Lock) Descriptor() ([]byte, []int) {
|
||||
return file_filer_proto_rawDescGZIP(), []int{59}
|
||||
return file_filer_proto_rawDescGZIP(), []int{61}
|
||||
}
|
||||
|
||||
func (x *Lock) GetName() string {
|
||||
@@ -3927,6 +4038,13 @@ func (x *Lock) GetExpiredAtNs() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Lock) GetOwner() string {
|
||||
if x != nil {
|
||||
return x.Owner
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TransferLocksRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -3938,7 +4056,7 @@ type TransferLocksRequest struct {
|
||||
func (x *TransferLocksRequest) Reset() {
|
||||
*x = TransferLocksRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_filer_proto_msgTypes[60]
|
||||
mi := &file_filer_proto_msgTypes[62]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -3951,7 +4069,7 @@ func (x *TransferLocksRequest) String() string {
|
||||
func (*TransferLocksRequest) ProtoMessage() {}
|
||||
|
||||
func (x *TransferLocksRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_filer_proto_msgTypes[60]
|
||||
mi := &file_filer_proto_msgTypes[62]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -3964,7 +4082,7 @@ func (x *TransferLocksRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use TransferLocksRequest.ProtoReflect.Descriptor instead.
|
||||
func (*TransferLocksRequest) Descriptor() ([]byte, []int) {
|
||||
return file_filer_proto_rawDescGZIP(), []int{60}
|
||||
return file_filer_proto_rawDescGZIP(), []int{62}
|
||||
}
|
||||
|
||||
func (x *TransferLocksRequest) GetLocks() []*Lock {
|
||||
@@ -3983,7 +4101,7 @@ type TransferLocksResponse struct {
|
||||
func (x *TransferLocksResponse) Reset() {
|
||||
*x = TransferLocksResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_filer_proto_msgTypes[61]
|
||||
mi := &file_filer_proto_msgTypes[63]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -3996,7 +4114,7 @@ func (x *TransferLocksResponse) String() string {
|
||||
func (*TransferLocksResponse) ProtoMessage() {}
|
||||
|
||||
func (x *TransferLocksResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_filer_proto_msgTypes[61]
|
||||
mi := &file_filer_proto_msgTypes[63]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -4009,7 +4127,7 @@ func (x *TransferLocksResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use TransferLocksResponse.ProtoReflect.Descriptor instead.
|
||||
func (*TransferLocksResponse) Descriptor() ([]byte, []int) {
|
||||
return file_filer_proto_rawDescGZIP(), []int{61}
|
||||
return file_filer_proto_rawDescGZIP(), []int{63}
|
||||
}
|
||||
|
||||
// if found, send the exact address
|
||||
@@ -4026,7 +4144,7 @@ type LocateBrokerResponse_Resource struct {
|
||||
func (x *LocateBrokerResponse_Resource) Reset() {
|
||||
*x = LocateBrokerResponse_Resource{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_filer_proto_msgTypes[64]
|
||||
mi := &file_filer_proto_msgTypes[66]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -4039,7 +4157,7 @@ func (x *LocateBrokerResponse_Resource) String() string {
|
||||
func (*LocateBrokerResponse_Resource) ProtoMessage() {}
|
||||
|
||||
func (x *LocateBrokerResponse_Resource) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_filer_proto_msgTypes[64]
|
||||
mi := &file_filer_proto_msgTypes[66]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -4090,7 +4208,7 @@ type FilerConf_PathConf struct {
|
||||
func (x *FilerConf_PathConf) Reset() {
|
||||
*x = FilerConf_PathConf{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_filer_proto_msgTypes[65]
|
||||
mi := &file_filer_proto_msgTypes[67]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -4103,7 +4221,7 @@ func (x *FilerConf_PathConf) String() string {
|
||||
func (*FilerConf_PathConf) ProtoMessage() {}
|
||||
|
||||
func (x *FilerConf_PathConf) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_filer_proto_msgTypes[65]
|
||||
mi := &file_filer_proto_msgTypes[67]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -4687,7 +4805,7 @@ var file_filer_proto_rawDesc = []byte{
|
||||
0x54, 0x6f, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62,
|
||||
0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x85, 0x01,
|
||||
0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x9b, 0x01,
|
||||
0x0a, 0x0b, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x74, 0x6f, 0x5f,
|
||||
@@ -4696,163 +4814,179 @@ var file_filer_proto_rawDesc = []byte{
|
||||
0x65, 0x77, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x72, 0x65, 0x6e, 0x65, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73,
|
||||
0x5f, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73,
|
||||
0x4d, 0x6f, 0x76, 0x65, 0x64, 0x22, 0x60, 0x0a, 0x0c, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x5f, 0x74,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x6e, 0x65,
|
||||
0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f,
|
||||
0x4d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x60, 0x0a, 0x0c, 0x4c,
|
||||
0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72,
|
||||
0x65, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0a, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x19, 0x0a, 0x08,
|
||||
0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
||||
0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x5f, 0x0a,
|
||||
0x0d, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x4d, 0x6f, 0x76, 0x65, 0x64, 0x22, 0x41,
|
||||
0x0a, 0x0e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f,
|
||||
0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54,
|
||||
0x6f, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x5f, 0x0a, 0x0d, 0x55, 0x6e, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b,
|
||||
0x72, 0x65, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0a, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x19, 0x0a,
|
||||
0x08, 0x69, 0x73, 0x5f, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x07, 0x69, 0x73, 0x4d, 0x6f, 0x76, 0x65, 0x64, 0x22, 0x41, 0x0a, 0x0e, 0x55, 0x6e, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72,
|
||||
0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72,
|
||||
0x12, 0x19, 0x0a, 0x08, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x07, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x6f, 0x22, 0x5f, 0x0a, 0x04, 0x4c,
|
||||
0x6f, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x6e, 0x65, 0x77,
|
||||
0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65,
|
||||
0x6e, 0x65, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x69,
|
||||
0x72, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x41, 0x74, 0x4e, 0x73, 0x22, 0x3c, 0x0a, 0x14,
|
||||
0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x05, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c,
|
||||
0x6f, 0x63, 0x6b, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x54, 0x72,
|
||||
0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x32, 0xa5, 0x0f, 0x0a, 0x0c, 0x53, 0x65, 0x61, 0x77, 0x65, 0x65, 0x64, 0x46,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x12, 0x67, 0x0a, 0x14, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x44, 0x69,
|
||||
0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x25, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x44, 0x69,
|
||||
0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c,
|
||||
0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a,
|
||||
0x0b, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x4c, 0x0a,
|
||||
0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0b, 0x55,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72,
|
||||
0x5f, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x0d, 0x41, 0x70, 0x70,
|
||||
0x65, 0x6e, 0x64, 0x54, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1e, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a,
|
||||
0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x11, 0x41,
|
||||
0x74, 0x6f, 0x6d, 0x69, 0x63, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x12, 0x22, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x74, 0x6f, 0x6d,
|
||||
0x69, 0x63, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e,
|
||||
0x41, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, 0x53,
|
||||
0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x12, 0x22, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x65,
|
||||
0x61, 0x6d, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e,
|
||||
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x4f, 0x0a,
|
||||
0x0c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x1d, 0x2e,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x56,
|
||||
0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x56, 0x6f,
|
||||
0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f,
|
||||
0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x1d,
|
||||
0x6f, 0x22, 0x45, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x6b, 0x4f, 0x77, 0x6e,
|
||||
0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a,
|
||||
0x08, 0x69, 0x73, 0x5f, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x07, 0x69, 0x73, 0x4d, 0x6f, 0x76, 0x65, 0x64, 0x22, 0x2d, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64,
|
||||
0x4c, 0x6f, 0x63, 0x6b, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x75, 0x0a, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x54,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x5f,
|
||||
0x61, 0x74, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x65, 0x78, 0x70,
|
||||
0x69, 0x72, 0x65, 0x64, 0x41, 0x74, 0x4e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65,
|
||||
0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x3c,
|
||||
0x0a, 0x14, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x6b, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x05, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62,
|
||||
0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x22, 0x17, 0x0a, 0x15,
|
||||
0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8f, 0x10, 0x0a, 0x0c, 0x53, 0x65, 0x61, 0x77, 0x65, 0x65,
|
||||
0x64, 0x46, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x67, 0x0a, 0x14, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70,
|
||||
0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x25,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70,
|
||||
0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56,
|
||||
0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
||||
0x55, 0x0a, 0x0e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x12, 0x1f, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x20, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x43, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
||||
0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43,
|
||||
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
|
||||
0x73, 0x12, 0x1b, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61,
|
||||
0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73,
|
||||
0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37,
|
||||
0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x15, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70,
|
||||
0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x46, 0x69,
|
||||
0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x26, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x46,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72,
|
||||
0x5f, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
|
||||
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x22, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72,
|
||||
0x5f, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62,
|
||||
0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x65, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
|
||||
0x62, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12,
|
||||
0x22, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63,
|
||||
0x72, 0x69, 0x62, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53,
|
||||
0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3a, 0x0a, 0x05,
|
||||
0x4b, 0x76, 0x47, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62,
|
||||
0x2e, 0x4b, 0x76, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4b, 0x76, 0x47, 0x65, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x05, 0x4b, 0x76, 0x50, 0x75,
|
||||
0x74, 0x12, 0x16, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4b, 0x76, 0x50,
|
||||
0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4b, 0x76, 0x50, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x12, 0x88, 0x01, 0x0a, 0x1f, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65,
|
||||
0x6d, 0x6f, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x4c, 0x6f, 0x63, 0x61,
|
||||
0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72,
|
||||
0x5f, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73,
|
||||
0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62,
|
||||
0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
||||
0x4e, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1c,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12,
|
||||
0x4c, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1c,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a,
|
||||
0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x0d, 0x41,
|
||||
0x70, 0x70, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1e, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x54, 0x6f,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x54, 0x6f,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
||||
0x4c, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1c,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a,
|
||||
0x11, 0x41, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x12, 0x22, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x74,
|
||||
0x6f, 0x6d, 0x69, 0x63, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70,
|
||||
0x62, 0x2e, 0x41, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a,
|
||||
0x11, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x12, 0x22, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x74,
|
||||
0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70,
|
||||
0x62, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12,
|
||||
0x4f, 0x0a, 0x0c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12,
|
||||
0x1d, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
||||
0x12, 0x4f, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65,
|
||||
0x12, 0x1d, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b,
|
||||
0x75, 0x70, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x1e, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75,
|
||||
0x70, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x12, 0x55, 0x0a, 0x0e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x12, 0x1f, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x43,
|
||||
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e,
|
||||
0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65,
|
||||
0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x22, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74,
|
||||
0x69, 0x63, 0x73, 0x12, 0x1b, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53,
|
||||
0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1c, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
||||
0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
||||
0x12, 0x37, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x15, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72,
|
||||
0x5f, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x16, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x15, 0x47, 0x65, 0x74,
|
||||
0x46, 0x69, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x26, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x46, 0x69, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x72, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
|
||||
0x62, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x22, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
|
||||
0x69, 0x62, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x65, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63,
|
||||
0x72, 0x69, 0x62, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0x12, 0x22, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x62,
|
||||
0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62,
|
||||
0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
|
||||
0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3a,
|
||||
0x0a, 0x05, 0x4b, 0x76, 0x47, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f,
|
||||
0x70, 0x62, 0x2e, 0x4b, 0x76, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x17, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4b, 0x76, 0x47, 0x65, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x05, 0x4b, 0x76,
|
||||
0x50, 0x75, 0x74, 0x12, 0x16, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4b,
|
||||
0x76, 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4b, 0x76, 0x50, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x88, 0x01, 0x0a, 0x1f, 0x43, 0x61, 0x63, 0x68, 0x65,
|
||||
0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x4c, 0x6f,
|
||||
0x63, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74,
|
||||
0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6c,
|
||||
0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
||||
0x37, 0x0a, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f,
|
||||
0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x06, 0x55, 0x6e, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x12, 0x17, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x55, 0x6e,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73,
|
||||
0x66, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x1e, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72,
|
||||
0x5f, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x6b,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72,
|
||||
0x5f, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x6b,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4f, 0x0a, 0x10, 0x73,
|
||||
0x65, 0x61, 0x77, 0x65, 0x65, 0x64, 0x66, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x42,
|
||||
0x0a, 0x46, 0x69, 0x6c, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x2f, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x61, 0x77, 0x65, 0x65, 0x64, 0x66,
|
||||
0x73, 0x2f, 0x73, 0x65, 0x61, 0x77, 0x65, 0x65, 0x64, 0x66, 0x73, 0x2f, 0x77, 0x65, 0x65, 0x64,
|
||||
0x2f, 0x70, 0x62, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x6d,
|
||||
0x6f, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
|
||||
0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x12, 0x42, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64,
|
||||
0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e,
|
||||
0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x11, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62,
|
||||
0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x17, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x55,
|
||||
0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
||||
0x52, 0x0a, 0x0d, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x6b, 0x4f, 0x77, 0x6e, 0x65, 0x72,
|
||||
0x12, 0x1e, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64,
|
||||
0x4c, 0x6f, 0x63, 0x6b, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1f, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64,
|
||||
0x4c, 0x6f, 0x63, 0x6b, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c,
|
||||
0x6f, 0x63, 0x6b, 0x73, 0x12, 0x1e, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e,
|
||||
0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x2e,
|
||||
0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4f, 0x0a, 0x10, 0x73, 0x65, 0x61, 0x77, 0x65,
|
||||
0x65, 0x64, 0x66, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x0a, 0x46, 0x69, 0x6c,
|
||||
0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x61, 0x77, 0x65, 0x65, 0x64, 0x66, 0x73, 0x2f, 0x73, 0x65,
|
||||
0x61, 0x77, 0x65, 0x65, 0x64, 0x66, 0x73, 0x2f, 0x77, 0x65, 0x65, 0x64, 0x2f, 0x70, 0x62, 0x2f,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -4867,7 +5001,7 @@ func file_filer_proto_rawDescGZIP() []byte {
|
||||
return file_filer_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_filer_proto_msgTypes = make([]protoimpl.MessageInfo, 66)
|
||||
var file_filer_proto_msgTypes = make([]protoimpl.MessageInfo, 68)
|
||||
var file_filer_proto_goTypes = []interface{}{
|
||||
(*LookupDirectoryEntryRequest)(nil), // 0: filer_pb.LookupDirectoryEntryRequest
|
||||
(*LookupDirectoryEntryResponse)(nil), // 1: filer_pb.LookupDirectoryEntryResponse
|
||||
@@ -4928,20 +5062,22 @@ var file_filer_proto_goTypes = []interface{}{
|
||||
(*LockResponse)(nil), // 56: filer_pb.LockResponse
|
||||
(*UnlockRequest)(nil), // 57: filer_pb.UnlockRequest
|
||||
(*UnlockResponse)(nil), // 58: filer_pb.UnlockResponse
|
||||
(*Lock)(nil), // 59: filer_pb.Lock
|
||||
(*TransferLocksRequest)(nil), // 60: filer_pb.TransferLocksRequest
|
||||
(*TransferLocksResponse)(nil), // 61: filer_pb.TransferLocksResponse
|
||||
nil, // 62: filer_pb.Entry.ExtendedEntry
|
||||
nil, // 63: filer_pb.LookupVolumeResponse.LocationsMapEntry
|
||||
(*LocateBrokerResponse_Resource)(nil), // 64: filer_pb.LocateBrokerResponse.Resource
|
||||
(*FilerConf_PathConf)(nil), // 65: filer_pb.FilerConf.PathConf
|
||||
(*FindLockOwnerRequest)(nil), // 59: filer_pb.FindLockOwnerRequest
|
||||
(*FindLockOwnerResponse)(nil), // 60: filer_pb.FindLockOwnerResponse
|
||||
(*Lock)(nil), // 61: filer_pb.Lock
|
||||
(*TransferLocksRequest)(nil), // 62: filer_pb.TransferLocksRequest
|
||||
(*TransferLocksResponse)(nil), // 63: filer_pb.TransferLocksResponse
|
||||
nil, // 64: filer_pb.Entry.ExtendedEntry
|
||||
nil, // 65: filer_pb.LookupVolumeResponse.LocationsMapEntry
|
||||
(*LocateBrokerResponse_Resource)(nil), // 66: filer_pb.LocateBrokerResponse.Resource
|
||||
(*FilerConf_PathConf)(nil), // 67: filer_pb.FilerConf.PathConf
|
||||
}
|
||||
var file_filer_proto_depIdxs = []int32{
|
||||
5, // 0: filer_pb.LookupDirectoryEntryResponse.entry:type_name -> filer_pb.Entry
|
||||
5, // 1: filer_pb.ListEntriesResponse.entry:type_name -> filer_pb.Entry
|
||||
8, // 2: filer_pb.Entry.chunks:type_name -> filer_pb.FileChunk
|
||||
11, // 3: filer_pb.Entry.attributes:type_name -> filer_pb.FuseAttributes
|
||||
62, // 4: filer_pb.Entry.extended:type_name -> filer_pb.Entry.ExtendedEntry
|
||||
64, // 4: filer_pb.Entry.extended:type_name -> filer_pb.Entry.ExtendedEntry
|
||||
4, // 5: filer_pb.Entry.remote_entry:type_name -> filer_pb.RemoteEntry
|
||||
5, // 6: filer_pb.FullEntry.entry:type_name -> filer_pb.Entry
|
||||
5, // 7: filer_pb.EventNotification.old_entry:type_name -> filer_pb.Entry
|
||||
@@ -4955,13 +5091,13 @@ var file_filer_proto_depIdxs = []int32{
|
||||
7, // 15: filer_pb.StreamRenameEntryResponse.event_notification:type_name -> filer_pb.EventNotification
|
||||
28, // 16: filer_pb.AssignVolumeResponse.location:type_name -> filer_pb.Location
|
||||
28, // 17: filer_pb.Locations.locations:type_name -> filer_pb.Location
|
||||
63, // 18: filer_pb.LookupVolumeResponse.locations_map:type_name -> filer_pb.LookupVolumeResponse.LocationsMapEntry
|
||||
65, // 18: filer_pb.LookupVolumeResponse.locations_map:type_name -> filer_pb.LookupVolumeResponse.LocationsMapEntry
|
||||
30, // 19: filer_pb.CollectionListResponse.collections:type_name -> filer_pb.Collection
|
||||
7, // 20: filer_pb.SubscribeMetadataResponse.event_notification:type_name -> filer_pb.EventNotification
|
||||
64, // 21: filer_pb.LocateBrokerResponse.resources:type_name -> filer_pb.LocateBrokerResponse.Resource
|
||||
65, // 22: filer_pb.FilerConf.locations:type_name -> filer_pb.FilerConf.PathConf
|
||||
66, // 21: filer_pb.LocateBrokerResponse.resources:type_name -> filer_pb.LocateBrokerResponse.Resource
|
||||
67, // 22: filer_pb.FilerConf.locations:type_name -> filer_pb.FilerConf.PathConf
|
||||
5, // 23: filer_pb.CacheRemoteObjectToLocalClusterResponse.entry:type_name -> filer_pb.Entry
|
||||
59, // 24: filer_pb.TransferLocksRequest.locks:type_name -> filer_pb.Lock
|
||||
61, // 24: filer_pb.TransferLocksRequest.locks:type_name -> filer_pb.Lock
|
||||
27, // 25: filer_pb.LookupVolumeResponse.LocationsMapEntry.value:type_name -> filer_pb.Locations
|
||||
0, // 26: filer_pb.SeaweedFiler.LookupDirectoryEntry:input_type -> filer_pb.LookupDirectoryEntryRequest
|
||||
2, // 27: filer_pb.SeaweedFiler.ListEntries:input_type -> filer_pb.ListEntriesRequest
|
||||
@@ -4983,34 +5119,36 @@ var file_filer_proto_depIdxs = []int32{
|
||||
48, // 43: filer_pb.SeaweedFiler.KvGet:input_type -> filer_pb.KvGetRequest
|
||||
50, // 44: filer_pb.SeaweedFiler.KvPut:input_type -> filer_pb.KvPutRequest
|
||||
53, // 45: filer_pb.SeaweedFiler.CacheRemoteObjectToLocalCluster:input_type -> filer_pb.CacheRemoteObjectToLocalClusterRequest
|
||||
55, // 46: filer_pb.SeaweedFiler.Lock:input_type -> filer_pb.LockRequest
|
||||
57, // 47: filer_pb.SeaweedFiler.Unlock:input_type -> filer_pb.UnlockRequest
|
||||
60, // 48: filer_pb.SeaweedFiler.TransferLocks:input_type -> filer_pb.TransferLocksRequest
|
||||
1, // 49: filer_pb.SeaweedFiler.LookupDirectoryEntry:output_type -> filer_pb.LookupDirectoryEntryResponse
|
||||
3, // 50: filer_pb.SeaweedFiler.ListEntries:output_type -> filer_pb.ListEntriesResponse
|
||||
13, // 51: filer_pb.SeaweedFiler.CreateEntry:output_type -> filer_pb.CreateEntryResponse
|
||||
15, // 52: filer_pb.SeaweedFiler.UpdateEntry:output_type -> filer_pb.UpdateEntryResponse
|
||||
17, // 53: filer_pb.SeaweedFiler.AppendToEntry:output_type -> filer_pb.AppendToEntryResponse
|
||||
19, // 54: filer_pb.SeaweedFiler.DeleteEntry:output_type -> filer_pb.DeleteEntryResponse
|
||||
21, // 55: filer_pb.SeaweedFiler.AtomicRenameEntry:output_type -> filer_pb.AtomicRenameEntryResponse
|
||||
23, // 56: filer_pb.SeaweedFiler.StreamRenameEntry:output_type -> filer_pb.StreamRenameEntryResponse
|
||||
25, // 57: filer_pb.SeaweedFiler.AssignVolume:output_type -> filer_pb.AssignVolumeResponse
|
||||
29, // 58: filer_pb.SeaweedFiler.LookupVolume:output_type -> filer_pb.LookupVolumeResponse
|
||||
32, // 59: filer_pb.SeaweedFiler.CollectionList:output_type -> filer_pb.CollectionListResponse
|
||||
34, // 60: filer_pb.SeaweedFiler.DeleteCollection:output_type -> filer_pb.DeleteCollectionResponse
|
||||
36, // 61: filer_pb.SeaweedFiler.Statistics:output_type -> filer_pb.StatisticsResponse
|
||||
38, // 62: filer_pb.SeaweedFiler.Ping:output_type -> filer_pb.PingResponse
|
||||
40, // 63: filer_pb.SeaweedFiler.GetFilerConfiguration:output_type -> filer_pb.GetFilerConfigurationResponse
|
||||
42, // 64: filer_pb.SeaweedFiler.SubscribeMetadata:output_type -> filer_pb.SubscribeMetadataResponse
|
||||
42, // 65: filer_pb.SeaweedFiler.SubscribeLocalMetadata:output_type -> filer_pb.SubscribeMetadataResponse
|
||||
49, // 66: filer_pb.SeaweedFiler.KvGet:output_type -> filer_pb.KvGetResponse
|
||||
51, // 67: filer_pb.SeaweedFiler.KvPut:output_type -> filer_pb.KvPutResponse
|
||||
54, // 68: filer_pb.SeaweedFiler.CacheRemoteObjectToLocalCluster:output_type -> filer_pb.CacheRemoteObjectToLocalClusterResponse
|
||||
56, // 69: filer_pb.SeaweedFiler.Lock:output_type -> filer_pb.LockResponse
|
||||
58, // 70: filer_pb.SeaweedFiler.Unlock:output_type -> filer_pb.UnlockResponse
|
||||
61, // 71: filer_pb.SeaweedFiler.TransferLocks:output_type -> filer_pb.TransferLocksResponse
|
||||
49, // [49:72] is the sub-list for method output_type
|
||||
26, // [26:49] is the sub-list for method input_type
|
||||
55, // 46: filer_pb.SeaweedFiler.DistributedLock:input_type -> filer_pb.LockRequest
|
||||
57, // 47: filer_pb.SeaweedFiler.DistributedUnlock:input_type -> filer_pb.UnlockRequest
|
||||
59, // 48: filer_pb.SeaweedFiler.FindLockOwner:input_type -> filer_pb.FindLockOwnerRequest
|
||||
62, // 49: filer_pb.SeaweedFiler.TransferLocks:input_type -> filer_pb.TransferLocksRequest
|
||||
1, // 50: filer_pb.SeaweedFiler.LookupDirectoryEntry:output_type -> filer_pb.LookupDirectoryEntryResponse
|
||||
3, // 51: filer_pb.SeaweedFiler.ListEntries:output_type -> filer_pb.ListEntriesResponse
|
||||
13, // 52: filer_pb.SeaweedFiler.CreateEntry:output_type -> filer_pb.CreateEntryResponse
|
||||
15, // 53: filer_pb.SeaweedFiler.UpdateEntry:output_type -> filer_pb.UpdateEntryResponse
|
||||
17, // 54: filer_pb.SeaweedFiler.AppendToEntry:output_type -> filer_pb.AppendToEntryResponse
|
||||
19, // 55: filer_pb.SeaweedFiler.DeleteEntry:output_type -> filer_pb.DeleteEntryResponse
|
||||
21, // 56: filer_pb.SeaweedFiler.AtomicRenameEntry:output_type -> filer_pb.AtomicRenameEntryResponse
|
||||
23, // 57: filer_pb.SeaweedFiler.StreamRenameEntry:output_type -> filer_pb.StreamRenameEntryResponse
|
||||
25, // 58: filer_pb.SeaweedFiler.AssignVolume:output_type -> filer_pb.AssignVolumeResponse
|
||||
29, // 59: filer_pb.SeaweedFiler.LookupVolume:output_type -> filer_pb.LookupVolumeResponse
|
||||
32, // 60: filer_pb.SeaweedFiler.CollectionList:output_type -> filer_pb.CollectionListResponse
|
||||
34, // 61: filer_pb.SeaweedFiler.DeleteCollection:output_type -> filer_pb.DeleteCollectionResponse
|
||||
36, // 62: filer_pb.SeaweedFiler.Statistics:output_type -> filer_pb.StatisticsResponse
|
||||
38, // 63: filer_pb.SeaweedFiler.Ping:output_type -> filer_pb.PingResponse
|
||||
40, // 64: filer_pb.SeaweedFiler.GetFilerConfiguration:output_type -> filer_pb.GetFilerConfigurationResponse
|
||||
42, // 65: filer_pb.SeaweedFiler.SubscribeMetadata:output_type -> filer_pb.SubscribeMetadataResponse
|
||||
42, // 66: filer_pb.SeaweedFiler.SubscribeLocalMetadata:output_type -> filer_pb.SubscribeMetadataResponse
|
||||
49, // 67: filer_pb.SeaweedFiler.KvGet:output_type -> filer_pb.KvGetResponse
|
||||
51, // 68: filer_pb.SeaweedFiler.KvPut:output_type -> filer_pb.KvPutResponse
|
||||
54, // 69: filer_pb.SeaweedFiler.CacheRemoteObjectToLocalCluster:output_type -> filer_pb.CacheRemoteObjectToLocalClusterResponse
|
||||
56, // 70: filer_pb.SeaweedFiler.DistributedLock:output_type -> filer_pb.LockResponse
|
||||
58, // 71: filer_pb.SeaweedFiler.DistributedUnlock:output_type -> filer_pb.UnlockResponse
|
||||
60, // 72: filer_pb.SeaweedFiler.FindLockOwner:output_type -> filer_pb.FindLockOwnerResponse
|
||||
63, // 73: filer_pb.SeaweedFiler.TransferLocks:output_type -> filer_pb.TransferLocksResponse
|
||||
50, // [50:74] is the sub-list for method output_type
|
||||
26, // [26:50] is the sub-list for method input_type
|
||||
26, // [26:26] is the sub-list for extension type_name
|
||||
26, // [26:26] is the sub-list for extension extendee
|
||||
0, // [0:26] is the sub-list for field type_name
|
||||
@@ -5731,7 +5869,7 @@ func file_filer_proto_init() {
|
||||
}
|
||||
}
|
||||
file_filer_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Lock); i {
|
||||
switch v := v.(*FindLockOwnerRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -5743,7 +5881,7 @@ func file_filer_proto_init() {
|
||||
}
|
||||
}
|
||||
file_filer_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TransferLocksRequest); i {
|
||||
switch v := v.(*FindLockOwnerResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -5755,6 +5893,30 @@ func file_filer_proto_init() {
|
||||
}
|
||||
}
|
||||
file_filer_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Lock); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_filer_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TransferLocksRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_filer_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TransferLocksResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -5766,7 +5928,7 @@ func file_filer_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_filer_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_filer_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*LocateBrokerResponse_Resource); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -5778,7 +5940,7 @@ func file_filer_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_filer_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_filer_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*FilerConf_PathConf); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -5797,7 +5959,7 @@ func file_filer_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_filer_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 66,
|
||||
NumMessages: 68,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -42,8 +42,10 @@ type SeaweedFilerClient interface {
|
||||
KvGet(ctx context.Context, in *KvGetRequest, opts ...grpc.CallOption) (*KvGetResponse, error)
|
||||
KvPut(ctx context.Context, in *KvPutRequest, opts ...grpc.CallOption) (*KvPutResponse, error)
|
||||
CacheRemoteObjectToLocalCluster(ctx context.Context, in *CacheRemoteObjectToLocalClusterRequest, opts ...grpc.CallOption) (*CacheRemoteObjectToLocalClusterResponse, error)
|
||||
Lock(ctx context.Context, in *LockRequest, opts ...grpc.CallOption) (*LockResponse, error)
|
||||
Unlock(ctx context.Context, in *UnlockRequest, opts ...grpc.CallOption) (*UnlockResponse, error)
|
||||
DistributedLock(ctx context.Context, in *LockRequest, opts ...grpc.CallOption) (*LockResponse, error)
|
||||
DistributedUnlock(ctx context.Context, in *UnlockRequest, opts ...grpc.CallOption) (*UnlockResponse, error)
|
||||
FindLockOwner(ctx context.Context, in *FindLockOwnerRequest, opts ...grpc.CallOption) (*FindLockOwnerResponse, error)
|
||||
// distributed lock management internal use only
|
||||
TransferLocks(ctx context.Context, in *TransferLocksRequest, opts ...grpc.CallOption) (*TransferLocksResponse, error)
|
||||
}
|
||||
|
||||
@@ -327,18 +329,27 @@ func (c *seaweedFilerClient) CacheRemoteObjectToLocalCluster(ctx context.Context
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedFilerClient) Lock(ctx context.Context, in *LockRequest, opts ...grpc.CallOption) (*LockResponse, error) {
|
||||
func (c *seaweedFilerClient) DistributedLock(ctx context.Context, in *LockRequest, opts ...grpc.CallOption) (*LockResponse, error) {
|
||||
out := new(LockResponse)
|
||||
err := c.cc.Invoke(ctx, "/filer_pb.SeaweedFiler/Lock", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/filer_pb.SeaweedFiler/DistributedLock", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedFilerClient) Unlock(ctx context.Context, in *UnlockRequest, opts ...grpc.CallOption) (*UnlockResponse, error) {
|
||||
func (c *seaweedFilerClient) DistributedUnlock(ctx context.Context, in *UnlockRequest, opts ...grpc.CallOption) (*UnlockResponse, error) {
|
||||
out := new(UnlockResponse)
|
||||
err := c.cc.Invoke(ctx, "/filer_pb.SeaweedFiler/Unlock", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/filer_pb.SeaweedFiler/DistributedUnlock", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedFilerClient) FindLockOwner(ctx context.Context, in *FindLockOwnerRequest, opts ...grpc.CallOption) (*FindLockOwnerResponse, error) {
|
||||
out := new(FindLockOwnerResponse)
|
||||
err := c.cc.Invoke(ctx, "/filer_pb.SeaweedFiler/FindLockOwner", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -378,8 +389,10 @@ type SeaweedFilerServer interface {
|
||||
KvGet(context.Context, *KvGetRequest) (*KvGetResponse, error)
|
||||
KvPut(context.Context, *KvPutRequest) (*KvPutResponse, error)
|
||||
CacheRemoteObjectToLocalCluster(context.Context, *CacheRemoteObjectToLocalClusterRequest) (*CacheRemoteObjectToLocalClusterResponse, error)
|
||||
Lock(context.Context, *LockRequest) (*LockResponse, error)
|
||||
Unlock(context.Context, *UnlockRequest) (*UnlockResponse, error)
|
||||
DistributedLock(context.Context, *LockRequest) (*LockResponse, error)
|
||||
DistributedUnlock(context.Context, *UnlockRequest) (*UnlockResponse, error)
|
||||
FindLockOwner(context.Context, *FindLockOwnerRequest) (*FindLockOwnerResponse, error)
|
||||
// distributed lock management internal use only
|
||||
TransferLocks(context.Context, *TransferLocksRequest) (*TransferLocksResponse, error)
|
||||
mustEmbedUnimplementedSeaweedFilerServer()
|
||||
}
|
||||
@@ -448,11 +461,14 @@ func (UnimplementedSeaweedFilerServer) KvPut(context.Context, *KvPutRequest) (*K
|
||||
func (UnimplementedSeaweedFilerServer) CacheRemoteObjectToLocalCluster(context.Context, *CacheRemoteObjectToLocalClusterRequest) (*CacheRemoteObjectToLocalClusterResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CacheRemoteObjectToLocalCluster not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedFilerServer) Lock(context.Context, *LockRequest) (*LockResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Lock not implemented")
|
||||
func (UnimplementedSeaweedFilerServer) DistributedLock(context.Context, *LockRequest) (*LockResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DistributedLock not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedFilerServer) Unlock(context.Context, *UnlockRequest) (*UnlockResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Unlock not implemented")
|
||||
func (UnimplementedSeaweedFilerServer) DistributedUnlock(context.Context, *UnlockRequest) (*UnlockResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DistributedUnlock not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedFilerServer) FindLockOwner(context.Context, *FindLockOwnerRequest) (*FindLockOwnerResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method FindLockOwner not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedFilerServer) TransferLocks(context.Context, *TransferLocksRequest) (*TransferLocksResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method TransferLocks not implemented")
|
||||
@@ -842,38 +858,56 @@ func _SeaweedFiler_CacheRemoteObjectToLocalCluster_Handler(srv interface{}, ctx
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SeaweedFiler_Lock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _SeaweedFiler_DistributedLock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(LockRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedFilerServer).Lock(ctx, in)
|
||||
return srv.(SeaweedFilerServer).DistributedLock(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/filer_pb.SeaweedFiler/Lock",
|
||||
FullMethod: "/filer_pb.SeaweedFiler/DistributedLock",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedFilerServer).Lock(ctx, req.(*LockRequest))
|
||||
return srv.(SeaweedFilerServer).DistributedLock(ctx, req.(*LockRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SeaweedFiler_Unlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _SeaweedFiler_DistributedUnlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UnlockRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedFilerServer).Unlock(ctx, in)
|
||||
return srv.(SeaweedFilerServer).DistributedUnlock(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/filer_pb.SeaweedFiler/Unlock",
|
||||
FullMethod: "/filer_pb.SeaweedFiler/DistributedUnlock",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedFilerServer).Unlock(ctx, req.(*UnlockRequest))
|
||||
return srv.(SeaweedFilerServer).DistributedUnlock(ctx, req.(*UnlockRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SeaweedFiler_FindLockOwner_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(FindLockOwnerRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedFilerServer).FindLockOwner(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/filer_pb.SeaweedFiler/FindLockOwner",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedFilerServer).FindLockOwner(ctx, req.(*FindLockOwnerRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -968,12 +1002,16 @@ var SeaweedFiler_ServiceDesc = grpc.ServiceDesc{
|
||||
Handler: _SeaweedFiler_CacheRemoteObjectToLocalCluster_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Lock",
|
||||
Handler: _SeaweedFiler_Lock_Handler,
|
||||
MethodName: "DistributedLock",
|
||||
Handler: _SeaweedFiler_DistributedLock_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Unlock",
|
||||
Handler: _SeaweedFiler_Unlock_Handler,
|
||||
MethodName: "DistributedUnlock",
|
||||
Handler: _SeaweedFiler_DistributedUnlock_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "FindLockOwner",
|
||||
Handler: _SeaweedFiler_FindLockOwner_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "TransferLocks",
|
||||
|
||||
@@ -225,14 +225,6 @@ func WithVolumeServerClient(streamingMode bool, volumeServer ServerAddress, grpc
|
||||
|
||||
}
|
||||
|
||||
func WithBrokerClient(streamingMode bool, broker ServerAddress, grpcDialOption grpc.DialOption, fn func(client mq_pb.SeaweedMessagingClient) error) error {
|
||||
return WithGrpcClient(streamingMode, 0, func(grpcConnection *grpc.ClientConn) error {
|
||||
client := mq_pb.NewSeaweedMessagingClient(grpcConnection)
|
||||
return fn(client)
|
||||
}, broker.ToGrpcAddress(), false, grpcDialOption)
|
||||
|
||||
}
|
||||
|
||||
func WithOneOfGrpcMasterClients(streamingMode bool, masterGrpcAddresses map[string]ServerAddress, grpcDialOption grpc.DialOption, fn func(client master_pb.SeaweedClient) error) (err error) {
|
||||
|
||||
for _, masterGrpcAddress := range masterGrpcAddresses {
|
||||
|
||||
+102
-23
@@ -20,8 +20,17 @@ service SeaweedMessaging {
|
||||
rpc CheckBrokerLoad (CheckBrokerLoadRequest) returns (CheckBrokerLoadResponse) {
|
||||
}
|
||||
|
||||
// control plane for balancer
|
||||
rpc ConnectToBalancer (stream ConnectToBalancerRequest) returns (stream ConnectToBalancerResponse) {
|
||||
}
|
||||
// control plane for topic partitions
|
||||
rpc FindTopicBrokers (FindTopicBrokersRequest) returns (FindTopicBrokersResponse) {
|
||||
rpc LookupTopicBrokers (LookupTopicBrokersRequest) returns (LookupTopicBrokersResponse) {
|
||||
}
|
||||
rpc CreateTopic (CreateTopicRequest) returns (CreateTopicResponse) {
|
||||
}
|
||||
rpc DoCreateTopic (DoCreateTopicRequest) returns (DoCreateTopicResponse) {
|
||||
}
|
||||
rpc ListTopics (ListTopicsRequest) returns (ListTopicsResponse) {
|
||||
}
|
||||
// a pub client will call this to get the topic partitions assignment
|
||||
rpc RequestTopicPartitions (RequestTopicPartitionsRequest) returns (RequestTopicPartitionsResponse) {
|
||||
@@ -34,6 +43,8 @@ service SeaweedMessaging {
|
||||
// data plane
|
||||
rpc Publish (stream PublishRequest) returns (stream PublishResponse) {
|
||||
}
|
||||
rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse) {
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
@@ -98,23 +109,61 @@ message CheckBrokerLoadResponse {
|
||||
|
||||
}
|
||||
|
||||
message FindTopicBrokersRequest {
|
||||
//////////////////////////////////////////////////
|
||||
message BrokerStats {
|
||||
int32 cpu_usage_percent = 1;
|
||||
map<string, TopicPartitionStats> stats = 2;
|
||||
}
|
||||
message TopicPartitionStats {
|
||||
Topic topic = 1;
|
||||
Partition partition = 2;
|
||||
int32 consumer_count = 3;
|
||||
bool is_leader = 4;
|
||||
}
|
||||
|
||||
|
||||
message ConnectToBalancerRequest {
|
||||
message InitMessage {
|
||||
string broker = 1;
|
||||
}
|
||||
oneof message {
|
||||
InitMessage init = 1;
|
||||
BrokerStats stats = 2;
|
||||
}
|
||||
}
|
||||
message ConnectToBalancerResponse {
|
||||
}
|
||||
//////////////////////////////////////////////////
|
||||
message CreateTopicRequest {
|
||||
Topic topic = 1;
|
||||
int32 partition_count = 2;
|
||||
}
|
||||
message CreateTopicResponse {
|
||||
repeated BrokerPartitionAssignment broker_partition_assignments = 2;
|
||||
}
|
||||
message DoCreateTopicRequest {
|
||||
Topic topic = 1;
|
||||
Partition partition = 2;
|
||||
}
|
||||
message DoCreateTopicResponse {
|
||||
}
|
||||
message ListTopicsRequest {
|
||||
}
|
||||
message ListTopicsResponse {
|
||||
repeated Topic topics = 1;
|
||||
}
|
||||
message LookupTopicBrokersRequest {
|
||||
Topic topic = 1;
|
||||
bool is_for_publish = 2;
|
||||
}
|
||||
message FindTopicBrokersResponse {
|
||||
message LookupTopicBrokersResponse {
|
||||
Topic topic = 1;
|
||||
TopicPartitionsAssignment topic_partitions_assignment = 2;
|
||||
repeated BrokerPartitionAssignment broker_partition_assignments = 2;
|
||||
}
|
||||
message BrokerPartitionsAssignment {
|
||||
int32 partition_start = 1;
|
||||
int32 partition_stop = 2;
|
||||
string leader_broker = 3;
|
||||
repeated string follower_brokers = 4;
|
||||
}
|
||||
message TopicPartitionsAssignment {
|
||||
int32 partition_count = 1; // over-sharded partitions, usually 1024
|
||||
repeated BrokerPartitionsAssignment broker_partitions = 2;
|
||||
message BrokerPartitionAssignment {
|
||||
Partition partition = 1;
|
||||
string leader_broker = 2;
|
||||
repeated string follower_brokers = 3;
|
||||
}
|
||||
|
||||
message RequestTopicPartitionsRequest {
|
||||
@@ -122,12 +171,12 @@ message RequestTopicPartitionsRequest {
|
||||
int32 partition_count = 2;
|
||||
}
|
||||
message RequestTopicPartitionsResponse {
|
||||
TopicPartitionsAssignment topic_partitions_assignment = 1;
|
||||
repeated BrokerPartitionAssignment broker_partition_assignments = 1;
|
||||
}
|
||||
|
||||
message AssignTopicPartitionsRequest {
|
||||
Topic topic = 1;
|
||||
TopicPartitionsAssignment topic_partitions_assignment = 2;
|
||||
repeated BrokerPartitionAssignment broker_partition_assignments = 2;
|
||||
bool is_leader = 3;
|
||||
}
|
||||
message AssignTopicPartitionsResponse {
|
||||
@@ -136,21 +185,23 @@ message AssignTopicPartitionsResponse {
|
||||
message CheckTopicPartitionsStatusRequest {
|
||||
string namespace = 1;
|
||||
string topic = 2;
|
||||
BrokerPartitionsAssignment broker_partitions_assignment = 3;
|
||||
BrokerPartitionAssignment broker_partition_assignment = 3;
|
||||
bool should_cancel_if_not_match = 4;
|
||||
}
|
||||
message CheckTopicPartitionsStatusResponse {
|
||||
TopicPartitionsAssignment topic_partitions_assignment = 1;
|
||||
repeated BrokerPartitionAssignment broker_partition_assignments = 1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
message DataMessage {
|
||||
bytes key = 1;
|
||||
bytes value = 2;
|
||||
}
|
||||
message PublishRequest {
|
||||
message InitMessage {
|
||||
Segment segment = 1;
|
||||
}
|
||||
message DataMessage {
|
||||
bytes key = 1;
|
||||
bytes value = 2;
|
||||
Topic topic = 1;
|
||||
Partition partition = 2;
|
||||
int32 ack_interval = 3;
|
||||
}
|
||||
oneof message {
|
||||
InitMessage init = 1;
|
||||
@@ -161,5 +212,33 @@ message PublishRequest {
|
||||
message PublishResponse {
|
||||
int64 ack_sequence = 1;
|
||||
string error = 2;
|
||||
bool is_closed = 3;
|
||||
string redirect_to_broker = 3;
|
||||
}
|
||||
message SubscribeRequest {
|
||||
message Consumer {
|
||||
string consumer_group = 1;
|
||||
string consumer_id = 2;
|
||||
string client_id = 3;
|
||||
}
|
||||
message Cursor {
|
||||
Topic topic = 1;
|
||||
Partition partition = 2;
|
||||
oneof offset {
|
||||
int64 start_offset = 3;
|
||||
int64 start_timestamp_ns = 4;
|
||||
}
|
||||
string filter = 5;
|
||||
}
|
||||
Consumer consumer = 1;
|
||||
Cursor cursor = 2;
|
||||
}
|
||||
message SubscribeResponse {
|
||||
message CtrlMessage {
|
||||
string error = 1;
|
||||
string redirect_to_broker = 2;
|
||||
}
|
||||
oneof message {
|
||||
CtrlMessage ctrl = 1;
|
||||
DataMessage data = 2;
|
||||
}
|
||||
}
|
||||
|
||||
+1679
-419
File diff suppressed because it is too large
Load Diff
+256
-15
@@ -27,14 +27,20 @@ type SeaweedMessagingClient interface {
|
||||
AssignSegmentBrokers(ctx context.Context, in *AssignSegmentBrokersRequest, opts ...grpc.CallOption) (*AssignSegmentBrokersResponse, error)
|
||||
CheckSegmentStatus(ctx context.Context, in *CheckSegmentStatusRequest, opts ...grpc.CallOption) (*CheckSegmentStatusResponse, error)
|
||||
CheckBrokerLoad(ctx context.Context, in *CheckBrokerLoadRequest, opts ...grpc.CallOption) (*CheckBrokerLoadResponse, error)
|
||||
// control plane for balancer
|
||||
ConnectToBalancer(ctx context.Context, opts ...grpc.CallOption) (SeaweedMessaging_ConnectToBalancerClient, error)
|
||||
// control plane for topic partitions
|
||||
FindTopicBrokers(ctx context.Context, in *FindTopicBrokersRequest, opts ...grpc.CallOption) (*FindTopicBrokersResponse, error)
|
||||
LookupTopicBrokers(ctx context.Context, in *LookupTopicBrokersRequest, opts ...grpc.CallOption) (*LookupTopicBrokersResponse, error)
|
||||
CreateTopic(ctx context.Context, in *CreateTopicRequest, opts ...grpc.CallOption) (*CreateTopicResponse, error)
|
||||
DoCreateTopic(ctx context.Context, in *DoCreateTopicRequest, opts ...grpc.CallOption) (*DoCreateTopicResponse, error)
|
||||
ListTopics(ctx context.Context, in *ListTopicsRequest, opts ...grpc.CallOption) (*ListTopicsResponse, error)
|
||||
// a pub client will call this to get the topic partitions assignment
|
||||
RequestTopicPartitions(ctx context.Context, in *RequestTopicPartitionsRequest, opts ...grpc.CallOption) (*RequestTopicPartitionsResponse, error)
|
||||
AssignTopicPartitions(ctx context.Context, in *AssignTopicPartitionsRequest, opts ...grpc.CallOption) (*AssignTopicPartitionsResponse, error)
|
||||
CheckTopicPartitionsStatus(ctx context.Context, in *CheckTopicPartitionsStatusRequest, opts ...grpc.CallOption) (*CheckTopicPartitionsStatusResponse, error)
|
||||
// data plane
|
||||
Publish(ctx context.Context, opts ...grpc.CallOption) (SeaweedMessaging_PublishClient, error)
|
||||
Subscribe(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (SeaweedMessaging_SubscribeClient, error)
|
||||
}
|
||||
|
||||
type seaweedMessagingClient struct {
|
||||
@@ -81,9 +87,67 @@ func (c *seaweedMessagingClient) CheckBrokerLoad(ctx context.Context, in *CheckB
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedMessagingClient) FindTopicBrokers(ctx context.Context, in *FindTopicBrokersRequest, opts ...grpc.CallOption) (*FindTopicBrokersResponse, error) {
|
||||
out := new(FindTopicBrokersResponse)
|
||||
err := c.cc.Invoke(ctx, "/messaging_pb.SeaweedMessaging/FindTopicBrokers", in, out, opts...)
|
||||
func (c *seaweedMessagingClient) ConnectToBalancer(ctx context.Context, opts ...grpc.CallOption) (SeaweedMessaging_ConnectToBalancerClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &SeaweedMessaging_ServiceDesc.Streams[0], "/messaging_pb.SeaweedMessaging/ConnectToBalancer", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &seaweedMessagingConnectToBalancerClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type SeaweedMessaging_ConnectToBalancerClient interface {
|
||||
Send(*ConnectToBalancerRequest) error
|
||||
Recv() (*ConnectToBalancerResponse, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type seaweedMessagingConnectToBalancerClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *seaweedMessagingConnectToBalancerClient) Send(m *ConnectToBalancerRequest) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *seaweedMessagingConnectToBalancerClient) Recv() (*ConnectToBalancerResponse, error) {
|
||||
m := new(ConnectToBalancerResponse)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *seaweedMessagingClient) LookupTopicBrokers(ctx context.Context, in *LookupTopicBrokersRequest, opts ...grpc.CallOption) (*LookupTopicBrokersResponse, error) {
|
||||
out := new(LookupTopicBrokersResponse)
|
||||
err := c.cc.Invoke(ctx, "/messaging_pb.SeaweedMessaging/LookupTopicBrokers", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedMessagingClient) CreateTopic(ctx context.Context, in *CreateTopicRequest, opts ...grpc.CallOption) (*CreateTopicResponse, error) {
|
||||
out := new(CreateTopicResponse)
|
||||
err := c.cc.Invoke(ctx, "/messaging_pb.SeaweedMessaging/CreateTopic", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedMessagingClient) DoCreateTopic(ctx context.Context, in *DoCreateTopicRequest, opts ...grpc.CallOption) (*DoCreateTopicResponse, error) {
|
||||
out := new(DoCreateTopicResponse)
|
||||
err := c.cc.Invoke(ctx, "/messaging_pb.SeaweedMessaging/DoCreateTopic", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedMessagingClient) ListTopics(ctx context.Context, in *ListTopicsRequest, opts ...grpc.CallOption) (*ListTopicsResponse, error) {
|
||||
out := new(ListTopicsResponse)
|
||||
err := c.cc.Invoke(ctx, "/messaging_pb.SeaweedMessaging/ListTopics", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -118,7 +182,7 @@ func (c *seaweedMessagingClient) CheckTopicPartitionsStatus(ctx context.Context,
|
||||
}
|
||||
|
||||
func (c *seaweedMessagingClient) Publish(ctx context.Context, opts ...grpc.CallOption) (SeaweedMessaging_PublishClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &SeaweedMessaging_ServiceDesc.Streams[0], "/messaging_pb.SeaweedMessaging/Publish", opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &SeaweedMessaging_ServiceDesc.Streams[1], "/messaging_pb.SeaweedMessaging/Publish", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -148,6 +212,38 @@ func (x *seaweedMessagingPublishClient) Recv() (*PublishResponse, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *seaweedMessagingClient) Subscribe(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (SeaweedMessaging_SubscribeClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &SeaweedMessaging_ServiceDesc.Streams[2], "/messaging_pb.SeaweedMessaging/Subscribe", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &seaweedMessagingSubscribeClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type SeaweedMessaging_SubscribeClient interface {
|
||||
Recv() (*SubscribeResponse, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type seaweedMessagingSubscribeClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *seaweedMessagingSubscribeClient) Recv() (*SubscribeResponse, error) {
|
||||
m := new(SubscribeResponse)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// SeaweedMessagingServer is the server API for SeaweedMessaging service.
|
||||
// All implementations must embed UnimplementedSeaweedMessagingServer
|
||||
// for forward compatibility
|
||||
@@ -157,14 +253,20 @@ type SeaweedMessagingServer interface {
|
||||
AssignSegmentBrokers(context.Context, *AssignSegmentBrokersRequest) (*AssignSegmentBrokersResponse, error)
|
||||
CheckSegmentStatus(context.Context, *CheckSegmentStatusRequest) (*CheckSegmentStatusResponse, error)
|
||||
CheckBrokerLoad(context.Context, *CheckBrokerLoadRequest) (*CheckBrokerLoadResponse, error)
|
||||
// control plane for balancer
|
||||
ConnectToBalancer(SeaweedMessaging_ConnectToBalancerServer) error
|
||||
// control plane for topic partitions
|
||||
FindTopicBrokers(context.Context, *FindTopicBrokersRequest) (*FindTopicBrokersResponse, error)
|
||||
LookupTopicBrokers(context.Context, *LookupTopicBrokersRequest) (*LookupTopicBrokersResponse, error)
|
||||
CreateTopic(context.Context, *CreateTopicRequest) (*CreateTopicResponse, error)
|
||||
DoCreateTopic(context.Context, *DoCreateTopicRequest) (*DoCreateTopicResponse, error)
|
||||
ListTopics(context.Context, *ListTopicsRequest) (*ListTopicsResponse, error)
|
||||
// a pub client will call this to get the topic partitions assignment
|
||||
RequestTopicPartitions(context.Context, *RequestTopicPartitionsRequest) (*RequestTopicPartitionsResponse, error)
|
||||
AssignTopicPartitions(context.Context, *AssignTopicPartitionsRequest) (*AssignTopicPartitionsResponse, error)
|
||||
CheckTopicPartitionsStatus(context.Context, *CheckTopicPartitionsStatusRequest) (*CheckTopicPartitionsStatusResponse, error)
|
||||
// data plane
|
||||
Publish(SeaweedMessaging_PublishServer) error
|
||||
Subscribe(*SubscribeRequest, SeaweedMessaging_SubscribeServer) error
|
||||
mustEmbedUnimplementedSeaweedMessagingServer()
|
||||
}
|
||||
|
||||
@@ -184,8 +286,20 @@ func (UnimplementedSeaweedMessagingServer) CheckSegmentStatus(context.Context, *
|
||||
func (UnimplementedSeaweedMessagingServer) CheckBrokerLoad(context.Context, *CheckBrokerLoadRequest) (*CheckBrokerLoadResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CheckBrokerLoad not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedMessagingServer) FindTopicBrokers(context.Context, *FindTopicBrokersRequest) (*FindTopicBrokersResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method FindTopicBrokers not implemented")
|
||||
func (UnimplementedSeaweedMessagingServer) ConnectToBalancer(SeaweedMessaging_ConnectToBalancerServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method ConnectToBalancer not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedMessagingServer) LookupTopicBrokers(context.Context, *LookupTopicBrokersRequest) (*LookupTopicBrokersResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method LookupTopicBrokers not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedMessagingServer) CreateTopic(context.Context, *CreateTopicRequest) (*CreateTopicResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateTopic not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedMessagingServer) DoCreateTopic(context.Context, *DoCreateTopicRequest) (*DoCreateTopicResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DoCreateTopic not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedMessagingServer) ListTopics(context.Context, *ListTopicsRequest) (*ListTopicsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListTopics not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedMessagingServer) RequestTopicPartitions(context.Context, *RequestTopicPartitionsRequest) (*RequestTopicPartitionsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RequestTopicPartitions not implemented")
|
||||
@@ -199,6 +313,9 @@ func (UnimplementedSeaweedMessagingServer) CheckTopicPartitionsStatus(context.Co
|
||||
func (UnimplementedSeaweedMessagingServer) Publish(SeaweedMessaging_PublishServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method Publish not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedMessagingServer) Subscribe(*SubscribeRequest, SeaweedMessaging_SubscribeServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method Subscribe not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedMessagingServer) mustEmbedUnimplementedSeaweedMessagingServer() {}
|
||||
|
||||
// UnsafeSeaweedMessagingServer may be embedded to opt out of forward compatibility for this service.
|
||||
@@ -284,20 +401,100 @@ func _SeaweedMessaging_CheckBrokerLoad_Handler(srv interface{}, ctx context.Cont
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SeaweedMessaging_FindTopicBrokers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(FindTopicBrokersRequest)
|
||||
func _SeaweedMessaging_ConnectToBalancer_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(SeaweedMessagingServer).ConnectToBalancer(&seaweedMessagingConnectToBalancerServer{stream})
|
||||
}
|
||||
|
||||
type SeaweedMessaging_ConnectToBalancerServer interface {
|
||||
Send(*ConnectToBalancerResponse) error
|
||||
Recv() (*ConnectToBalancerRequest, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type seaweedMessagingConnectToBalancerServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *seaweedMessagingConnectToBalancerServer) Send(m *ConnectToBalancerResponse) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *seaweedMessagingConnectToBalancerServer) Recv() (*ConnectToBalancerRequest, error) {
|
||||
m := new(ConnectToBalancerRequest)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func _SeaweedMessaging_LookupTopicBrokers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(LookupTopicBrokersRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedMessagingServer).FindTopicBrokers(ctx, in)
|
||||
return srv.(SeaweedMessagingServer).LookupTopicBrokers(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/messaging_pb.SeaweedMessaging/FindTopicBrokers",
|
||||
FullMethod: "/messaging_pb.SeaweedMessaging/LookupTopicBrokers",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedMessagingServer).FindTopicBrokers(ctx, req.(*FindTopicBrokersRequest))
|
||||
return srv.(SeaweedMessagingServer).LookupTopicBrokers(ctx, req.(*LookupTopicBrokersRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SeaweedMessaging_CreateTopic_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateTopicRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedMessagingServer).CreateTopic(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/messaging_pb.SeaweedMessaging/CreateTopic",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedMessagingServer).CreateTopic(ctx, req.(*CreateTopicRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SeaweedMessaging_DoCreateTopic_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DoCreateTopicRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedMessagingServer).DoCreateTopic(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/messaging_pb.SeaweedMessaging/DoCreateTopic",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedMessagingServer).DoCreateTopic(ctx, req.(*DoCreateTopicRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SeaweedMessaging_ListTopics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListTopicsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedMessagingServer).ListTopics(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/messaging_pb.SeaweedMessaging/ListTopics",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedMessagingServer).ListTopics(ctx, req.(*ListTopicsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -382,6 +579,27 @@ func (x *seaweedMessagingPublishServer) Recv() (*PublishRequest, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func _SeaweedMessaging_Subscribe_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(SubscribeRequest)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(SeaweedMessagingServer).Subscribe(m, &seaweedMessagingSubscribeServer{stream})
|
||||
}
|
||||
|
||||
type SeaweedMessaging_SubscribeServer interface {
|
||||
Send(*SubscribeResponse) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type seaweedMessagingSubscribeServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *seaweedMessagingSubscribeServer) Send(m *SubscribeResponse) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
// SeaweedMessaging_ServiceDesc is the grpc.ServiceDesc for SeaweedMessaging service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -406,8 +624,20 @@ var SeaweedMessaging_ServiceDesc = grpc.ServiceDesc{
|
||||
Handler: _SeaweedMessaging_CheckBrokerLoad_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "FindTopicBrokers",
|
||||
Handler: _SeaweedMessaging_FindTopicBrokers_Handler,
|
||||
MethodName: "LookupTopicBrokers",
|
||||
Handler: _SeaweedMessaging_LookupTopicBrokers_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreateTopic",
|
||||
Handler: _SeaweedMessaging_CreateTopic_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DoCreateTopic",
|
||||
Handler: _SeaweedMessaging_DoCreateTopic_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListTopics",
|
||||
Handler: _SeaweedMessaging_ListTopics_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RequestTopicPartitions",
|
||||
@@ -423,12 +653,23 @@ var SeaweedMessaging_ServiceDesc = grpc.ServiceDesc{
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "ConnectToBalancer",
|
||||
Handler: _SeaweedMessaging_ConnectToBalancer_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "Publish",
|
||||
Handler: _SeaweedMessaging_Publish_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "Subscribe",
|
||||
Handler: _SeaweedMessaging_Subscribe_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "mq.proto",
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@ import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
|
||||
)
|
||||
|
||||
var IdentityAnonymous *Identity
|
||||
|
||||
type Action string
|
||||
|
||||
type Iam interface {
|
||||
@@ -29,12 +27,14 @@ type Iam interface {
|
||||
type IdentityAccessManagement struct {
|
||||
m sync.RWMutex
|
||||
|
||||
identities []*Identity
|
||||
isAuthEnabled bool
|
||||
domain string
|
||||
hashes map[string]*sync.Pool
|
||||
hashCounters map[string]*int32
|
||||
hashMu sync.RWMutex
|
||||
identities []*Identity
|
||||
accessKeyIdent map[string]*Identity
|
||||
hashes map[string]*sync.Pool
|
||||
hashCounters map[string]*int32
|
||||
identityAnonymous *Identity
|
||||
hashMu sync.RWMutex
|
||||
domain string
|
||||
isAuthEnabled bool
|
||||
}
|
||||
|
||||
type Identity struct {
|
||||
@@ -136,6 +136,8 @@ func (iam *IdentityAccessManagement) LoadS3ApiConfigurationFromBytes(content []b
|
||||
|
||||
func (iam *IdentityAccessManagement) loadS3ApiConfiguration(config *iam_pb.S3ApiConfiguration) error {
|
||||
var identities []*Identity
|
||||
var identityAnonymous *Identity
|
||||
accessKeyIdent := make(map[string]*Identity)
|
||||
for _, ident := range config.Identities {
|
||||
t := &Identity{
|
||||
Name: ident.Name,
|
||||
@@ -149,7 +151,7 @@ func (iam *IdentityAccessManagement) loadS3ApiConfiguration(config *iam_pb.S3Api
|
||||
glog.Warningf("anonymous identity is associated with a non-anonymous account ID, the association is invalid")
|
||||
}
|
||||
t.AccountId = s3account.AccountAnonymous.Id
|
||||
IdentityAnonymous = t
|
||||
identityAnonymous = t
|
||||
} else {
|
||||
if len(ident.AccountId) > 0 {
|
||||
t.AccountId = ident.AccountId
|
||||
@@ -164,19 +166,15 @@ func (iam *IdentityAccessManagement) loadS3ApiConfiguration(config *iam_pb.S3Api
|
||||
AccessKey: cred.AccessKey,
|
||||
SecretKey: cred.SecretKey,
|
||||
})
|
||||
accessKeyIdent[cred.AccessKey] = t
|
||||
}
|
||||
identities = append(identities, t)
|
||||
}
|
||||
|
||||
if IdentityAnonymous == nil {
|
||||
IdentityAnonymous = &Identity{
|
||||
Name: s3account.AccountAnonymous.Name,
|
||||
AccountId: s3account.AccountAnonymous.Id,
|
||||
}
|
||||
}
|
||||
iam.m.Lock()
|
||||
// atomically switch
|
||||
iam.identities = identities
|
||||
iam.identityAnonymous = identityAnonymous
|
||||
iam.accessKeyIdent = accessKeyIdent
|
||||
if !iam.isAuthEnabled { // one-directional, no toggling
|
||||
iam.isAuthEnabled = len(identities) > 0
|
||||
}
|
||||
@@ -189,14 +187,12 @@ func (iam *IdentityAccessManagement) isEnabled() bool {
|
||||
}
|
||||
|
||||
func (iam *IdentityAccessManagement) lookupByAccessKey(accessKey string) (identity *Identity, cred *Credential, found bool) {
|
||||
|
||||
iam.m.RLock()
|
||||
defer iam.m.RUnlock()
|
||||
for _, ident := range iam.identities {
|
||||
for _, cred := range ident.Credentials {
|
||||
// println("checking", ident.Name, cred.AccessKey)
|
||||
if cred.AccessKey == accessKey {
|
||||
return ident, cred, true
|
||||
if ident, ok := iam.accessKeyIdent[accessKey]; ok {
|
||||
for _, credential := range ident.Credentials {
|
||||
if credential.AccessKey == accessKey {
|
||||
return ident, credential, true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,10 +203,8 @@ func (iam *IdentityAccessManagement) lookupByAccessKey(accessKey string) (identi
|
||||
func (iam *IdentityAccessManagement) lookupAnonymous() (identity *Identity, found bool) {
|
||||
iam.m.RLock()
|
||||
defer iam.m.RUnlock()
|
||||
for _, ident := range iam.identities {
|
||||
if ident.isAnonymous() {
|
||||
return ident, true
|
||||
}
|
||||
if iam.identityAnonymous != nil {
|
||||
return iam.identityAnonymous, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
@@ -270,8 +264,7 @@ func (iam *IdentityAccessManagement) authRequest(r *http.Request, action Action)
|
||||
return identity, s3err.ErrNotImplemented
|
||||
case authTypeAnonymous:
|
||||
authType = "Anonymous"
|
||||
identity, found = iam.lookupAnonymous()
|
||||
if !found {
|
||||
if identity, found = iam.lookupAnonymous(); !found {
|
||||
r.Header.Set(s3_constants.AmzAuthType, authType)
|
||||
return identity, s3err.ErrAccessDenied
|
||||
}
|
||||
|
||||
@@ -89,10 +89,13 @@ func TestCanDo(t *testing.T) {
|
||||
Actions: []Action{
|
||||
"Read:bucket1",
|
||||
"Write:bucket1/*",
|
||||
"WriteAcp:bucket1",
|
||||
},
|
||||
}
|
||||
assert.Equal(t, true, ident2.canDo(ACTION_READ, "bucket1", "/a/b/c/d.txt"))
|
||||
assert.Equal(t, true, ident2.canDo(ACTION_WRITE, "bucket1", "/a/b/c/d.txt"))
|
||||
assert.Equal(t, true, ident2.canDo(ACTION_WRITE_ACP, "bucket1", ""))
|
||||
assert.Equal(t, false, ident2.canDo(ACTION_READ_ACP, "bucket1", ""))
|
||||
assert.Equal(t, false, ident2.canDo(ACTION_LIST, "bucket1", "/a/b/c/d.txt"))
|
||||
|
||||
// across buckets
|
||||
@@ -106,15 +109,18 @@ func TestCanDo(t *testing.T) {
|
||||
assert.Equal(t, true, ident3.canDo(ACTION_READ, "bucket1", "/a/b/c/d.txt"))
|
||||
assert.Equal(t, true, ident3.canDo(ACTION_WRITE, "bucket1", "/a/b/c/d.txt"))
|
||||
assert.Equal(t, false, ident3.canDo(ACTION_LIST, "bucket1", "/a/b/other/some"))
|
||||
assert.Equal(t, false, ident3.canDo(ACTION_WRITE_ACP, "bucket1", ""))
|
||||
|
||||
// partial buckets
|
||||
ident4 := &Identity{
|
||||
Name: "anything",
|
||||
Actions: []Action{
|
||||
"Read:special_*",
|
||||
"ReadAcp:special_*",
|
||||
},
|
||||
}
|
||||
assert.Equal(t, true, ident4.canDo(ACTION_READ, "special_bucket", "/a/b/c/d.txt"))
|
||||
assert.Equal(t, true, ident4.canDo(ACTION_READ_ACP, "special_bucket", ""))
|
||||
assert.Equal(t, false, ident4.canDo(ACTION_READ, "bucket1", "/a/b/c/d.txt"))
|
||||
|
||||
// admin buckets
|
||||
@@ -125,7 +131,18 @@ func TestCanDo(t *testing.T) {
|
||||
},
|
||||
}
|
||||
assert.Equal(t, true, ident5.canDo(ACTION_READ, "special_bucket", "/a/b/c/d.txt"))
|
||||
assert.Equal(t, true, ident5.canDo(ACTION_READ_ACP, "special_bucket", ""))
|
||||
assert.Equal(t, true, ident5.canDo(ACTION_WRITE, "special_bucket", "/a/b/c/d.txt"))
|
||||
assert.Equal(t, true, ident5.canDo(ACTION_WRITE_ACP, "special_bucket", ""))
|
||||
|
||||
// anonymous buckets
|
||||
ident6 := &Identity{
|
||||
Name: "anonymous",
|
||||
Actions: []Action{
|
||||
"Read",
|
||||
},
|
||||
}
|
||||
assert.Equal(t, true, ident6.canDo(ACTION_READ, "anything_bucket", "/a/b/c/d.txt"))
|
||||
}
|
||||
|
||||
type LoadS3ApiConfigurationTestCase struct {
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -58,20 +60,24 @@ func TestIsRequestPresignedSignatureV4(t *testing.T) {
|
||||
|
||||
// Tests is requested authenticated function, tests replies for s3 errors.
|
||||
func TestIsReqAuthenticated(t *testing.T) {
|
||||
option := S3ApiServerOption{}
|
||||
iam := NewIdentityAccessManagement(&option)
|
||||
iam.identities = []*Identity{
|
||||
{
|
||||
Name: "someone",
|
||||
Credentials: []*Credential{
|
||||
{
|
||||
AccessKey: "access_key_1",
|
||||
SecretKey: "secret_key_1",
|
||||
},
|
||||
},
|
||||
Actions: nil,
|
||||
},
|
||||
iam := &IdentityAccessManagement{
|
||||
hashes: make(map[string]*sync.Pool),
|
||||
hashCounters: make(map[string]*int32),
|
||||
}
|
||||
_ = iam.loadS3ApiConfiguration(&iam_pb.S3ApiConfiguration{
|
||||
Identities: []*iam_pb.Identity{
|
||||
{
|
||||
Name: "someone",
|
||||
Credentials: []*iam_pb.Credential{
|
||||
{
|
||||
AccessKey: "access_key_1",
|
||||
SecretKey: "secret_key_1",
|
||||
},
|
||||
},
|
||||
Actions: []string{},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// List of test cases for validating http request authentication.
|
||||
testCases := []struct {
|
||||
@@ -93,22 +99,58 @@ func TestIsReqAuthenticated(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckAdminRequestAuthType(t *testing.T) {
|
||||
option := S3ApiServerOption{}
|
||||
iam := NewIdentityAccessManagement(&option)
|
||||
iam.identities = []*Identity{
|
||||
{
|
||||
Name: "someone",
|
||||
Credentials: []*Credential{
|
||||
{
|
||||
AccessKey: "access_key_1",
|
||||
SecretKey: "secret_key_1",
|
||||
},
|
||||
func TestCheckaAnonymousRequestAuthType(t *testing.T) {
|
||||
iam := &IdentityAccessManagement{
|
||||
hashes: make(map[string]*sync.Pool),
|
||||
hashCounters: make(map[string]*int32),
|
||||
}
|
||||
_ = iam.loadS3ApiConfiguration(&iam_pb.S3ApiConfiguration{
|
||||
Identities: []*iam_pb.Identity{
|
||||
{
|
||||
Name: "anonymous",
|
||||
Actions: []string{s3_constants.ACTION_READ},
|
||||
},
|
||||
Actions: nil,
|
||||
},
|
||||
})
|
||||
testCases := []struct {
|
||||
Request *http.Request
|
||||
ErrCode s3err.ErrorCode
|
||||
Action Action
|
||||
}{
|
||||
{Request: mustNewRequest("GET", "http://127.0.0.1:9000/bucket", 0, nil, t), ErrCode: s3err.ErrNone, Action: s3_constants.ACTION_READ},
|
||||
{Request: mustNewRequest("PUT", "http://127.0.0.1:9000/bucket", 0, nil, t), ErrCode: s3err.ErrAccessDenied, Action: s3_constants.ACTION_WRITE},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
_, s3Error := iam.authRequest(testCase.Request, testCase.Action)
|
||||
if s3Error != testCase.ErrCode {
|
||||
t.Errorf("Test %d: Unexpected s3error returned wanted %d, got %d", i, testCase.ErrCode, s3Error)
|
||||
}
|
||||
if testCase.Request.Header.Get(s3_constants.AmzAuthType) != "Anonymous" {
|
||||
t.Errorf("Test %d: Unexpected AuthType returned wanted %s, got %s", i, "Anonymous", testCase.Request.Header.Get(s3_constants.AmzAuthType))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCheckAdminRequestAuthType(t *testing.T) {
|
||||
iam := &IdentityAccessManagement{
|
||||
hashes: make(map[string]*sync.Pool),
|
||||
hashCounters: make(map[string]*int32),
|
||||
}
|
||||
_ = iam.loadS3ApiConfiguration(&iam_pb.S3ApiConfiguration{
|
||||
Identities: []*iam_pb.Identity{
|
||||
{
|
||||
Name: "someone",
|
||||
Credentials: []*iam_pb.Credential{
|
||||
{
|
||||
AccessKey: "access_key_1",
|
||||
SecretKey: "secret_key_1",
|
||||
},
|
||||
},
|
||||
Actions: []string{},
|
||||
},
|
||||
},
|
||||
})
|
||||
testCases := []struct {
|
||||
Request *http.Request
|
||||
ErrCode s3err.ErrorCode
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package s3_constants
|
||||
|
||||
const (
|
||||
ACTION_READ = "Read"
|
||||
ACTION_WRITE = "Write"
|
||||
ACTION_ADMIN = "Admin"
|
||||
ACTION_TAGGING = "Tagging"
|
||||
ACTION_LIST = "List"
|
||||
ACTION_READ = "Read"
|
||||
ACTION_READ_ACP = "ReadAcp"
|
||||
ACTION_WRITE = "Write"
|
||||
ACTION_WRITE_ACP = "WriteAcp"
|
||||
ACTION_ADMIN = "Admin"
|
||||
ACTION_TAGGING = "Tagging"
|
||||
ACTION_LIST = "List"
|
||||
|
||||
SeaweedStorageDestinationHeader = "x-seaweedfs-destination"
|
||||
MultipartUploadsFolder = ".uploads"
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
var (
|
||||
CircuitBreakerConfigDir = "/etc/s3"
|
||||
CircuitBreakerConfigFile = "circuit_breaker.json"
|
||||
AllowedActions = []string{ACTION_READ, ACTION_WRITE, ACTION_LIST, ACTION_TAGGING, ACTION_ADMIN}
|
||||
AllowedActions = []string{ACTION_READ, ACTION_READ_ACP, ACTION_WRITE, ACTION_WRITE_ACP, ACTION_LIST, ACTION_TAGGING, ACTION_ADMIN}
|
||||
LimitTypeCount = "Count"
|
||||
LimitTypeBytes = "MB"
|
||||
Separator = ":"
|
||||
|
||||
@@ -259,34 +259,56 @@ func (s3a *S3ApiServer) GetBucketAclHandler(w http.ResponseWriter, r *http.Reque
|
||||
return
|
||||
}
|
||||
|
||||
response := AccessControlPolicy{}
|
||||
for _, ident := range s3a.iam.identities {
|
||||
if len(ident.Credentials) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, action := range ident.Actions {
|
||||
if !action.overBucket(bucket) || action.getPermission() == "" {
|
||||
continue
|
||||
}
|
||||
id := ident.Credentials[0].AccessKey
|
||||
if response.Owner.DisplayName == "" && action.isOwner(bucket) && len(ident.Credentials) > 0 {
|
||||
response.Owner.DisplayName = ident.Name
|
||||
response.Owner.ID = id
|
||||
}
|
||||
response.AccessControlList.Grant = append(response.AccessControlList.Grant, Grant{
|
||||
Grantee: Grantee{
|
||||
ID: id,
|
||||
DisplayName: ident.Name,
|
||||
Type: "CanonicalUser",
|
||||
XMLXSI: "CanonicalUser",
|
||||
XMLNS: "http://www.w3.org/2001/XMLSchema-instance"},
|
||||
Permission: action.getPermission(),
|
||||
})
|
||||
}
|
||||
identityId := r.Header.Get(s3_constants.AmzIdentityId)
|
||||
response := AccessControlPolicy{
|
||||
Owner: CanonicalUser{
|
||||
ID: identityId,
|
||||
DisplayName: identityId,
|
||||
},
|
||||
}
|
||||
response.AccessControlList.Grant = append(response.AccessControlList.Grant, Grant{
|
||||
Grantee: Grantee{
|
||||
ID: identityId,
|
||||
DisplayName: identityId,
|
||||
Type: "CanonicalUser",
|
||||
XMLXSI: "CanonicalUser",
|
||||
XMLNS: "http://www.w3.org/2001/XMLSchema-instance"},
|
||||
Permission: s3.PermissionFullControl,
|
||||
})
|
||||
writeSuccessResponseXML(w, r, response)
|
||||
}
|
||||
|
||||
// PutBucketAclHandler Put bucket ACL only responds success if the ACL is private.
|
||||
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html //
|
||||
func (s3a *S3ApiServer) PutBucketAclHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// collect parameters
|
||||
bucket, _ := s3_constants.GetBucketAndObject(r)
|
||||
glog.V(3).Infof("PutBucketAclHandler %s", bucket)
|
||||
|
||||
if err := s3a.checkBucket(r, bucket); err != s3err.ErrNone {
|
||||
s3err.WriteErrorResponse(w, r, err)
|
||||
return
|
||||
}
|
||||
cannedAcl := r.Header.Get(s3_constants.AmzCannedAcl)
|
||||
switch {
|
||||
case cannedAcl == "":
|
||||
acl := &s3.AccessControlPolicy{}
|
||||
if err := xmlDecoder(r.Body, acl, r.ContentLength); err != nil {
|
||||
glog.Errorf("PutBucketAclHandler: %s", err)
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest)
|
||||
return
|
||||
}
|
||||
if len(acl.Grants) == 1 && acl.Grants[0].Permission != nil && *acl.Grants[0].Permission == s3_constants.PermissionFullControl {
|
||||
writeSuccessResponseEmpty(w, r)
|
||||
return
|
||||
}
|
||||
case cannedAcl == s3_constants.CannedAclPrivate:
|
||||
writeSuccessResponseEmpty(w, r)
|
||||
return
|
||||
}
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented)
|
||||
}
|
||||
|
||||
// GetBucketLifecycleConfigurationHandler Get Bucket Lifecycle configuration
|
||||
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html
|
||||
func (s3a *S3ApiServer) GetBucketLifecycleConfigurationHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -41,9 +41,3 @@ func (s3a *S3ApiServer) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Re
|
||||
func (s3a *S3ApiServer) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
s3err.WriteErrorResponse(w, r, http.StatusNoContent)
|
||||
}
|
||||
|
||||
// PutBucketAclHandler Put bucket ACL
|
||||
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html
|
||||
func (s3a *S3ApiServer) PutBucketAclHandler(w http.ResponseWriter, r *http.Request) {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented)
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ func (s3a *S3ApiServer) registerRouter(router *mux.Router) {
|
||||
bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.DeleteObjectTaggingHandler, ACTION_TAGGING)), "DELETE")).Queries("tagging", "")
|
||||
|
||||
// PutObjectACL
|
||||
bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutObjectAclHandler, ACTION_WRITE)), "PUT")).Queries("acl", "")
|
||||
bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutObjectAclHandler, ACTION_WRITE_ACP)), "PUT")).Queries("acl", "")
|
||||
// PutObjectRetention
|
||||
bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutObjectRetentionHandler, ACTION_WRITE)), "PUT")).Queries("retention", "")
|
||||
// PutObjectLegalHold
|
||||
@@ -156,7 +156,7 @@ func (s3a *S3ApiServer) registerRouter(router *mux.Router) {
|
||||
bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutObjectLockConfigurationHandler, ACTION_WRITE)), "PUT")).Queries("object-lock", "")
|
||||
|
||||
// GetObjectACL
|
||||
bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetObjectAclHandler, ACTION_READ)), "GET")).Queries("acl", "")
|
||||
bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetObjectAclHandler, ACTION_READ_ACP)), "GET")).Queries("acl", "")
|
||||
|
||||
// objects with query
|
||||
|
||||
@@ -183,9 +183,9 @@ func (s3a *S3ApiServer) registerRouter(router *mux.Router) {
|
||||
bucket.Methods("POST").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.DeleteMultipleObjectsHandler, ACTION_WRITE)), "DELETE")).Queries("delete", "")
|
||||
|
||||
// GetBucketACL
|
||||
bucket.Methods("GET").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetBucketAclHandler, ACTION_READ)), "GET")).Queries("acl", "")
|
||||
bucket.Methods("GET").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetBucketAclHandler, ACTION_READ_ACP)), "GET")).Queries("acl", "")
|
||||
// PutBucketACL
|
||||
bucket.Methods("PUT").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutBucketAclHandler, ACTION_WRITE)), "PUT")).Queries("acl", "")
|
||||
bucket.Methods("PUT").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutBucketAclHandler, ACTION_WRITE_ACP)), "PUT")).Queries("acl", "")
|
||||
|
||||
// GetBucketPolicy
|
||||
bucket.Methods("GET").HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetBucketPolicyHandler, ACTION_READ)), "GET")).Queries("policy", "")
|
||||
|
||||
@@ -244,9 +244,9 @@ func (fs *FilerServer) AppendToEntry(ctx context.Context, req *filer_pb.AppendTo
|
||||
glog.V(4).Infof("AppendToEntry %v", req)
|
||||
fullpath := util.NewFullPath(req.Directory, req.EntryName)
|
||||
|
||||
lockClient := cluster.NewLockClient(fs.grpcDialOption)
|
||||
lock := lockClient.NewLock(fs.option.Host, string(fullpath))
|
||||
defer lock.Unlock()
|
||||
lockClient := cluster.NewLockClient(fs.grpcDialOption, fs.option.Host)
|
||||
lock := lockClient.NewLock(string(fullpath), string(fs.option.Host))
|
||||
defer lock.StopLock()
|
||||
|
||||
var offset int64 = 0
|
||||
entry, err := fs.filer.FindEntry(ctx, fullpath)
|
||||
|
||||
@@ -6,24 +6,28 @@ import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Lock is a grpc handler to handle FilerServer's LockRequest
|
||||
func (fs *FilerServer) Lock(ctx context.Context, req *filer_pb.LockRequest) (resp *filer_pb.LockResponse, err error) {
|
||||
// DistributedLock is a grpc handler to handle FilerServer's LockRequest
|
||||
func (fs *FilerServer) DistributedLock(ctx context.Context, req *filer_pb.LockRequest) (resp *filer_pb.LockResponse, err error) {
|
||||
|
||||
resp = &filer_pb.LockResponse{}
|
||||
|
||||
var movedTo pb.ServerAddress
|
||||
expiredAtNs := time.Now().Add(time.Duration(req.SecondsToLock) * time.Second).UnixNano()
|
||||
resp.RenewToken, movedTo, err = fs.filer.Dlm.LockWithTimeout(req.Name, expiredAtNs, req.RenewToken)
|
||||
if !req.IsMoved && movedTo != "" {
|
||||
resp.RenewToken, movedTo, err = fs.filer.Dlm.LockWithTimeout(req.Name, expiredAtNs, req.RenewToken, req.Owner)
|
||||
glog.V(3).Infof("lock %s %v %v %v, isMoved=%v %v", req.Name, req.SecondsToLock, req.RenewToken, req.Owner, req.IsMoved, movedTo)
|
||||
if movedTo != "" && movedTo != fs.option.Host && !req.IsMoved {
|
||||
err = pb.WithFilerClient(false, 0, movedTo, fs.grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
|
||||
secondResp, err := client.Lock(context.Background(), &filer_pb.LockRequest{
|
||||
secondResp, err := client.DistributedLock(context.Background(), &filer_pb.LockRequest{
|
||||
Name: req.Name,
|
||||
SecondsToLock: req.SecondsToLock,
|
||||
RenewToken: req.RenewToken,
|
||||
IsMoved: true,
|
||||
Owner: req.Owner,
|
||||
})
|
||||
if err == nil {
|
||||
resp.RenewToken = secondResp.RenewToken
|
||||
@@ -45,7 +49,7 @@ func (fs *FilerServer) Lock(ctx context.Context, req *filer_pb.LockRequest) (res
|
||||
}
|
||||
|
||||
// Unlock is a grpc handler to handle FilerServer's UnlockRequest
|
||||
func (fs *FilerServer) Unlock(ctx context.Context, req *filer_pb.UnlockRequest) (resp *filer_pb.UnlockResponse, err error) {
|
||||
func (fs *FilerServer) DistributedUnlock(ctx context.Context, req *filer_pb.UnlockRequest) (resp *filer_pb.UnlockResponse, err error) {
|
||||
|
||||
resp = &filer_pb.UnlockResponse{}
|
||||
|
||||
@@ -54,7 +58,7 @@ func (fs *FilerServer) Unlock(ctx context.Context, req *filer_pb.UnlockRequest)
|
||||
|
||||
if !req.IsMoved && movedTo != "" {
|
||||
err = pb.WithFilerClient(false, 0, movedTo, fs.grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
|
||||
secondResp, err := client.Unlock(context.Background(), &filer_pb.UnlockRequest{
|
||||
secondResp, err := client.DistributedUnlock(context.Background(), &filer_pb.UnlockRequest{
|
||||
Name: req.Name,
|
||||
RenewToken: req.RenewToken,
|
||||
IsMoved: true,
|
||||
@@ -75,11 +79,37 @@ func (fs *FilerServer) Unlock(ctx context.Context, req *filer_pb.UnlockRequest)
|
||||
|
||||
}
|
||||
|
||||
func (fs *FilerServer) FindLockOwner(ctx context.Context, req *filer_pb.FindLockOwnerRequest) (*filer_pb.FindLockOwnerResponse, error) {
|
||||
owner, movedTo, err := fs.filer.Dlm.FindLockOwner(req.Name)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
if !req.IsMoved && movedTo != "" {
|
||||
err = pb.WithFilerClient(false, 0, movedTo, fs.grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
|
||||
secondResp, err := client.FindLockOwner(context.Background(), &filer_pb.FindLockOwnerRequest{
|
||||
Name: req.Name,
|
||||
IsMoved: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
owner = secondResp.Owner
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &filer_pb.FindLockOwnerResponse{
|
||||
Owner: owner,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TransferLocks is a grpc handler to handle FilerServer's TransferLocksRequest
|
||||
func (fs *FilerServer) TransferLocks(ctx context.Context, req *filer_pb.TransferLocksRequest) (*filer_pb.TransferLocksResponse, error) {
|
||||
|
||||
for _, lock := range req.Locks {
|
||||
fs.filer.Dlm.InsertLock(lock.Name, lock.ExpiredAtNs, lock.RenewToken)
|
||||
fs.filer.Dlm.InsertLock(lock.Name, lock.ExpiredAtNs, lock.RenewToken, lock.Owner)
|
||||
}
|
||||
|
||||
return &filer_pb.TransferLocksResponse{}, nil
|
||||
@@ -101,6 +131,7 @@ func (fs *FilerServer) OnDlmChangeSnapshot(snapshot []pb.ServerAddress) {
|
||||
Name: lock.Key,
|
||||
RenewToken: lock.Token,
|
||||
ExpiredAtNs: lock.ExpiredAtNs,
|
||||
Owner: lock.Owner,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -94,9 +94,6 @@ type FilerServer struct {
|
||||
// track known metadata listeners
|
||||
knownListenersLock sync.Mutex
|
||||
knownListeners map[int32]int32
|
||||
|
||||
// client to assign file id
|
||||
assignProxy *operation.AssignProxy
|
||||
}
|
||||
|
||||
func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption) (fs *FilerServer, err error) {
|
||||
@@ -135,8 +132,6 @@ func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption)
|
||||
go stats.LoopPushingMetric("filer", string(fs.option.Host), fs.metricsAddress, fs.metricsIntervalSec)
|
||||
go fs.filer.KeepMasterClientConnected()
|
||||
|
||||
fs.assignProxy, err = operation.NewAssignProxy(fs.filer.GetMaster, fs.grpcDialOption, 16)
|
||||
|
||||
if !util.LoadConfiguration("filer", false) {
|
||||
v.SetDefault("leveldb2.enabled", true)
|
||||
v.SetDefault("leveldb2.dir", option.DefaultLevelDbDir)
|
||||
@@ -189,7 +184,7 @@ func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption)
|
||||
|
||||
fs.filer.Dlm.LockRing.SetTakeSnapshotCallback(fs.OnDlmChangeSnapshot)
|
||||
|
||||
return fs, err
|
||||
return fs, nil
|
||||
}
|
||||
|
||||
func (fs *FilerServer) checkWithMaster() {
|
||||
|
||||
@@ -30,12 +30,6 @@ func (fs *FilerServer) filerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
isReadHttpCall := r.Method == "GET" || r.Method == "HEAD"
|
||||
if !fs.maybeCheckJwtAuthorization(r, !isReadHttpCall) {
|
||||
writeJsonError(w, r, http.StatusUnauthorized, errors.New("wrong jwt"))
|
||||
return
|
||||
}
|
||||
|
||||
// proxy to volume servers
|
||||
var fileId string
|
||||
if strings.HasPrefix(r.RequestURI, "/?proxyChunkId=") {
|
||||
@@ -48,6 +42,12 @@ func (fs *FilerServer) filerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
isReadHttpCall := r.Method == "GET" || r.Method == "HEAD"
|
||||
if !fs.maybeCheckJwtAuthorization(r, !isReadHttpCall) {
|
||||
writeJsonError(w, r, http.StatusUnauthorized, errors.New("wrong jwt"))
|
||||
return
|
||||
}
|
||||
|
||||
stats.FilerRequestCounter.WithLabelValues(r.Method).Inc()
|
||||
defer func() {
|
||||
stats.FilerRequestHistogram.WithLabelValues(r.Method).Observe(time.Since(start).Seconds())
|
||||
|
||||
@@ -43,7 +43,7 @@ func (fs *FilerServer) assignNewFileInfo(so *operation.StorageOption) (fileId, u
|
||||
|
||||
ar, altRequest := so.ToAssignRequests(1)
|
||||
|
||||
assignResult, ae := fs.assignProxy.Assign(ar, altRequest)
|
||||
assignResult, ae := operation.Assign(fs.filer.GetMaster, fs.grpcDialOption, ar, altRequest)
|
||||
if ae != nil {
|
||||
glog.Errorf("failing to assign a file id: %v", ae)
|
||||
err = ae
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"io"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Commands = append(Commands, &commandMqTopicCreate{})
|
||||
}
|
||||
|
||||
type commandMqTopicCreate struct {
|
||||
}
|
||||
|
||||
func (c *commandMqTopicCreate) Name() string {
|
||||
return "mq.topic.create"
|
||||
}
|
||||
|
||||
func (c *commandMqTopicCreate) Help() string {
|
||||
return `create a topic with a given name
|
||||
|
||||
Example:
|
||||
mq.topic.create -namespace <namespace> -topic <topic_name> -partition_count <partition_count>
|
||||
`
|
||||
}
|
||||
|
||||
func (c *commandMqTopicCreate) Do(args []string, commandEnv *CommandEnv, writer io.Writer) error {
|
||||
|
||||
// parse parameters
|
||||
mqCommand := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||
namespace := mqCommand.String("namespace", "", "namespace name")
|
||||
topicName := mqCommand.String("topic", "", "topic name")
|
||||
partitionCount := mqCommand.Int("partitionCount", 6, "partition count")
|
||||
if err := mqCommand.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// find the broker balancer
|
||||
brokerBalancer, err := findBrokerBalancer(commandEnv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(writer, "current balancer: %s\n", brokerBalancer)
|
||||
|
||||
// create topic
|
||||
return pb.WithBrokerGrpcClient(false, brokerBalancer, commandEnv.option.GrpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
resp, err := client.CreateTopic(context.Background(), &mq_pb.CreateTopicRequest{
|
||||
Topic: &mq_pb.Topic{
|
||||
Namespace: *namespace,
|
||||
Name: *topicName,
|
||||
},
|
||||
PartitionCount: int32(*partitionCount),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
output, _ := json.MarshalIndent(resp, "", " ")
|
||||
fmt.Fprintf(writer, "response:\n%+v\n", string(output))
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/balancer"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
|
||||
"io"
|
||||
)
|
||||
|
||||
@@ -20,9 +25,40 @@ func (c *commandMqTopicList) Help() string {
|
||||
return `print out all topics`
|
||||
}
|
||||
|
||||
func (c *commandMqTopicList) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) {
|
||||
func (c *commandMqTopicList) Do(args []string, commandEnv *CommandEnv, writer io.Writer) error {
|
||||
|
||||
fmt.Fprintf(writer, "%s\n", commandEnv.option.Directory)
|
||||
brokerBalancer, err := findBrokerBalancer(commandEnv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(writer, "current balancer: %s\n", brokerBalancer)
|
||||
|
||||
return nil
|
||||
return pb.WithBrokerGrpcClient(false, brokerBalancer, commandEnv.option.GrpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
|
||||
resp, err := client.ListTopics(context.Background(), &mq_pb.ListTopicsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(resp.Topics) == 0 {
|
||||
fmt.Fprintf(writer, "no topics found\n")
|
||||
return nil
|
||||
}
|
||||
for _, topic := range resp.Topics {
|
||||
fmt.Fprintf(writer, " %+v\n", topic)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func findBrokerBalancer(commandEnv *CommandEnv) (brokerBalancer string, err error) {
|
||||
err = commandEnv.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
|
||||
resp, err := client.FindLockOwner(context.Background(), &filer_pb.FindLockOwnerRequest{
|
||||
Name: balancer.LockBrokerBalancer,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
brokerBalancer = resp.Owner
|
||||
return nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -36,7 +36,9 @@ func (s *Store) DeleteEcShardNeedle(ecVolume *erasure_coding.EcVolume, n *needle
|
||||
func (s *Store) doDeleteNeedleFromAtLeastOneRemoteEcShards(ecVolume *erasure_coding.EcVolume, needleId types.NeedleId) error {
|
||||
|
||||
_, _, intervals, err := ecVolume.LocateEcShardNeedle(needleId, ecVolume.Version)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(intervals) == 0 {
|
||||
return erasure_coding.NotFoundError
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
VERSION_NUMBER = fmt.Sprintf("%.02f", 3.56)
|
||||
VERSION_NUMBER = fmt.Sprintf("%.02f", 3.57)
|
||||
VERSION = sizeLimit + " " + VERSION_NUMBER
|
||||
COMMIT = ""
|
||||
)
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// LockTable is a table of locks that can be acquired.
|
||||
// Locks are acquired in order of request.
|
||||
type LockTable[T comparable] struct {
|
||||
mu sync.Mutex
|
||||
locks map[T]*LockEntry
|
||||
lockIdSeq int64
|
||||
}
|
||||
|
||||
type LockEntry struct {
|
||||
mu sync.Mutex
|
||||
waiters []*ActiveLock // ordered waiters that are blocked by exclusive locks
|
||||
activeSharedLockOwnerCount int32
|
||||
activeExclusiveLockOwnerCount int32
|
||||
cond *sync.Cond
|
||||
}
|
||||
|
||||
type LockType int
|
||||
|
||||
const (
|
||||
SharedLock LockType = iota
|
||||
ExclusiveLock
|
||||
)
|
||||
|
||||
type ActiveLock struct {
|
||||
ID int64
|
||||
isDeleted bool
|
||||
intention string // for debugging
|
||||
lockType LockType
|
||||
}
|
||||
|
||||
func NewLockTable[T comparable]() *LockTable[T] {
|
||||
return &LockTable[T]{
|
||||
locks: make(map[T]*LockEntry),
|
||||
}
|
||||
}
|
||||
|
||||
func (lt *LockTable[T]) NewActiveLock(intention string, lockType LockType) *ActiveLock {
|
||||
id := atomic.AddInt64(<.lockIdSeq, 1)
|
||||
l := &ActiveLock{ID: id, intention: intention, lockType: lockType}
|
||||
return l
|
||||
}
|
||||
|
||||
func (lt *LockTable[T]) AcquireLock(intention string, key T, lockType LockType) (lock *ActiveLock) {
|
||||
lt.mu.Lock()
|
||||
// Get or create the lock entry for the key
|
||||
entry, exists := lt.locks[key]
|
||||
if !exists {
|
||||
entry = &LockEntry{}
|
||||
entry.cond = sync.NewCond(&entry.mu)
|
||||
lt.locks[key] = entry
|
||||
}
|
||||
lt.mu.Unlock()
|
||||
|
||||
lock = lt.NewActiveLock(intention, lockType)
|
||||
|
||||
// If the lock is held exclusively, wait
|
||||
entry.mu.Lock()
|
||||
if len(entry.waiters) > 0 || lockType == ExclusiveLock || entry.activeExclusiveLockOwnerCount > 0 {
|
||||
if glog.V(4) {
|
||||
fmt.Printf("ActiveLock %d %s wait for %+v type=%v with waiters %d active r%d w%d.\n", lock.ID, lock.intention, key, lockType, len(entry.waiters), entry.activeSharedLockOwnerCount, entry.activeExclusiveLockOwnerCount)
|
||||
if len(entry.waiters) > 0 {
|
||||
for _, waiter := range entry.waiters {
|
||||
fmt.Printf(" %d", waiter.ID)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
}
|
||||
entry.waiters = append(entry.waiters, lock)
|
||||
if lockType == ExclusiveLock {
|
||||
for !lock.isDeleted && ((len(entry.waiters) > 0 && lock.ID != entry.waiters[0].ID) || entry.activeExclusiveLockOwnerCount > 0 || entry.activeSharedLockOwnerCount > 0) {
|
||||
entry.cond.Wait()
|
||||
}
|
||||
} else {
|
||||
for !lock.isDeleted && (len(entry.waiters) > 0 && lock.ID != entry.waiters[0].ID) || entry.activeExclusiveLockOwnerCount > 0 {
|
||||
entry.cond.Wait()
|
||||
}
|
||||
}
|
||||
// Remove the transaction from the waiters list
|
||||
if len(entry.waiters) > 0 && lock.ID == entry.waiters[0].ID {
|
||||
entry.waiters = entry.waiters[1:]
|
||||
entry.cond.Broadcast()
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, grant the lock
|
||||
if glog.V(4) {
|
||||
fmt.Printf("ActiveLock %d %s locked %+v type=%v with waiters %d active r%d w%d.\n", lock.ID, lock.intention, key, lockType, len(entry.waiters), entry.activeSharedLockOwnerCount, entry.activeExclusiveLockOwnerCount)
|
||||
if len(entry.waiters) > 0 {
|
||||
for _, waiter := range entry.waiters {
|
||||
fmt.Printf(" %d", waiter.ID)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
}
|
||||
if lock.lockType == ExclusiveLock {
|
||||
entry.activeExclusiveLockOwnerCount++
|
||||
} else {
|
||||
entry.activeSharedLockOwnerCount++
|
||||
}
|
||||
entry.mu.Unlock()
|
||||
|
||||
return lock
|
||||
}
|
||||
|
||||
func (lt *LockTable[T]) ReleaseLock(key T, lock *ActiveLock) {
|
||||
lt.mu.Lock()
|
||||
defer lt.mu.Unlock()
|
||||
|
||||
entry, exists := lt.locks[key]
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
|
||||
entry.mu.Lock()
|
||||
defer entry.mu.Unlock()
|
||||
|
||||
// Remove the transaction from the waiters list
|
||||
for i, waiter := range entry.waiters {
|
||||
if waiter == lock {
|
||||
waiter.isDeleted = true
|
||||
entry.waiters = append(entry.waiters[:i], entry.waiters[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no waiters, release the lock
|
||||
if len(entry.waiters) == 0 && entry.activeExclusiveLockOwnerCount <= 0 && entry.activeSharedLockOwnerCount <= 0 {
|
||||
delete(lt.locks, key)
|
||||
}
|
||||
|
||||
if glog.V(4) {
|
||||
fmt.Printf("ActiveLock %d %s unlocked %+v type=%v with waiters %d active r%d w%d.\n", lock.ID, lock.intention, key, lock.lockType, len(entry.waiters), entry.activeSharedLockOwnerCount, entry.activeExclusiveLockOwnerCount)
|
||||
if len(entry.waiters) > 0 {
|
||||
for _, waiter := range entry.waiters {
|
||||
fmt.Printf(" %d", waiter.ID)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
}
|
||||
if lock.lockType == ExclusiveLock {
|
||||
entry.activeExclusiveLockOwnerCount--
|
||||
} else {
|
||||
entry.activeSharedLockOwnerCount--
|
||||
}
|
||||
|
||||
// Notify the next waiter
|
||||
entry.cond.Broadcast()
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestOrderedLock(t *testing.T) {
|
||||
lt := NewLockTable[string]()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
// Simulate transactions requesting locks
|
||||
for i := 1; i <= 50; i++ {
|
||||
wg.Add(1)
|
||||
go func(i int) {
|
||||
defer wg.Done()
|
||||
key := "resource"
|
||||
lockType := SharedLock
|
||||
if i%5 == 0 {
|
||||
lockType = ExclusiveLock
|
||||
}
|
||||
|
||||
// Simulate attempting to acquire the lock
|
||||
lock := lt.AcquireLock("", key, lockType)
|
||||
|
||||
// Lock acquired, perform some work
|
||||
fmt.Printf("ActiveLock %d acquired lock %v\n", lock.ID, lockType)
|
||||
|
||||
// Simulate some work
|
||||
time.Sleep(time.Duration(rand.Int31n(10)*10) * time.Millisecond)
|
||||
|
||||
// Release the lock
|
||||
lt.ReleaseLock(key, lock)
|
||||
fmt.Printf("ActiveLock %d released lock %v\n", lock.ID, lockType)
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
@@ -25,7 +25,7 @@ type MasterClient struct {
|
||||
currentMaster pb.ServerAddress
|
||||
currentMasterLock sync.RWMutex
|
||||
masters pb.ServerDiscovery
|
||||
grpcDialOption grpc.DialOption
|
||||
grpcDialOption grpc.DialOption
|
||||
|
||||
*vidMap
|
||||
vidMapCacheSize int
|
||||
@@ -244,9 +244,9 @@ func (mc *MasterClient) tryConnectToMaster(master pb.ServerAddress) (nextHintedL
|
||||
if mc.OnPeerUpdate != nil {
|
||||
if update.FilerGroup == mc.FilerGroup {
|
||||
if update.IsAdd {
|
||||
glog.V(0).Infof("+ %s.%s %s\n", update.FilerGroup, update.NodeType, update.Address)
|
||||
glog.V(0).Infof("+ %s@%s noticed %s.%s %s\n", mc.clientType, mc.clientHost, update.FilerGroup, update.NodeType, update.Address)
|
||||
} else {
|
||||
glog.V(0).Infof("- %s.%s %s\n", update.FilerGroup, update.NodeType, update.Address)
|
||||
glog.V(0).Infof("- %s@%s noticed %s.%s %s\n", mc.clientType, mc.clientHost, update.FilerGroup, update.NodeType, update.Address)
|
||||
}
|
||||
stats.MasterClientConnectCounter.WithLabelValues(stats.OnPeerUpdate).Inc()
|
||||
mc.OnPeerUpdate(update, time.Now())
|
||||
|
||||
Reference in New Issue
Block a user