* vector: follow a leader hint at once and skip one that failed this pass
A follower naming a dead leader stalled master failover. Each pass broke
off at the first hint, tried that leader first on the next pass, then
got the same hint from the same follower, so the later configured
masters were never tried. A pass now works like wdclient.tryAllMasters:
it follows a hint at once, does not follow a hint to a master that
already failed in that pass, and moves on to the rest. The hops are
bounded by the master count, as the volume heartbeat bounds its hints,
so two masters naming each other cannot spin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* vector: test a hint naming a failed master in its gRPC form
A pass keys failed masters by host:http, so a configured m1:9333 that
failed must also stop a hint of m1:9333.19333. Cover that equivalence.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UpvafvK8JpagF94MHWqwK
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* vector: refuse to drop a location that is not the table's own
DropIndex removed everything under whatever location the catalog
described. That location is caller-supplied through the Lance
namespace and only confined to the bucket, so a table registered at
s3://bkt/vector, or at another index's directory, wiped every index in
the bucket or that index. drop now accepts only the colocated path the
gateway's tableLocation derives from the table id, after trimming a
trailing slash, and the RPC answers FailedPrecondition otherwise. This
mirrors the ancestor and live-entry guards on the catalog's DeleteTable.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* vector: bound the master dial and try a leader hint once
A remembered leader hint was never cleared and the dial had no connect
timeout, so a black-holed former leader added the kernel's SYN timeout
(about two minutes) to every reconnect pass before the configured
masters were tried, and registration lapsed. The dial now gives up
after 5s, the same bound wdclient puts on a master call, and a hint is
tried once ahead of the configured masters, as wdclient.tryAllMasters
keeps nextHintedLeader for one cycle only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* vector: refuse a master port whose gRPC port would pass 65535
grpc_addr derived the gRPC port as http + 10000 in u16, which panics in
debug builds and in release silently dials a wrapped port for HTTP
ports above 55535. Go's pb.ServerToGrpcAddress adds in int, so the port
never wraps and the dial fails instead. The addition is now checked,
and weed-vector refuses to start with an error asking for the explicit
host:http.grpc form.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* vector: refuse a numeric master port past 65535
A master given as m1:65536 or m1:9333.65536 failed both u16 parses and
fell through to the raw address, so startup accepted it and every dial
failed. Ports now parse as u64, as Go's ServerToGrpcAddress does with
ParseUint, and one outside u16 is refused at startup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* vector: bound the master's first keep-connected answer
The connect timeout only covers TCP. A master that accepts the stream
and never answers held stream_to forever: grpc-go sends the response
headers with the first message, so the call never returned and later
seeds were never tried. A healthy master always answers at once (a
follower with its leader hint), so the stream open and the first
response now share the same 5s bound; after that the long-lived stream
stays untimed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* vector: only follow a leader hint that points elsewhere
The master sends volume_location on every KeepConnected response —
the leader always names itself, so the worker exited the stream on
the first response and flapped every 3s, leaving ListClusterNodes to
see the node intermittently. Only redirect when the hint points at a
different master.
* vector: leader hints carry host:http.grpc — normalize before comparing
A self-hint arrives as host:9333.19333 while --masters gives host:9333,
so the raw comparison still redirected and grpc_addr could not parse
the dotted port. grpc_addr now prefers the explicit .grpcPort, and the
hint comparison normalizes both sides to host:httpPort first.
* vector: weed-vector registers with the weed master
weed-vector-server --masters holds a KeepConnected stream to the weed
master, the same mechanism filer and s3 use via wdclient — the server
shows up in ListClusterNodes(client_type=vector). Resends registration
and rediscovers on failure.
* vector: s3 discovers weed-vector through the master
With -vectors.grpc unset the vectors gateway resolves one registered
weed-vector via ListClusterNodes on the masters it already derives
from filer config — discovery replaces the static dial for the
single-worker OSS path. The conformance harness registers the engine
to mini's master and drops -vectors.grpc.
* vector: default-fill registration fields
..Default::default() keeps the source compiling against proto variants
that carry extra fields, so the same file works in either tree.
* vector: serve the Vectors API on the main s3 port
The vectors router sits on the main -port listener behind a dispatch
that checks the SigV4 credential scope for /s3vectors/ — no separate
port needed. -port.vectors stays for explicit dedicated-port
deployments; the conformance harness now hits vectors through :8334.
* vector: drop -port.vectors entirely
It was new — no compat to preserve. The main -port listener serves the
API whenever a weed-vector backend is reachable.
* vector: drop -vectors.grpc; discovery is the only locator
weed-vector always registers to master, the gateway always resolves it
through ListClusterNodes — a static address just forks membership.
* vector: binary is weed-vector
Matches the enterprise binary; package and lib names are unchanged.
* vector: review fixes — cluster type, grpc port, lazy resolve, leader hint, advertise
- cluster: register 'vector' as a node type so ListClusterNodes returns
weed-vector members
- s3: dial masters via ToGrpcAddress (HTTP port + 10000)
- s3: backend resolves lazily through vectorDiscovery — workers joining
after gateway startup work on first query, and address changes re-dial
- master_client: convert master HTTP addr to grpc +10000, honor http(s)
scheme, follow the leader hint in KeepConnectedResponse, and
--advertise covers wildcard/unreachable listen addresses
* vector: no --advertise flag; derive the outbound address
A wildcard listen resolves to the source IP the master sees via a
route lookup, so registration always advertises something reachable
without another flag.
* vector: review fixes — plaintext dispatch, conn leaks, discovery backoff
The two plaintext http servers now serve the vectors dispatch too —
signed s3vectors calls on the main port reach the right router.
discoverVectorWorker closes each master conn and bounds lookups to 5s;
a dead or absent worker no longer re-hits master on every RPC — the
resolver backs off for 5s between rediscovery attempts.
* vector: 1 GiB grpc cap, dead-worker invalidation, CLI rename
Valid PutVectors batches exceed the tonic 4 MiB default — match the
gateway's 1 GiB cap. A replaced worker no longer sticks: any RPC error
resets the cached address and the next call rediscovers through the
master. The core CLI bin renames to weed-vector-cli so the two crates
do not collide on the same output path.
* vector: retry-only-transport reset, periodic re-resolve, cli rename
- reset() takes the failed client and runs only on transport errors —
an InvalidArgument on a healthy conn no longer interrupts unrelated
requests, and a concurrent re-resolve wins the race.
- cli() re-resolves once the interval passes even with a live client,
so a worker that moves addresses is picked up.
- verify.rs spike docs use weed-vector-cli after the bin rename.
* vector: only Unavailable counts as a transport failure
A request deadline or an application error can fire on a healthy
connection — resetting the shared conn on those churned reconnects.