use of io.pravega.client.stream.ReaderNotInReaderGroupException in project pravega by pravega.
the class ReaderGroupStateManager method acquireSegment.
private Map<SegmentWithRange, Long> acquireSegment(long timeLag, Position position) throws ReaderNotInReaderGroupException {
AtomicBoolean reinitRequired = new AtomicBoolean();
Map<SegmentWithRange, Long> result = sync.updateState((state, updates) -> {
if (!state.isReaderOnline(readerId)) {
reinitRequired.set(true);
return Collections.<SegmentWithRange, Long>emptyMap();
}
reinitRequired.set(false);
if (state.getCheckpointForReader(readerId) != null) {
return Collections.<SegmentWithRange, Long>emptyMap();
}
int toAcquire = calculateNumSegmentsToAcquire(state);
if (toAcquire == 0) {
return Collections.<SegmentWithRange, Long>emptyMap();
}
Map<SegmentWithRange, Long> unassignedSegments = state.getUnassignedSegments();
Map<SegmentWithRange, Long> acquired = new HashMap<>(toAcquire);
Iterator<Entry<SegmentWithRange, Long>> iter = unassignedSegments.entrySet().iterator();
for (int i = 0; i < toAcquire; i++) {
assert iter.hasNext();
Entry<SegmentWithRange, Long> segment = iter.next();
acquired.put(segment.getKey(), segment.getValue());
updates.add(new AcquireSegment(readerId, segment.getKey().getSegment()));
}
updates.add(new UpdateDistanceToTail(readerId, timeLag, position.asImpl().getOwnedSegmentRangesWithOffsets()));
return acquired;
});
if (reinitRequired.get()) {
throw new ReaderNotInReaderGroupException(readerId);
}
releaseTimer.reset(calculateReleaseTime(readerId, sync.getState()));
acquireTimer.reset(calculateAcquireTime(readerId, sync.getState()));
resetLagUpdateTimer();
return result;
}
use of io.pravega.client.stream.ReaderNotInReaderGroupException in project pravega by pravega.
the class ReaderGroupStateManager method checkpoint.
void checkpoint(String checkpointName, PositionInternal lastPosition) throws ReaderNotInReaderGroupException {
AtomicBoolean reinitRequired = new AtomicBoolean(false);
sync.updateState((state, updates) -> {
if (!state.isReaderOnline(readerId)) {
reinitRequired.set(true);
} else {
reinitRequired.set(false);
String cpName = state.getCheckpointForReader(readerId);
if (checkpointName.equals(cpName)) {
updates.add(new CheckpointReader(checkpointName, readerId, lastPosition.getOwnedSegmentsWithOffsets()));
} else {
log.warn("{} was asked to checkpoint for {} but the state says its next checkpoint should be {}", readerId, checkpointName, cpName);
}
}
});
if (reinitRequired.get()) {
throw new ReaderNotInReaderGroupException(readerId);
}
}
use of io.pravega.client.stream.ReaderNotInReaderGroupException in project pravega by pravega.
the class ReaderGroupStateManager method handleEndOfSegment.
/**
* Handles a segment being completed by calling the controller to gather all successors to the
* completed segment. To ensure consistent checkpoints, a segment cannot be released while a
* checkpoint for the reader is pending, so it may or may not succeed.
*
* @return true if the completed segment was released successfully.
*/
boolean handleEndOfSegment(SegmentWithRange segmentCompleted) throws ReaderNotInReaderGroupException {
final Map<SegmentWithRange, List<Long>> segmentToPredecessor;
if (sync.getState().getEndSegments().containsKey(segmentCompleted.getSegment())) {
segmentToPredecessor = Collections.emptyMap();
} else {
val successors = getAndHandleExceptions(controller.getSuccessors(segmentCompleted.getSegment()), RuntimeException::new);
segmentToPredecessor = successors.getSegmentToPredecessor();
}
AtomicBoolean reinitRequired = new AtomicBoolean(false);
boolean result = sync.updateState((state, updates) -> {
if (!state.isReaderOnline(readerId)) {
log.error("Reader " + readerId + " is offline according to the state but is attempting to update it.");
reinitRequired.set(true);
return false;
}
if (!state.getSegments(readerId).contains(segmentCompleted.getSegment())) {
log.error("Reader " + readerId + " is does not own the segment " + segmentCompleted + "but is attempting to release it.");
reinitRequired.set(true);
return false;
}
log.debug("Marking segment {} as completed in reader group. CurrentState is: {}", segmentCompleted, state);
reinitRequired.set(false);
// This check guards against another checkpoint having started.
if (state.getCheckpointForReader(readerId) == null) {
updates.add(new SegmentCompleted(readerId, segmentCompleted, segmentToPredecessor));
return true;
}
return false;
});
if (reinitRequired.get()) {
throw new ReaderNotInReaderGroupException(readerId);
}
acquireTimer.zero();
return result;
}
use of io.pravega.client.stream.ReaderNotInReaderGroupException in project pravega by pravega.
the class ReaderGroupStateManager method releaseSegment.
/**
* Releases a segment to another reader. This reader should no longer read from the segment.
*
* @param segment The segment to be released
* @param lastOffset The offset from which the new owner should start reading from.
* @param timeLag How far the reader is from the tail of the stream in time.
* @param position The last read position
* @return a boolean indicating if the segment was successfully released.
* @throws ReaderNotInReaderGroupException If the reader has been declared offline.
*/
boolean releaseSegment(Segment segment, long lastOffset, long timeLag, Position position) throws ReaderNotInReaderGroupException {
sync.updateState((state, updates) -> {
Set<Segment> segments = state.getSegments(readerId);
if (segments != null && segments.contains(segment) && state.getCheckpointForReader(readerId) == null && doesReaderOwnTooManySegments(state)) {
updates.add(new ReleaseSegment(readerId, segment, lastOffset));
updates.add(new UpdateDistanceToTail(readerId, timeLag, position.asImpl().getOwnedSegmentRangesWithOffsets()));
}
});
ReaderGroupState state = sync.getState();
releaseTimer.reset(calculateReleaseTime(readerId, state));
acquireTimer.reset(calculateAcquireTime(readerId, state));
resetLagUpdateTimer();
if (!state.isReaderOnline(readerId)) {
throw new ReaderNotInReaderGroupException(readerId);
}
return !state.getSegments(readerId).contains(segment);
}
use of io.pravega.client.stream.ReaderNotInReaderGroupException in project pravega by pravega.
the class ReaderGroupStateManager method getCheckpoint.
/**
* Returns name of the checkpoint to be processed by this reader
* @return String - name of the first checkpoint pending processing for this Reader.
*/
String getCheckpoint() throws ReaderNotInReaderGroupException {
fetchUpdatesIfNeeded();
ReaderGroupState state = sync.getState();
long automaticCpInterval = state.getConfig().getAutomaticCheckpointIntervalMillis();
if (!state.isReaderOnline(readerId)) {
throw new ReaderNotInReaderGroupException(readerId);
}
String checkpoint = state.getCheckpointForReader(readerId);
if (checkpoint != null) {
checkpointTimer.reset(Duration.ofMillis(automaticCpInterval));
return checkpoint;
}
if (automaticCpInterval <= 0 || checkpointTimer.hasRemaining() || state.hasOngoingCheckpoint()) {
return null;
}
sync.updateState((s, u) -> {
if (!s.hasOngoingCheckpoint()) {
CreateCheckpoint newCp = new CreateCheckpoint();
u.add(newCp);
u.add(new ClearCheckpointsBefore(newCp.getCheckpointId()));
log.debug("Created new checkpoint: {} currentState is: {}", newCp, s);
}
});
checkpointTimer.reset(Duration.ofMillis(automaticCpInterval));
return state.getCheckpointForReader(readerId);
}
Aggregations