|
29 | 29 | import com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression;
|
30 | 30 | import com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression;
|
31 | 31 | import com.apple.foundationdb.record.metadata.expressions.KeyExpression;
|
| 32 | +import com.apple.foundationdb.synchronizedsession.SynchronizedSessionLockedException; |
32 | 33 | import com.apple.test.BooleanSource;
|
33 | 34 | import com.google.common.collect.Comparators;
|
34 | 35 | import org.junit.jupiter.api.Test;
|
|
40 | 41 | import javax.annotation.Nullable;
|
41 | 42 | import java.util.List;
|
42 | 43 | import java.util.Map;
|
| 44 | +import java.util.concurrent.Semaphore; |
| 45 | +import java.util.concurrent.TimeUnit; |
| 46 | +import java.util.concurrent.atomic.AtomicBoolean; |
43 | 47 | import java.util.concurrent.atomic.AtomicLong;
|
44 | 48 | import java.util.stream.Collectors;
|
45 | 49 | import java.util.stream.IntStream;
|
@@ -1156,4 +1160,69 @@ void testIndexFromIndexBlock() {
|
1156 | 1160 | assertReadable(tgtIndex);
|
1157 | 1161 | scrubAndValidate(List.of(tgtIndex));
|
1158 | 1162 | }
|
| 1163 | + |
| 1164 | + @Test |
| 1165 | + void testForbidConcurrentIndexFromIndexSessions() throws InterruptedException { |
| 1166 | + // Do not let a conversion of few indexes of an active multi-target session |
| 1167 | + final int numRecords = 59; |
| 1168 | + populateData(numRecords); |
| 1169 | + |
| 1170 | + Index sourceIndex = new Index("src_index", field("num_value_2"), EmptyKeyExpression.EMPTY, IndexTypes.VALUE, IndexOptions.UNIQUE_OPTIONS); |
| 1171 | + openSimpleMetaData(metaDataBuilder -> metaDataBuilder.addIndex("MySimpleRecord", sourceIndex)); |
| 1172 | + buildIndexClean(sourceIndex); |
| 1173 | + |
| 1174 | + // Partly build index |
| 1175 | + Index tgtIndex = new Index("tgt_index", field("num_value_3_indexed"), IndexTypes.VALUE); |
| 1176 | + FDBRecordStoreTestBase.RecordMetaDataHook hook = myHook(sourceIndex, tgtIndex); |
| 1177 | + openSimpleMetaData(hook); |
| 1178 | + |
| 1179 | + Semaphore pauseMutualBuildSemaphore = new Semaphore(1); |
| 1180 | + Semaphore startBuildingSemaphore = new Semaphore(1); |
| 1181 | + pauseMutualBuildSemaphore.acquire(); |
| 1182 | + startBuildingSemaphore.acquire(); |
| 1183 | + AtomicBoolean passed = new AtomicBoolean(false); |
| 1184 | + Thread t1 = new Thread(() -> { |
| 1185 | + // build index and pause halfway, allowing an active session test |
| 1186 | + try (OnlineIndexer indexBuilder = newIndexerBuilder(tgtIndex) |
| 1187 | + .setLeaseLengthMillis(TimeUnit.SECONDS.toMillis(20)) |
| 1188 | + .setLimit(4) |
| 1189 | + .setIndexingPolicy(OnlineIndexer.IndexingPolicy.newBuilder() |
| 1190 | + .setSourceIndex("src_index") |
| 1191 | + .forbidRecordScan()) |
| 1192 | + .setConfigLoader(old -> { |
| 1193 | + if (passed.get()) { |
| 1194 | + try { |
| 1195 | + startBuildingSemaphore.release(); |
| 1196 | + pauseMutualBuildSemaphore.acquire(); // pause to try building indexes |
| 1197 | + } catch (InterruptedException e) { |
| 1198 | + throw new RuntimeException(e); |
| 1199 | + } finally { |
| 1200 | + pauseMutualBuildSemaphore.release(); |
| 1201 | + } |
| 1202 | + } else { |
| 1203 | + passed.set(true); |
| 1204 | + } |
| 1205 | + return old; |
| 1206 | + }) |
| 1207 | + .build()) { |
| 1208 | + indexBuilder.buildIndex(); |
| 1209 | + } |
| 1210 | + }); |
| 1211 | + t1.start(); |
| 1212 | + startBuildingSemaphore.acquire(); |
| 1213 | + startBuildingSemaphore.release(); |
| 1214 | + // Try one index at a time |
| 1215 | + try (OnlineIndexer indexBuilder = newIndexerBuilder(tgtIndex) |
| 1216 | + .setIndexingPolicy(OnlineIndexer.IndexingPolicy.newBuilder() |
| 1217 | + .setSourceIndex("src_index") |
| 1218 | + .forbidRecordScan()) |
| 1219 | + .build()) { |
| 1220 | + assertThrows(SynchronizedSessionLockedException.class, indexBuilder::buildIndex); |
| 1221 | + } |
| 1222 | + // let the other thread finish indexing |
| 1223 | + pauseMutualBuildSemaphore.release(); |
| 1224 | + t1.join(); |
| 1225 | + // happy indexes assertion |
| 1226 | + assertReadable(tgtIndex); |
| 1227 | + } |
1159 | 1228 | }
|
0 commit comments