Source:
public static void transfer(Layout layout, @NonNull String endpoint, CorfuRuntime runtime, Layout.LayoutSegment segment) throws Exception { if (endpoint.isEmpty()) { log.debug("stateTransfer: No server needs to transfer for segment [{} - {}], " + "skipping state transfer for this segment.", segment.getStart(), segment.getEnd()); return; } int chunkSize = runtime.getParameters().getBulkReadSize(); final AtomicInteger overwriteRetries = new AtomicInteger(); IRetry.build(ExponentialBackoffRetry.class, RetryExhaustedException.class, () -> { try { long trimMark = setTrimOnNewLogUnit(layout, runtime, endpoint); if (trimMark > segment.getEnd()) { log.info("stateTransfer: Nothing to transfer, trimMark {}" + "greater than end of segment {}", trimMark, segment.getEnd()); return true; } final long segmentStart = Math.max(trimMark, segment.getStart()); final long segmentEnd = segment.getEnd() - 1; log.info("stateTransfer: Total address range to transfer: [{}-{}] to node {}", segmentStart, segmentEnd, endpoint); for (long pendingWritesBatch = segmentStart; pendingWritesBatch <= segmentEnd ; pendingWritesBatch += RECORDS_PER_LOG_FILE) { long pendingWritesBatchEnd = Math.min(segmentEnd, pendingWritesBatch + RECORDS_PER_LOG_FILE - 1); Iterable<List<Long>> chunks = getMissingEntriesChunks( layout, runtime, chunkSize, endpoint, pendingWritesBatch, pendingWritesBatchEnd); for (List<Long> chunk : chunks) { transferChunk(layout, runtime, endpoint, chunk); } } } catch (OverwriteException oe) { if (!oe.getOverWriteCause().equals(OverwriteCause.SAME_DATA)) { throw oe; } if (overwriteRetries.getAndIncrement() >= OVERWRITE_RETRIES) { throw new RetryExhaustedException("StateTransfer: Retries exhausted."); } throw new RetryNeededException(); } return true; }).setOptions(retry -> retry.setMaxRetryThreshold(MAX_RETRY_TIMEOUT)).run(); }

Target:
public static void transfer(Layout layout, @NonNull String endpoint, CorfuRuntime runtime, Layout.LayoutSegment segment) throws InterruptedException { int chunkSize = runtime.getParameters().getBulkReadSize(); final AtomicInteger overwriteRetries = new AtomicInteger(); IRetry.build(ExponentialBackoffRetry.class, RetryExhaustedException.class, () -> { try { long trimMark = setTrimOnNewLogUnit(layout, runtime, endpoint); if (trimMark > segment.getEnd()) { log.info("stateTransfer: Nothing to transfer, trimMark {}" + "greater than end of segment {}", trimMark, segment.getEnd()); return true; } final long segmentStart = Math.max(trimMark, segment.getStart()); final long segmentEnd = segment.getEnd() - 1; log.info("stateTransfer: Total address range to transfer: [{}-{}] to node {}", segmentStart, segmentEnd, endpoint); for (long chunkStart = segmentStart; chunkStart <= segmentEnd ; chunkStart += chunkSize) { long chunkEnd = Math.min(segmentEnd, chunkStart + chunkSize - 1); List<Long> chunk = getMissingEntriesChunk(layout, runtime, endpoint, chunkStart, chunkEnd); transferChunk(layout, runtime, endpoint, chunk); } } catch (OverwriteException oe) { log.error("stateTransfer: Overwrite Exception: retried: times", overwriteRetries.get()); if (overwriteRetries.getAndIncrement() >= OVERWRITE_RETRIES) { throw new RetryExhaustedException("StateTransfer: Retries exhausted."); } throw new RetryNeededException(); } return true; }).setOptions(retry -> { retry.setMaxRetryThreshold(MAX_RETRY_TIMEOUT); retry.setRandomPortion(RANDOM_FACTOR_BACKOFF); }).run(); }