use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class EntryIterator method getNext.
// endregion
// region AsyncIterator Implementation
/**
* Attempts to get the next element in the iteration. Please refer to {@link AsyncIterator#getNext()} for details.
*
* If this method is invoked concurrently (a second call is initiated prior to the previous call terminating) the
* state of the {@link EntryIterator} will be corrupted. Consider using {@link AsyncIterator#asSequential}.
*
* @return A CompletableFuture that, when completed, will contain a List of {@link PageEntry} instances that are
* next in the iteration, or null if no more items can be served.
*/
@Override
public CompletableFuture<List<PageEntry>> getNext() {
if (this.finished.get()) {
return CompletableFuture.completedFuture(null);
}
TimeoutTimer timer = new TimeoutTimer(this.fetchTimeout);
return locateNextPage(timer).thenApply(pageWrapper -> {
// Remember this page (for next time).
this.lastPage.set(pageWrapper);
List<PageEntry> result = null;
if (pageWrapper != null) {
// Extract the intermediate results from the page.
result = extractFromPage(pageWrapper);
this.processedPageCount.incrementAndGet();
}
// Check if we have reached the last page that could possibly contain some result.
if (result == null) {
this.finished.set(true);
}
return result;
});
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class AsyncTableEntryReaderTests method testReadEntryNoKeyMatch.
/**
* Tests the ability to not read a Table Entry if the sought key does not match.
*/
@Test
public void testReadEntryNoKeyMatch() throws Exception {
val testItems = generateTestItems();
for (int i = 0; i < testItems.size(); i++) {
for (int j = 0; j < testItems.size(); j++) {
if (i == j) {
// This case is tested in testReadEntry().
continue;
}
val searchKey = testItems.get(i).key;
val searchData = testItems.get(j).serialization;
val entryReader = AsyncTableEntryReader.readEntry(new ByteArraySegment(searchKey), 0L, SERIALIZER, new TimeoutTimer(TIMEOUT));
@Cleanup val rr = new ReadResultMock(searchData, searchData.length, 1);
AsyncReadResultProcessor.process(rr, entryReader, executorService());
val result = entryReader.getResult().get(BASE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
Assert.assertNull("Not expecting a result.", result);
}
}
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class StreamSegmentStoreTestBase method waitForSegmentInStorage.
private CompletableFuture<Void> waitForSegmentInStorage(SegmentProperties sp, StreamSegmentStore readOnlyStore) {
if (sp.getLength() == 0) {
// Empty segments may or may not exist in Storage, so don't bother complicating ourselves with this.
return CompletableFuture.completedFuture(null);
}
// We want to make sure that both the main segment and its attribute segment have been sync-ed to Storage. In case
// of the attribute segment, the only thing we can easily do is verify that it has been sealed when the main segment
// it is associated with has also been sealed.
String attributeSegmentName = NameUtils.getAttributeSegmentName(sp.getName());
TimeoutTimer timer = new TimeoutTimer(TIMEOUT);
AtomicBoolean tryAgain = new AtomicBoolean(true);
return Futures.loop(tryAgain::get, () -> {
val segInfo = getStorageSegmentInfo(sp.getName(), timer, readOnlyStore);
val attrInfo = getStorageSegmentInfo(attributeSegmentName, timer, readOnlyStore);
return CompletableFuture.allOf(segInfo, attrInfo).thenCompose(v -> {
StreamSegmentInformation storageProps = (StreamSegmentInformation) segInfo.join();
StreamSegmentInformation attrProps = (StreamSegmentInformation) attrInfo.join();
if (sp.isDeleted()) {
tryAgain.set(!storageProps.isDeletedInStorage());
} else if (sp.isSealed()) {
tryAgain.set(!storageProps.isSealedInStorage());
} else {
tryAgain.set(sp.getLength() != storageProps.getStorageLength());
}
if (tryAgain.get() && !timer.hasRemaining()) {
return Futures.<Void>failedFuture(new TimeoutException(String.format("Segment %s did not complete in Storage in the allotted time. %s ", sp.getName(), segInfo)));
} else {
return Futures.delayedFuture(Duration.ofMillis(100), executorService());
}
});
}, executorService());
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class AsyncTableEntryReaderTests method testBufferCompaction.
private <T> void testBufferCompaction(GetEntryReader<T> createReader, Function<T, TableKey> getKey, Function<T, BufferView> getValue) throws Exception {
// Must be less than AsyncTableEntryReader.INITIAL_READ_LENGTH / 2 (to ease testing).
val keyLength = 3987;
// Must be less than AsyncTableEntryReader.INITIAL_READ_LENGTH / 2 (to ease testing)..
val valueLength = 3123;
val serializer = new EntrySerializer();
// Generate a number of entries. We only care about the first one, but we want to ensure that we have enough other
// data to force the ReadResult to try to read more.
val testItems = generateTestItems(() -> keyLength, () -> valueLength);
val entries = testItems.stream().filter(i -> !i.isRemoval).map(i -> TableEntry.unversioned(new ByteArraySegment(i.key), new ByteArraySegment(i.value))).collect(Collectors.toList());
// Search for the first Key/Entry. This makes it easier as we don't have to guess the versions, offsets, etc.
val soughtEntry = entries.get(0);
val segmentData = serializer.serializeUpdate(entries).getCopy();
@Cleanup val readResultNoCompact = new ReadResultMock(segmentData, keyLength + valueLength + 20, keyLength + 200);
val readerNoCompact = createReader.apply(soughtEntry.getKey().getKey(), 0L, serializer, new TimeoutTimer(TIMEOUT));
testBufferCompaction(readerNoCompact, readResultNoCompact, getKey, getValue, false);
@Cleanup val readResultWithCompact = new ReadResultMock(segmentData, segmentData.length, segmentData.length);
val readerWithCompact = createReader.apply(soughtEntry.getKey().getKey(), 0L, serializer, new TimeoutTimer(TIMEOUT));
testBufferCompaction(readerWithCompact, readResultWithCompact, getKey, getValue, true);
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class AsyncTableEntryReaderTests method testReadKey.
// region Reading Keys
/**
* Tests the ability to read a key.
*/
@Test
public void testReadKey() throws Exception {
val testItems = generateTestItems();
for (val e : testItems) {
val keyReader = AsyncTableEntryReader.readKey(1L, SERIALIZER, new TimeoutTimer(TIMEOUT));
Assert.assertEquals("Unexpected initial suggested read length.", AsyncTableEntryReader.INITIAL_READ_LENGTH, keyReader.getMaxReadAtOnce());
@Cleanup val rr = new ReadResultMock(e.serialization, e.serialization.length, 1);
AsyncReadResultProcessor.process(rr, keyReader, executorService());
AssertExtensions.assertEventuallyEquals(true, () -> {
int readerMaxReadAtOnce = keyReader.getMaxReadAtOnce();
return Math.min(rr.getMaxResultLength(), readerMaxReadAtOnce != 0 ? readerMaxReadAtOnce : Integer.MAX_VALUE) == rr.getMaxReadAtOnce();
}, 30 * 1000);
// Get the result and compare it with the original key.
val result = keyReader.getResult().get(BASE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
val expectedVersion = e.isRemoval ? TableKey.NOT_EXISTS : (e.explicitVersion == TableKey.NO_VERSION) ? 1L : e.explicitVersion;
Assert.assertEquals("Unexpected version.", expectedVersion, result.getVersion());
Assert.assertEquals("Unexpected key read back.", new ByteArraySegment(e.key), result.getKey());
Assert.assertEquals("Unexpected final suggested read length.", 0, keyReader.getMaxReadAtOnce());
}
}
Aggregations