Skip to content

Commit 80a7adb

Browse files
author
Harald Musum
authored
Merge pull request #32562 from vespa-engine/revert-32555-vekterli/wire-tas-timestamps-through-document-v1-handler
Revert "Use timestamp TaS conditions from Document V1 handler when possible"
2 parents 4d14ac6 + d690b40 commit 80a7adb

File tree

2 files changed

+14
-108
lines changed

2 files changed

+14
-108
lines changed

vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,55 +1285,35 @@ private interface VisitCallback {
12851285
default void onStart(JsonResponse response, boolean fullyApplied) throws IOException { }
12861286

12871287
/** Called for every document or removal received from backend visitors—must call the ack for these to proceed. */
1288-
default void onDocument(JsonResponse response, Document document, DocumentId removeId, long persistedTimestamp, Runnable ack, Consumer<String> onError) { }
1288+
default void onDocument(JsonResponse response, Document document, DocumentId removeId, Runnable ack, Consumer<String> onError) { }
12891289

12901290
/** Called at the end of response rendering, before generic status data is written. Called from a dedicated thread pool. */
12911291
default void onEnd(JsonResponse response) throws IOException { }
12921292
}
12931293

1294-
@FunctionalInterface
1295-
private interface VisitProcessingCallback {
1296-
Result apply(DocumentId id, long persistedTimestamp, DocumentOperationParameters params);
1297-
}
1298-
12991294
private void visitAndDelete(HttpRequest request, VisitorParameters parameters, ResponseHandler handler,
13001295
TestAndSetCondition condition, String route) {
1301-
visitAndProcess(request, parameters, true, handler, route, (id, timestamp, operationParameters) -> {
1296+
visitAndProcess(request, parameters, true, handler, route, (id, operationParameters) -> {
13021297
DocumentRemove remove = new DocumentRemove(id);
1303-
// If the backend provided a persisted timestamp, we set a condition that specifies _both_ the
1304-
// original selection and the timestamp. If the backend supports timestamp-predicated TaS operations,
1305-
// it will ignore the selection entirely and only look at the timestamp. If it does not, it will fall
1306-
// back to evaluating the selection, which preserves legacy behavior.
1307-
if (timestamp != 0) {
1308-
remove.setCondition(TestAndSetCondition.ofRequiredTimestampWithSelectionFallback(
1309-
timestamp, condition.getSelection()));
1310-
} else {
1311-
remove.setCondition(condition);
1312-
}
1298+
remove.setCondition(condition);
13131299
return asyncSession.remove(remove, operationParameters);
13141300
});
13151301
}
13161302

13171303
private void visitAndUpdate(HttpRequest request, VisitorParameters parameters, boolean fullyApplied,
13181304
ResponseHandler handler, DocumentUpdate protoUpdate, String route) {
1319-
visitAndProcess(request, parameters, fullyApplied, handler, route, (id, timestamp, operationParameters) -> {
1320-
DocumentUpdate update = new DocumentUpdate(protoUpdate);
1321-
// See `visitAndDelete()` for rationale for sending down a timestamp _and_ the original condition.
1322-
if (timestamp != 0) {
1323-
update.setCondition(TestAndSetCondition.ofRequiredTimestampWithSelectionFallback(
1324-
timestamp, protoUpdate.getCondition().getSelection()));
1325-
} // else: use condition already set from protoUpdate
1326-
update.setId(id);
1327-
return asyncSession.update(update, operationParameters);
1305+
visitAndProcess(request, parameters, fullyApplied, handler, route, (id, operationParameters) -> {
1306+
DocumentUpdate update = new DocumentUpdate(protoUpdate);
1307+
update.setId(id);
1308+
return asyncSession.update(update, operationParameters);
13281309
});
13291310
}
13301311

13311312
private void visitAndProcess(HttpRequest request, VisitorParameters parameters, boolean fullyApplied,
13321313
ResponseHandler handler,
1333-
String route, VisitProcessingCallback operation) {
1314+
String route, BiFunction<DocumentId, DocumentOperationParameters, Result> operation) {
13341315
visit(request, parameters, false, fullyApplied, handler, new VisitCallback() {
1335-
@Override public void onDocument(JsonResponse response, Document document, DocumentId removeId,
1336-
long persistedTimestamp, Runnable ack, Consumer<String> onError) {
1316+
@Override public void onDocument(JsonResponse response, Document document, DocumentId removeId, Runnable ack, Consumer<String> onError) {
13371317
DocumentOperationParameters operationParameters = parameters().withRoute(route)
13381318
.withResponseHandler(operationResponse -> {
13391319
outstanding.decrementAndGet();
@@ -1352,7 +1332,7 @@ private void visitAndProcess(HttpRequest request, VisitorParameters parameters,
13521332
}
13531333
});
13541334
visitOperations.offer(() -> {
1355-
Result result = operation.apply(document.getId(), persistedTimestamp, operationParameters);
1335+
Result result = operation.apply(document.getId(), operationParameters);
13561336
if (result.type() == Result.ResultType.TRANSIENT_ERROR)
13571337
return false;
13581338

@@ -1377,8 +1357,7 @@ private void visitAndWrite(HttpRequest request, VisitorParameters parameters, Re
13771357

13781358
response.writeDocumentsArrayStart();
13791359
}
1380-
@Override public void onDocument(JsonResponse response, Document document, DocumentId removeId,
1381-
long persistedTimestamp, Runnable ack, Consumer<String> onError) {
1360+
@Override public void onDocument(JsonResponse response, Document document, DocumentId removeId, Runnable ack, Consumer<String> onError) {
13821361
try {
13831362
if (streamed) {
13841363
CompletionHandler completion = new CompletionHandler() {
@@ -1478,21 +1457,13 @@ private void visit(HttpRequest request, VisitorParameters parameters, boolean st
14781457
@Override public void onMessage(Message m, AckToken token) {
14791458
Document document = null;
14801459
DocumentId removeId = null;
1481-
long persistedTimestamp = 0;
1482-
if (m instanceof PutDocumentMessage put) {
1483-
document = put.getDocumentPut().getDocument();
1484-
persistedTimestamp = put.getPersistedTimestamp();
1485-
} else if (parameters.visitRemoves() && m instanceof RemoveDocumentMessage remove) {
1486-
removeId = remove.getDocumentId();
1487-
persistedTimestamp = remove.getPersistedTimestamp();
1488-
} else {
1489-
throw new UnsupportedOperationException("Got unsupported message type: " + m.getClass().getName());
1490-
}
1460+
if (m instanceof PutDocumentMessage put) document = put.getDocumentPut().getDocument();
1461+
else if (parameters.visitRemoves() && m instanceof RemoveDocumentMessage remove) removeId = remove.getDocumentId();
1462+
else throw new UnsupportedOperationException("Got unsupported message type: " + m.getClass().getName());
14911463
locallyReceivedDocCount.getAndAdd(1);
14921464
callback.onDocument(response,
14931465
document,
14941466
removeId,
1495-
persistedTimestamp,
14961467
() -> ack(token),
14971468
errorMessage -> {
14981469
error.set(errorMessage);

vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,71 +1018,6 @@ public void testResponses() {
10181018
driver.close();
10191019
}
10201020

1021-
@Test
1022-
public void batch_update_rewrites_tas_condition_with_timestamp_predicate_if_provided_by_backend() {
1023-
var driver = new RequestHandlerTestDriver(handler); // try-with-resources hangs the test on assertion failure, which isn't optimal
1024-
List<AckToken> tokens = List.of(new AckToken(null), new AckToken(null), new AckToken(null), new AckToken(null));
1025-
long backendTimestamp = 1234567890;
1026-
1027-
access.expect(tokens.subList(2, 3));
1028-
access.expect(parameters -> {
1029-
var put = new PutDocumentMessage(new DocumentPut(doc3));
1030-
put.setPersistedTimestamp(backendTimestamp);
1031-
parameters.getLocalDataHandler().onMessage(put, tokens.get(2));
1032-
parameters.getControlHandler().onDone(VisitorControlHandler.CompletionCode.TIMEOUT, "Won't care");
1033-
});
1034-
access.session.expect((update, parameters) -> {
1035-
// TaS condition should now have _both_ the original selection and the exact backend timestamp.
1036-
var expectedCondition = TestAndSetCondition.ofRequiredTimestampWithSelectionFallback(backendTimestamp, "optimist");
1037-
assertEquals(expectedCondition, ((DocumentUpdate) update).getCondition());
1038-
parameters.responseHandler().get().handleResponse(new UpdateResponse(0, false));
1039-
return new Result();
1040-
});
1041-
var response = driver.sendRequest("http://localhost/document/v1/space/music/docid?selection=optimist&cluster=content&timeChunk=10", PUT,
1042-
"""
1043-
{
1044-
"fields": {
1045-
"artist": { "assign": "Jahn Teigen" }
1046-
}
1047-
}""");
1048-
assertSameJson("""
1049-
{
1050-
"pathId": "/document/v1/space/music/docid",
1051-
"documentCount": 1
1052-
}""",
1053-
response.readAll());
1054-
assertEquals(200, response.getStatus());
1055-
}
1056-
1057-
@Test
1058-
public void batch_remove_rewrites_tas_condition_with_timestamp_predicate_if_provided_by_backend() {
1059-
var driver = new RequestHandlerTestDriver(handler); // try-with-resources hangs the test on assertion failure, which isn't optimal
1060-
List<AckToken> tokens = List.of(new AckToken(null), new AckToken(null), new AckToken(null), new AckToken(null));
1061-
long backendTimestamp = 1234567890;
1062-
1063-
access.expect(tokens.subList(2, 3));
1064-
access.expect(parameters -> {
1065-
var put = new PutDocumentMessage(new DocumentPut(doc3.getDataType(), doc3.getId())); // Only the document ID
1066-
put.setPersistedTimestamp(backendTimestamp);
1067-
parameters.getLocalDataHandler().onMessage(put, tokens.get(2));
1068-
parameters.getControlHandler().onDone(VisitorControlHandler.CompletionCode.TIMEOUT, "Won't care");
1069-
});
1070-
access.session.expect((remove, parameters) -> {
1071-
var expectedCondition = TestAndSetCondition.ofRequiredTimestampWithSelectionFallback(backendTimestamp, "pessimist");
1072-
assertEquals(expectedCondition, ((DocumentRemove) remove).getCondition());
1073-
parameters.responseHandler().get().handleResponse(new DocumentIdResponse(0, doc2.getId()));
1074-
return new Result();
1075-
});
1076-
var response = driver.sendRequest("http://localhost/document/v1/?selection=pessimist&cluster=content&timeChunk=10", DELETE);
1077-
assertSameJson("""
1078-
{
1079-
"pathId": "/document/v1/",
1080-
"documentCount": 1
1081-
}""",
1082-
response.readAll());
1083-
assertEquals(200, response.getStatus());
1084-
}
1085-
10861021
private void doTestVisitRequestWithParams(String httpReqParams, Consumer<VisitorParameters> paramChecker) {
10871022
try (var driver = new RequestHandlerTestDriver(handler)) {
10881023
access.expect(parameters -> {

0 commit comments

Comments
 (0)