|
6 | 6 | package org.elasticsearch.xpack.ccr.action;
|
7 | 7 |
|
8 | 8 | import org.elasticsearch.ElasticsearchException;
|
| 9 | +import org.elasticsearch.action.ActionListener; |
9 | 10 | import org.elasticsearch.common.UUIDs;
|
10 | 11 | import org.elasticsearch.common.collect.Tuple;
|
11 | 12 | import org.elasticsearch.common.settings.Settings;
|
@@ -77,6 +78,7 @@ public class ShardFollowNodeTaskTests extends ESTestCase {
|
77 | 78 | private Queue<Long> followerGlobalCheckpoints;
|
78 | 79 | private Queue<Long> maxSeqNos;
|
79 | 80 | private Queue<Integer> responseSizes;
|
| 81 | + private Queue<ActionListener<BulkShardOperationsResponse>> pendingBulkShardRequests; |
80 | 82 |
|
81 | 83 | public void testCoordinateReads() {
|
82 | 84 | ShardFollowTaskParams params = new ShardFollowTaskParams();
|
@@ -597,6 +599,55 @@ public void testReceiveNothingExpectedSomething() {
|
597 | 599 | assertThat(status.leaderGlobalCheckpoint(), equalTo(63L));
|
598 | 600 | }
|
599 | 601 |
|
| 602 | + public void testHandlePartialResponses() { |
| 603 | + ShardFollowTaskParams params = new ShardFollowTaskParams(); |
| 604 | + params.maxReadRequestOperationCount = 10; |
| 605 | + params.maxOutstandingReadRequests = 2; |
| 606 | + params.maxOutstandingWriteRequests = 1; |
| 607 | + params.maxWriteBufferCount = 3; |
| 608 | + |
| 609 | + ShardFollowNodeTask task = createShardFollowTask(params); |
| 610 | + startTask(task, 99, -1); |
| 611 | + |
| 612 | + task.coordinateReads(); |
| 613 | + assertThat(shardChangesRequests.size(), equalTo(2)); |
| 614 | + assertThat(shardChangesRequests.get(0)[0], equalTo(0L)); |
| 615 | + assertThat(shardChangesRequests.get(0)[1], equalTo(10L)); |
| 616 | + assertThat(shardChangesRequests.get(1)[0], equalTo(10L)); |
| 617 | + assertThat(shardChangesRequests.get(1)[1], equalTo(10L)); |
| 618 | + |
| 619 | + task.innerHandleReadResponse(0L, 9L, generateShardChangesResponse(0L, 5L, 0L, 0L, 99L)); |
| 620 | + assertThat(pendingBulkShardRequests, hasSize(1)); |
| 621 | + assertThat("continue the partial request", shardChangesRequests, hasSize(3)); |
| 622 | + assertThat(shardChangesRequests.get(2)[0], equalTo(6L)); |
| 623 | + assertThat(shardChangesRequests.get(2)[1], equalTo(4L)); |
| 624 | + assertThat(pendingBulkShardRequests, hasSize(1)); |
| 625 | + task.innerHandleReadResponse(10, 19L, generateShardChangesResponse(10L, 17L, 0L, 0L, 99L)); |
| 626 | + assertThat("do not continue partial reads as the buffer is full", shardChangesRequests, hasSize(3)); |
| 627 | + task.innerHandleReadResponse(6L, 9L, generateShardChangesResponse(6L, 8L, 0L, 0L, 99L)); |
| 628 | + assertThat("do not continue partial reads as the buffer is full", shardChangesRequests, hasSize(3)); |
| 629 | + pendingBulkShardRequests.remove().onResponse(new BulkShardOperationsResponse()); |
| 630 | + assertThat(pendingBulkShardRequests, hasSize(1)); |
| 631 | + |
| 632 | + assertThat("continue two partial requests as the buffer is empty after sending", shardChangesRequests, hasSize(5)); |
| 633 | + assertThat(shardChangesRequests.get(3)[0], equalTo(9L)); |
| 634 | + assertThat(shardChangesRequests.get(3)[1], equalTo(1L)); |
| 635 | + assertThat(shardChangesRequests.get(4)[0], equalTo(18L)); |
| 636 | + assertThat(shardChangesRequests.get(4)[1], equalTo(2L)); |
| 637 | + |
| 638 | + task.innerHandleReadResponse(18L, 19L, generateShardChangesResponse(18L, 19L, 0L, 0L, 99L)); |
| 639 | + assertThat("start new range as the buffer has empty slots", shardChangesRequests, hasSize(6)); |
| 640 | + assertThat(shardChangesRequests.get(5)[0], equalTo(20L)); |
| 641 | + assertThat(shardChangesRequests.get(5)[1], equalTo(10L)); |
| 642 | + |
| 643 | + task.innerHandleReadResponse(9L, 9L, generateShardChangesResponse(9L, 9L, 0L, 0L, 99L)); |
| 644 | + assertThat("do not start new range as the buffer is full", shardChangesRequests, hasSize(6)); |
| 645 | + pendingBulkShardRequests.remove().onResponse(new BulkShardOperationsResponse()); |
| 646 | + assertThat("start new range as the buffer is empty after sending", shardChangesRequests, hasSize(7)); |
| 647 | + assertThat(shardChangesRequests.get(6)[0], equalTo(30L)); |
| 648 | + assertThat(shardChangesRequests.get(6)[1], equalTo(10L)); |
| 649 | + } |
| 650 | + |
600 | 651 | public void testMappingUpdate() {
|
601 | 652 | ShardFollowTaskParams params = new ShardFollowTaskParams();
|
602 | 653 | params.maxReadRequestOperationCount = 64;
|
@@ -909,7 +960,7 @@ public void testMaxWriteRequestSize() {
|
909 | 960 |
|
910 | 961 | ShardChangesAction.Response response = generateShardChangesResponse(0, 63, 0L, 0L, 64L);
|
911 | 962 | // Also invokes coordinatesWrites()
|
912 |
| - task.innerHandleReadResponse(0L, 64L, response); |
| 963 | + task.innerHandleReadResponse(0L, 63L, response); |
913 | 964 |
|
914 | 965 | assertThat(bulkShardOperationRequests.size(), equalTo(64));
|
915 | 966 | }
|
@@ -1033,6 +1084,7 @@ private ShardFollowNodeTask createShardFollowTask(ShardFollowTaskParams params)
|
1033 | 1084 | followerGlobalCheckpoints = new LinkedList<>();
|
1034 | 1085 | maxSeqNos = new LinkedList<>();
|
1035 | 1086 | responseSizes = new LinkedList<>();
|
| 1087 | + pendingBulkShardRequests = new LinkedList<>(); |
1036 | 1088 | return new ShardFollowNodeTask(
|
1037 | 1089 | 1L, "type", ShardFollowTask.NAME, "description", null, Collections.emptyMap(), followTask, scheduler, System::nanoTime) {
|
1038 | 1090 |
|
@@ -1082,6 +1134,8 @@ protected void innerSendBulkShardOperationsRequest(
|
1082 | 1134 | response.setGlobalCheckpoint(followerGlobalCheckpoint);
|
1083 | 1135 | response.setMaxSeqNo(followerGlobalCheckpoint);
|
1084 | 1136 | handler.accept(response);
|
| 1137 | + } else { |
| 1138 | + pendingBulkShardRequests.add(ActionListener.wrap(handler::accept, errorHandler)); |
1085 | 1139 | }
|
1086 | 1140 | }
|
1087 | 1141 |
|
|
0 commit comments