use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class SegmentAggregator method reconcileAppendOperation.
/**
* Attempts to reconcile the given Append Operation. Since Append Operations can be partially flushed, reconciliation
* may be for the full operation or for a part of it.
*
* @param op The Operation (StreamSegmentAppendOperation or CachedStreamSegmentAppendOperation) to reconcile.
* @param storageInfo The current state of the Segment in Storage.
* @param timer Timer for the operation.
* @return A CompletableFuture containing a FlushResult with the number of bytes reconciled, or failed with a ReconciliationFailureException,
* if the operation cannot be reconciled, based on the in-memory metadata or the current state of the Segment in Storage.
*/
private CompletableFuture<FlushResult> reconcileAppendOperation(StorageOperation op, SegmentProperties storageInfo, TimeoutTimer timer) {
Preconditions.checkArgument(op instanceof AggregatedAppendOperation, "Not given an append operation.");
// Read data from Storage, and compare byte-by-byte.
InputStream appendStream = this.dataSource.getAppendData(op.getStreamSegmentId(), op.getStreamSegmentOffset(), (int) op.getLength());
if (appendStream == null) {
return Futures.failedFuture(new ReconciliationFailureException(String.format("Unable to reconcile operation '%s' because no append data is associated with it.", op), this.metadata, storageInfo));
}
// Only read as much data as we need.
long readLength = Math.min(op.getLastStreamSegmentOffset(), storageInfo.getLength()) - op.getStreamSegmentOffset();
assert readLength > 0 : "Append Operation to be reconciled is beyond the Segment's StorageLength " + op;
AtomicInteger bytesReadSoFar = new AtomicInteger();
// Read all data from storage.
byte[] storageData = new byte[(int) readLength];
return Futures.loop(() -> bytesReadSoFar.get() < readLength, () -> this.storage.read(this.handle.get(), op.getStreamSegmentOffset() + bytesReadSoFar.get(), storageData, bytesReadSoFar.get(), (int) readLength - bytesReadSoFar.get(), timer.getRemaining()), bytesRead -> {
assert bytesRead > 0 : String.format("Unable to make any read progress when reconciling operation '%s' after reading %s bytes.", op, bytesReadSoFar);
bytesReadSoFar.addAndGet(bytesRead);
}, this.executor).thenApplyAsync(v -> {
// Compare, byte-by-byte, the contents of the append.
verifySame(appendStream, storageData, op, storageInfo);
if (readLength >= op.getLength() && op.getLastStreamSegmentOffset() <= storageInfo.getLength()) {
// Operation has been completely validated; pop it off the list.
StorageOperation removedOp = this.operations.removeFirst();
assert op == removedOp : "Reconciled operation is not the same as removed operation";
}
return new FlushResult().withFlushedBytes(readLength);
}, this.executor);
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class SegmentStateStore method put.
@Override
public CompletableFuture<Void> put(String segmentName, SegmentState state, Duration timeout) {
String stateSegment = StreamSegmentNameUtils.getStateSegmentName(segmentName);
TimeoutTimer timer = new TimeoutTimer(timeout);
ArrayView toWrite = serialize(state);
// delete the existing segment (if any), then create a new one and write the contents to it.
return this.storage.openWrite(stateSegment).thenComposeAsync(handle -> this.storage.delete(handle, timer.getRemaining()), this.executor).exceptionally(this::handleSegmentNotExistsException).thenComposeAsync(v -> this.storage.create(stateSegment, SegmentRollingPolicy.NO_ROLLING, timer.getRemaining()), this.executor).thenComposeAsync(v -> this.storage.openWrite(stateSegment), this.executor).thenComposeAsync(handle -> this.storage.write(handle, 0, toWrite.getReader(), toWrite.getLength(), timer.getRemaining()), this.executor);
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class StreamSegmentContainer method append.
// endregion
// region StreamSegmentStore Implementation
@Override
public CompletableFuture<Void> append(String streamSegmentName, byte[] data, Collection<AttributeUpdate> attributeUpdates, Duration timeout) {
ensureRunning();
TimeoutTimer timer = new TimeoutTimer(timeout);
logRequest("append", streamSegmentName, data.length);
this.metrics.append();
return this.segmentMapper.getOrAssignStreamSegmentId(streamSegmentName, timer.getRemaining(), streamSegmentId -> {
StreamSegmentAppendOperation operation = new StreamSegmentAppendOperation(streamSegmentId, data, attributeUpdates);
return this.durableLog.add(operation, timer.getRemaining());
});
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class StreamSegmentContainer method append.
@Override
public CompletableFuture<Void> append(String streamSegmentName, long offset, byte[] data, Collection<AttributeUpdate> attributeUpdates, Duration timeout) {
ensureRunning();
TimeoutTimer timer = new TimeoutTimer(timeout);
logRequest("appendWithOffset", streamSegmentName, data.length);
this.metrics.appendWithOffset();
return this.segmentMapper.getOrAssignStreamSegmentId(streamSegmentName, timer.getRemaining(), streamSegmentId -> {
StreamSegmentAppendOperation operation = new StreamSegmentAppendOperation(streamSegmentId, offset, data, attributeUpdates);
return this.durableLog.add(operation, timer.getRemaining());
});
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class StreamSegmentContainer method updateAttributes.
@Override
public CompletableFuture<Void> updateAttributes(String streamSegmentName, Collection<AttributeUpdate> attributeUpdates, Duration timeout) {
ensureRunning();
TimeoutTimer timer = new TimeoutTimer(timeout);
logRequest("updateAttributes", streamSegmentName, attributeUpdates);
this.metrics.updateAttributes();
return this.segmentMapper.getOrAssignStreamSegmentId(streamSegmentName, timer.getRemaining(), streamSegmentId -> {
UpdateAttributesOperation operation = new UpdateAttributesOperation(streamSegmentId, attributeUpdates);
return this.durableLog.add(operation, timer.getRemaining());
});
}
Aggregations