use of io.pravega.client.segment.impl.SegmentSealedException in project pravega by pravega.
the class EventStreamWriterImpl method handleLogSealed.
/**
* If a log sealed is encountered, we need to: 1. Find the new segments to write to. 2. For each outstanding
* message find which new segment it should go to and send it there.
*/
private void handleLogSealed(Segment segment) {
sealedSegmentQueueEmptyLatch.reset();
sealedSegmentQueue.add(segment);
retransmitPool.execute(() -> {
Retry.indefinitelyWithExpBackoff(config.getInitialBackoffMillis(), config.getBackoffMultiple(), config.getMaxBackoffMillis(), t -> log.error("Encountered exception when handling a sealed segment: ", t)).run(() -> {
/*
* Using writeSealLock prevents concurrent segmentSealedCallback for different segments
* from being invoked concurrently, or concurrently with write.
*
* By calling flush while the write lock is held we can ensure that any inflight
* entries that will succeed in being written to a new segment are written and any
* segmentSealedCallbacks that will be called happen before the next write is invoked.
*/
synchronized (writeSealLock) {
Segment toSeal = sealedSegmentQueue.poll();
log.info("Sealing segment {} ", toSeal);
while (toSeal != null) {
resend(selector.refreshSegmentEventWritersUponSealed(toSeal, segmentSealedCallBack));
// remove segment writer after resending inflight events of the sealed segment.
selector.removeSegmentWriter(toSeal);
/* In the case of segments merging Flush ensures there can't be anything left
* inflight that will need to be resent to the new segment when the write lock
* is released. (To preserve order)
*/
for (SegmentOutputStream writer : selector.getWriters().values()) {
try {
writer.write(PendingEvent.withoutHeader(null, ByteBufferUtils.EMPTY, null));
writer.flush();
} catch (SegmentSealedException e) {
// Segment sealed exception observed during a flush. Re-run flush on all the
// available writers.
log.info("Flush on segment {} failed due to {}, it will be retried.", writer.getSegmentName(), e.getMessage());
} catch (RetriesExhaustedException e1) {
log.warn("Flush on segment {} failed after all retries", writer.getSegmentName(), e1);
}
}
toSeal = sealedSegmentQueue.poll();
if (toSeal != null) {
log.info("Sealing another segment {} ", toSeal);
}
}
sealedSegmentQueueEmptyLatch.release();
}
return null;
});
});
}
use of io.pravega.client.segment.impl.SegmentSealedException in project pravega by pravega.
the class EventStreamWriterImpl method close.
@Override
public void close() {
if (closed.getAndSet(true)) {
return;
}
pinger.close();
synchronized (writeFlushLock) {
boolean success = false;
while (!success) {
success = true;
for (SegmentOutputStream writer : selector.getWriters().values()) {
try {
writer.close();
} catch (SegmentSealedException e) {
// Segment sealed exception observed during a close. Re-run close on all the available writers.
success = false;
log.warn("Close failed due to {}, it will be retried.", e.getMessage());
tryWaitForSuccessors();
}
}
}
}
ExecutorServiceHelpers.shutdown(retransmitPool);
}
use of io.pravega.client.segment.impl.SegmentSealedException in project pravega by pravega.
the class EventStreamWriterImpl method flush.
@Override
public void flush() {
Preconditions.checkState(!closed.get());
synchronized (writeFlushLock) {
boolean success = false;
RuntimeException retriesExhaustedException = null;
while (!success) {
success = true;
for (SegmentOutputStream writer : selector.getWriters().values()) {
try {
writer.flush();
} catch (SegmentSealedException e) {
// Segment sealed exception observed during a flush. Re-run flush on all the
// available writers.
success = false;
log.warn("Flush on segment {} by event writer {} failed due to {}, it will be retried.", writer.getSegmentName(), writerId, e.getMessage());
tryWaitForSuccessors();
break;
} catch (RetriesExhaustedException e1) {
// Ensure a flush is invoked on all the segment writers before throwing a RetriesExhaustedException.
log.warn("Flush on segment {} by event writer {} failed after all configured retries", writer.getSegmentName(), writerId);
retriesExhaustedException = e1;
}
}
}
if (retriesExhaustedException != null) {
log.error("Flush by writer {} on Stream {} failed after all retries to connect with Pravega exhausted.", writerId, stream.getScopedName());
throw retriesExhaustedException;
}
}
}
use of io.pravega.client.segment.impl.SegmentSealedException in project pravega by pravega.
the class RevisionedStreamClientImpl method writeConditionally.
@Override
public Revision writeConditionally(Revision latestRevision, T value) {
boolean wasWritten;
long offset = latestRevision.asImpl().getOffsetInSegment();
ByteBuffer serialized = serializer.serialize(value);
int size = serialized.remaining();
synchronized (lock) {
try {
wasWritten = conditional.write(serialized, offset);
} catch (SegmentSealedException e) {
throw new CorruptedStateException("Unexpected end of segment ", e);
}
}
if (wasWritten) {
long newOffset = getNewOffset(offset, size);
log.debug("Wrote from {} to {}", offset, newOffset);
return new RevisionImpl(segment, newOffset, 0);
} else {
log.debug("Conditional write failed at offset {}", offset);
return null;
}
}
use of io.pravega.client.segment.impl.SegmentSealedException in project pravega by pravega.
the class EventStreamWriterImpl method flushInternal.
private void flushInternal() {
writeFlushLock.readLock().lock();
boolean success = false;
try {
while (!success) {
success = true;
for (SegmentOutputStream writer : selector.getWriters()) {
try {
writer.flush();
} catch (SegmentSealedException e) {
// Segment sealed exception observed during a flush. Re-run flush on all the available writers.
success = false;
log.warn("Flush failed due to {}, it will be retried.", e.getMessage());
}
}
}
} finally {
writeFlushLock.readLock().unlock();
}
}
Aggregations