|
20 | 20 | import org.elasticsearch.index.translog.Translog;
|
21 | 21 | import org.elasticsearch.test.ESTestCase;
|
22 | 22 | import org.elasticsearch.threadpool.Scheduler;
|
| 23 | +import org.elasticsearch.threadpool.TestThreadPool; |
| 24 | +import org.elasticsearch.threadpool.ThreadPool; |
23 | 25 | import org.elasticsearch.xpack.ccr.action.bulk.BulkShardOperationsResponse;
|
24 | 26 | import org.elasticsearch.xpack.core.ccr.ShardFollowNodeTaskStatus;
|
25 | 27 |
|
|
33 | 35 | import java.util.Map;
|
34 | 36 | import java.util.Queue;
|
35 | 37 | import java.util.concurrent.CountDownLatch;
|
| 38 | +import java.util.concurrent.Phaser; |
36 | 39 | import java.util.concurrent.ScheduledFuture;
|
37 | 40 | import java.util.concurrent.ScheduledThreadPoolExecutor;
|
38 | 41 | import java.util.concurrent.TimeUnit;
|
@@ -1122,6 +1125,117 @@ public void testRetentionLeaseRenewal() throws InterruptedException {
|
1122 | 1125 | }
|
1123 | 1126 | }
|
1124 | 1127 |
|
| 1128 | + public void testUpdateMappingSettingsAndAliasesConcurrently() throws Exception { |
| 1129 | + final ShardFollowTask followTask = new ShardFollowTask( |
| 1130 | + "test", |
| 1131 | + new ShardId("leader_index", "", 0), |
| 1132 | + new ShardId("follow_index", "", 0), |
| 1133 | + Integer.MAX_VALUE, |
| 1134 | + Integer.MAX_VALUE, |
| 1135 | + Integer.MAX_VALUE, |
| 1136 | + Integer.MAX_VALUE, |
| 1137 | + new ByteSizeValue(Long.MAX_VALUE), |
| 1138 | + new ByteSizeValue(Long.MAX_VALUE), |
| 1139 | + Integer.MAX_VALUE, |
| 1140 | + new ByteSizeValue(Long.MAX_VALUE), |
| 1141 | + TimeValue.ZERO, |
| 1142 | + TimeValue.ZERO, |
| 1143 | + Collections.emptyMap() |
| 1144 | + ); |
| 1145 | + final ThreadPool threadPool = new TestThreadPool(getTestClass().getSimpleName()); |
| 1146 | + final AtomicLong leaderMappingVersion = new AtomicLong(0L); |
| 1147 | + final AtomicLong followerMappingVersion = new AtomicLong(0L); |
| 1148 | + final AtomicLong leaderSettingsVersion = new AtomicLong(0L); |
| 1149 | + final AtomicLong followerSettingsVersion = new AtomicLong(0L); |
| 1150 | + final AtomicLong leaderAliasesVersion = new AtomicLong(0L); |
| 1151 | + final AtomicLong followerAliasesVersion = new AtomicLong(0L); |
| 1152 | + |
| 1153 | + final Phaser updates = new Phaser(1); |
| 1154 | + final ShardFollowNodeTask shardFollowNodeTask = new ShardFollowNodeTask( |
| 1155 | + 1L, "type", ShardFollowTask.NAME, "description", null, Collections.emptyMap(), followTask, scheduler, System::nanoTime) { |
| 1156 | + @Override |
| 1157 | + protected void innerUpdateMapping(long minRequiredMappingVersion, LongConsumer handler, Consumer<Exception> errorHandler) { |
| 1158 | + updates.register(); |
| 1159 | + final long fetchedVersion = randomLongBetween(minRequiredMappingVersion, leaderMappingVersion.get()); |
| 1160 | + followerMappingVersion.updateAndGet(curr -> Math.max(curr, fetchedVersion)); |
| 1161 | + threadPool.generic().execute(() -> { |
| 1162 | + handler.accept(fetchedVersion); |
| 1163 | + updates.arriveAndDeregister(); |
| 1164 | + }); |
| 1165 | + } |
| 1166 | + |
| 1167 | + @Override |
| 1168 | + protected void innerUpdateSettings(LongConsumer handler, Consumer<Exception> errorHandler) { |
| 1169 | + updates.register(); |
| 1170 | + final long fetchedVersion = randomLongBetween(0L, leaderSettingsVersion.get()); |
| 1171 | + followerSettingsVersion.updateAndGet(curr -> Math.max(curr, fetchedVersion)); |
| 1172 | + threadPool.generic().execute(() -> { |
| 1173 | + handler.accept(fetchedVersion); |
| 1174 | + updates.arriveAndDeregister(); |
| 1175 | + }); |
| 1176 | + } |
| 1177 | + |
| 1178 | + @Override |
| 1179 | + protected void innerUpdateAliases(LongConsumer handler, Consumer<Exception> errorHandler) { |
| 1180 | + updates.register(); |
| 1181 | + final long fetchedVersion = randomLongBetween(0L, leaderAliasesVersion.get()); |
| 1182 | + followerAliasesVersion.updateAndGet(curr -> Math.max(curr, fetchedVersion)); |
| 1183 | + threadPool.generic().execute(() -> { |
| 1184 | + handler.accept(fetchedVersion); |
| 1185 | + updates.arriveAndDeregister(); |
| 1186 | + }); |
| 1187 | + } |
| 1188 | + |
| 1189 | + @Override |
| 1190 | + protected void innerSendBulkShardOperationsRequest(String followerHistoryUUID, |
| 1191 | + List<Translog.Operation> operations, |
| 1192 | + long leaderMaxSeqNoOfUpdatesOrDeletes, |
| 1193 | + Consumer<BulkShardOperationsResponse> handler, |
| 1194 | + Consumer<Exception> errorHandler) { |
| 1195 | + |
| 1196 | + } |
| 1197 | + |
| 1198 | + @Override |
| 1199 | + protected void innerSendShardChangesRequest(long from, int maxOperationCount, |
| 1200 | + Consumer<ShardChangesAction.Response> handler, |
| 1201 | + Consumer<Exception> errorHandler) { |
| 1202 | + |
| 1203 | + } |
| 1204 | + |
| 1205 | + @Override |
| 1206 | + protected Scheduler.Cancellable scheduleBackgroundRetentionLeaseRenewal(LongSupplier followerGlobalCheckpoint) { |
| 1207 | + return null; |
| 1208 | + } |
| 1209 | + |
| 1210 | + @Override |
| 1211 | + synchronized void coordinateReads() { |
| 1212 | + |
| 1213 | + } |
| 1214 | + }; |
| 1215 | + int responses = between(10, 5000); |
| 1216 | + for (int i = 0; i < responses; i++) { |
| 1217 | + ShardChangesAction.Response response = new ShardChangesAction.Response( |
| 1218 | + leaderMappingVersion.addAndGet(between(0, Integer.MAX_VALUE)), |
| 1219 | + leaderSettingsVersion.addAndGet(between(0, Integer.MAX_VALUE)), |
| 1220 | + leaderAliasesVersion.addAndGet(between(0, Integer.MAX_VALUE)), |
| 1221 | + SequenceNumbers.NO_OPS_PERFORMED, |
| 1222 | + SequenceNumbers.NO_OPS_PERFORMED, |
| 1223 | + -1, |
| 1224 | + new Translog.Operation[0], |
| 1225 | + randomLong() |
| 1226 | + ); |
| 1227 | + shardFollowNodeTask.handleReadResponse(0, -1, response); |
| 1228 | + } |
| 1229 | + try { |
| 1230 | + updates.arriveAndAwaitAdvance(); |
| 1231 | + final ShardFollowNodeTaskStatus status = shardFollowNodeTask.getStatus(); |
| 1232 | + assertThat(status.followerMappingVersion(), equalTo(followerMappingVersion.get())); |
| 1233 | + assertThat(status.followerSettingsVersion(), equalTo(followerSettingsVersion.get())); |
| 1234 | + assertThat(status.followerAliasesVersion(), equalTo(followerAliasesVersion.get())); |
| 1235 | + } finally { |
| 1236 | + terminate(threadPool); |
| 1237 | + } |
| 1238 | + } |
1125 | 1239 |
|
1126 | 1240 | static final class ShardFollowTaskParams {
|
1127 | 1241 | private String remoteCluster = null;
|
|
0 commit comments