Skip to content

Commit 3412427

Browse files
authored
[improve][broker] Expose interface for the replicator in ManagedLedger instead of cast the class (#26298)
1 parent a5e7937 commit 3412427

4 files changed

Lines changed: 56 additions & 7 deletions

File tree

managed-ledger/src/main/java/org/apache/bookkeeper/mledger/ManagedCursor.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
*/
1919
package org.apache.bookkeeper.mledger;
2020

21+
import static org.apache.pulsar.common.util.Runnables.catchingAndLoggingThrowables;
2122
import com.google.common.collect.Range;
2223
import java.util.List;
2324
import java.util.Map;
2425
import java.util.Optional;
2526
import java.util.Set;
2627
import java.util.concurrent.CompletableFuture;
28+
import java.util.concurrent.TimeUnit;
2729
import java.util.function.Predicate;
2830
import org.apache.bookkeeper.common.annotation.InterfaceAudience;
2931
import org.apache.bookkeeper.common.annotation.InterfaceStability;
@@ -879,6 +881,20 @@ default void skipNonRecoverableLedger(long ledgerId){}
879881
*/
880882
ManagedLedger getManagedLedger();
881883

884+
/**
885+
* Schedule a continuation of a read callback.
886+
*
887+
* <p>Implementations that deliver read callbacks on a dedicated execution context should override this method
888+
* to run the continuation on that same execution context.
889+
*
890+
* @param callback the callback continuation
891+
* @param delay the delay before executing the continuation
892+
* @param unit the time unit of the delay
893+
*/
894+
default void scheduleReadCallback(Runnable callback, long delay, TimeUnit unit) {
895+
CompletableFuture.delayedExecutor(delay, unit).execute(catchingAndLoggingThrowables(callback));
896+
}
897+
882898
/**
883899
* Get last individual deleted range.
884900
* @return range

managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/ManagedCursorImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import static org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl.DEFAULT_LEDGER_DELETE_RETRIES;
2727
import static org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl.createManagedLedgerException;
2828
import static org.apache.bookkeeper.mledger.util.Errors.isNoSuchLedgerExistsException;
29+
import static org.apache.pulsar.common.util.Runnables.catchingAndLoggingThrowables;
2930
import com.google.common.annotations.VisibleForTesting;
3031
import com.google.common.base.MoreObjects;
3132
import com.google.common.collect.Collections2;
@@ -4021,6 +4022,12 @@ public ManagedLedger getManagedLedger() {
40214022
return this.ledger;
40224023
}
40234024

4025+
@Override
4026+
public void scheduleReadCallback(Runnable callback, long delay, TimeUnit unit) {
4027+
ledger.getScheduledExecutor().schedule(
4028+
catchingAndLoggingThrowables(() -> ledger.getExecutor().execute(callback)), delay, unit);
4029+
}
4030+
40244031
@Override
40254032
public Range<Position> getLastIndividualDeletedRange() {
40264033
lock.readLock().lock();

managed-ledger/src/test/java/org/apache/bookkeeper/mledger/impl/ManagedCursorTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
import org.apache.bookkeeper.client.api.LedgerEntries;
101101
import org.apache.bookkeeper.client.api.ReadHandle;
102102
import org.apache.bookkeeper.common.util.OrderedExecutor;
103+
import org.apache.bookkeeper.common.util.OrderedScheduler;
103104
import org.apache.bookkeeper.mledger.AsyncCallbacks;
104105
import org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback;
105106
import org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCallback;
@@ -138,6 +139,7 @@
138139
import org.apache.pulsar.metadata.api.extended.SessionEvent;
139140
import org.apache.pulsar.metadata.impl.FaultInjectionMetadataStore;
140141
import org.awaitility.Awaitility;
142+
import org.mockito.ArgumentCaptor;
141143
import org.mockito.MockedStatic;
142144
import org.mockito.Mockito;
143145
import org.mockito.invocation.InvocationOnMock;
@@ -4198,6 +4200,36 @@ public void testEstimatedUnackedSizeWhenCursorCaughtUpWithLastPosition() throws
41984200
assertEquals(cursor.getEstimatedSizeSinceMarkDeletePosition(), 0);
41994201
}
42004202

4203+
@Test
4204+
public void testScheduleReadCallbackUsesManagedLedgerExecutionContext() {
4205+
ManagedLedgerImpl ledger = mock(ManagedLedgerImpl.class);
4206+
when(ledger.getConfig()).thenReturn(new ManagedLedgerConfig());
4207+
when(ledger.getLogger()).thenReturn(log);
4208+
OrderedScheduler scheduledExecutor = mock(OrderedScheduler.class);
4209+
ExecutorService executor = mock(ExecutorService.class);
4210+
when(ledger.getScheduledExecutor()).thenReturn(scheduledExecutor);
4211+
when(ledger.getExecutor()).thenReturn(executor);
4212+
ManagedCursorImpl cursor = new ManagedCursorImpl(mock(BookKeeper.class), ledger, "c1");
4213+
Runnable callback = mock(Runnable.class);
4214+
ArgumentCaptor<Runnable> scheduledTask = ArgumentCaptor.forClass(Runnable.class);
4215+
4216+
cursor.scheduleReadCallback(callback, 100, TimeUnit.MILLISECONDS);
4217+
4218+
verify(scheduledExecutor).schedule(scheduledTask.capture(), eq(100L), eq(TimeUnit.MILLISECONDS));
4219+
scheduledTask.getValue().run();
4220+
verify(executor).execute(callback);
4221+
}
4222+
4223+
@Test
4224+
public void testDefaultScheduleReadCallback() throws InterruptedException {
4225+
ManagedCursor cursor = mock(ManagedCursor.class, Mockito.CALLS_REAL_METHODS);
4226+
CountDownLatch callbackExecuted = new CountDownLatch(1);
4227+
4228+
cursor.scheduleReadCallback(callbackExecuted::countDown, 0, TimeUnit.MILLISECONDS);
4229+
4230+
assertTrue(callbackExecuted.await(5, TimeUnit.SECONDS));
4231+
}
4232+
42014233
@Test
42024234
public void testEstimatedUnackedSizeWhenCursorAdvancedToEmptyCurrentLedger() {
42034235
ManagedLedgerImpl ledger = mock(ManagedLedgerImpl.class);

pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentReplicator.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
import org.apache.bookkeeper.mledger.ManagedLedgerException.CursorAlreadyClosedException;
5454
import org.apache.bookkeeper.mledger.ManagedLedgerException.TooManyRequestsException;
5555
import org.apache.bookkeeper.mledger.Position;
56-
import org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl;
5756
import org.apache.commons.collections4.CollectionUtils;
5857
import org.apache.commons.lang3.tuple.Pair;
5958
import org.apache.pulsar.broker.PulsarServerException;
@@ -402,7 +401,6 @@ public void readEntriesComplete(List<Entry> entries, Object ctx) {
402401
}
403402

404403
// Retry to trigger read completes if it is not started.
405-
ManagedLedgerImpl ml = (ManagedLedgerImpl) cursor.getManagedLedger();
406404
Runnable retryReplicateEntries = () -> {
407405
long estimatedTimeStampProducerConnected = this.estimatedTimeStampProducerConnected;
408406
long delayMillis;
@@ -411,11 +409,7 @@ public void readEntriesComplete(List<Entry> entries, Object ctx) {
411409
} else {
412410
delayMillis = 100;
413411
}
414-
ml.getScheduledExecutor().schedule(() -> {
415-
ml.getExecutor().execute(() -> {
416-
readEntriesComplete(entries, ctx);
417-
});
418-
}, delayMillis, TimeUnit.MILLISECONDS);
412+
cursor.scheduleReadCallback(() -> readEntriesComplete(entries, ctx), delayMillis, TimeUnit.MILLISECONDS);
419413
};
420414

421415
// Retry.

0 commit comments

Comments
 (0)