Repository navigation
fix(tenants): split tenant updates at the server's limit of 100 - #616
dudanogueira wants to merge 3 commits into
Conversation
PUT /schema/{class}/tenants rejects more than 100 tenants with HTTP 422,
so updating more than that failed outright -- and with it activate,
deactivate and offload, which all delegate to update. The Python and
TypeScript clients split the request internally, so the same code
written against either of them worked and the Java one did not.
update() now sends the tenants in batches of 100, on the sync and async
clients alike; the async one chains them so they reach the server one
after another rather than all at once. Adding tenants stays a single
request: the server validates it with allowOverHundred=true, so only
updates are capped.
More than one request means a partial update is now possible: if a batch
fails, the tenants of the preceding batches stay updated and the error
propagates. Python and TypeScript behave the same way; it is documented
on both update() methods.
MockRestTransport.performRequestAsync returned null, which no chained
caller could compose on; it returns a completed future now.
Closes #615
Claude-Session: https://claude.ai/code/session_01WmY5dAGWCccWDoqkKNC2JU
b2ff369 to
f8d3db4
Compare
There was a problem hiding this comment.
Orca Security Scan Summary
| Status | Check | Issues by priority | |
|---|---|---|---|
| Infrastructure as Code | View in Orca | ||
| SAST | View in Orca | ||
| Secrets | View in Orca | ||
| Vulnerabilities | View in Orca |
There was a problem hiding this comment.
Pull request overview
This PR fixes tenant updates failing with HTTP 422 when more than 100 tenants are updated at once by batching PUT /schema/{class}/tenants requests at the server-enforced limit (100). The batching is centralized so that update, activate, deactivate, and offload all benefit, with both sync and async clients sending batches sequentially.
Changes:
- Add batching logic (
MAX_TENANTS_PER_REQUEST = 100andbatches(...)) toUpdateTenantsRequest. - Update sync and async tenants clients to send update batches sequentially, documenting partial-update behavior.
- Add unit and integration tests covering batching behavior and a mock transport adjustment to enable async chaining tests.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/java/io/weaviate/testutil/transport/MockRestTransport.java | Returns a completed future for async requests to enable thenCompose chaining in tests. |
| src/test/java/io/weaviate/client6/v1/api/collections/tenants/UpdateTenantsBatchingTest.java | New unit tests validating batch splitting and request counts/bodies for sync + async clients. |
| src/main/java/io/weaviate/client6/v1/api/collections/tenants/WeaviateTenantsClientAsync.java | Chains update batches sequentially via thenCompose; adds Javadoc about batching/partial updates. |
| src/main/java/io/weaviate/client6/v1/api/collections/tenants/WeaviateTenantsClient.java | Sends update batches sequentially in the sync client; adds Javadoc about batching/partial updates. |
| src/main/java/io/weaviate/client6/v1/api/collections/tenants/UpdateTenantsRequest.java | Encodes the server limit (100) and provides batching helper used by both clients. |
| src/it/java/io/weaviate/integration/TenantsITest.java | Adds an integration test validating 250-tenant deactivate/activate works via batching. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🟡 Changes recommended
The async MockRestTransport change currently drops BooleanEndpoint behavior (can return null where a boolean is expected) and there is a misleading @param Javadoc in the updated public method.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
src/test/java/io/weaviate/testutil/transport/MockRestTransport.java:61
performRequestAsyncalways returnscompletedFuture(null)and ignoresBooleanEndpoint, unlikeperformRequestandDefaultRestTransportwhich return a boolean result for boolean endpoints. This can cause async client tests usingMockRestTransport(e.g.,exists(...)) to seenullinstead of a boolean.
@Override
public <RequestT, ResponseT, ExceptionT> CompletableFuture<ResponseT> performRequestAsync(RequestT request,
Endpoint<RequestT, ResponseT> endpoint) {
requests.add(new Request<>(request, endpoint));
// A completed future rather than null, so callers which chain requests
// (thenCompose) can be tested against this transport.
return CompletableFuture.completedFuture(null);
}
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
- Remove the comments and Javadoc added in the previous commit. - Copy each batch so later changes to the caller's list cannot reach requests that are still in flight. - Fix the @PARAM of update(List<Tenant>): it takes tenant configurations. - MockRestTransport.performRequestAsync answers BooleanEndpoint with TRUE, like performRequest. Claude-Session: https://claude.ai/code/session_01VCkN66JyKNd2RQpFE46nCE
Problem
PUT /schema/{class}/tenantsrejects more than 100 tenants with HTTP 422, and the client sent the whole list in one request. Updating more than 100 tenants failed, and so didactivate,deactivateandoffload, which all go throughupdate:Fix
update(List<Tenant>)sends the tenants in batches of 100, one after another, in both the sync and async clients (the async client chains them withthenCompose).createis not split: the server does not cap the number of tenants added in one request.Breaking changes
None.
Closes #615