diff --git oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java index df5c52d7eb..edfdac97f8 100644 --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java @@ -62,6 +62,15 @@ import org.slf4j.LoggerFactory; */ public class SegmentNodeStore implements NodeStore, Observable { + private static final Closeable NOOP = new Closeable() { + + @Override + public void close() { + // This method was intentionally left blank. + } + + }; + public static class SegmentNodeStoreBuilder { private static final Logger LOG = LoggerFactory.getLogger(SegmentNodeStoreBuilder.class); @@ -177,7 +186,11 @@ public class SegmentNodeStore implements NodeStore, Observable { @Override public Closeable addObserver(Observer observer) { - return scheduler.addObserver(observer); + if (scheduler instanceof Observable) { + return ((Observable) scheduler).addObserver(observer); + } + + return NOOP; } @Override @Nonnull diff --git oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/scheduler/LockBasedScheduler.java oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/scheduler/LockBasedScheduler.java index 1d8400e00f..96fee2e181 100644 --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/scheduler/LockBasedScheduler.java +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/scheduler/LockBasedScheduler.java @@ -42,6 +42,7 @@ import org.apache.jackrabbit.oak.segment.SegmentOverflowException; import org.apache.jackrabbit.oak.segment.SegmentReader; import org.apache.jackrabbit.oak.spi.commit.ChangeDispatcher; import org.apache.jackrabbit.oak.spi.commit.CommitInfo; +import org.apache.jackrabbit.oak.spi.commit.Observable; import org.apache.jackrabbit.oak.spi.commit.Observer; import org.apache.jackrabbit.oak.spi.state.NodeBuilder; import org.apache.jackrabbit.oak.spi.state.NodeState; @@ -50,14 +51,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LockBasedScheduler implements Scheduler { - private static final Closeable NOOP = new Closeable() { - - @Override - public void close() { - // This method was intentionally left blank. - } - - }; public static class LockBasedSchedulerBuilder { @Nonnull @@ -97,7 +90,11 @@ public class LockBasedScheduler implements Scheduler { @Nonnull public LockBasedScheduler build() { - return new LockBasedScheduler(this); + if (dispatchChanges) { + return new ObservableLockBasedScheduler(this); + } else { + return new LockBasedScheduler(this); + } } } @@ -135,9 +132,7 @@ public class LockBasedScheduler implements Scheduler { @Nonnull private final Revisions revisions; - private final AtomicReference head; - - private final ChangeDispatcher changeDispatcher; + protected final AtomicReference head; private final SegmentNodeStoreStats stats; @@ -149,24 +144,11 @@ public class LockBasedScheduler implements Scheduler { this.reader = builder.reader; this.revisions = builder.revisions; this.head = new AtomicReference(reader.readHeadState(revisions)); - if (builder.dispatchChanges) { - this.changeDispatcher = new ChangeDispatcher(head.get().getChildNode(ROOT)); - } else { - this.changeDispatcher = null; - } this.stats = new SegmentNodeStoreStats(builder.statsProvider); } @Override - public Closeable addObserver(Observer observer) { - if (changeDispatcher != null) { - return changeDispatcher.addObserver(observer); - } - return NOOP; - } - - @Override public NodeState getHeadNodeState() { if (commitSemaphore.tryAcquire()) { try { @@ -195,10 +177,8 @@ public class LockBasedScheduler implements Scheduler { } } - private void contentChanged(NodeState root, CommitInfo info) { - if (changeDispatcher != null) { - changeDispatcher.contentChanged(root, info); - } + protected void contentChanged(NodeState root, CommitInfo info) { + // do nothing without a change dispatcher } @Override @@ -319,6 +299,25 @@ public class LockBasedScheduler implements Scheduler { return false; } + private static class ObservableLockBasedScheduler extends LockBasedScheduler implements Observable { + private final ChangeDispatcher changeDispatcher; + + public ObservableLockBasedScheduler(LockBasedSchedulerBuilder builder) { + super(builder); + this.changeDispatcher = new ChangeDispatcher(head.get().getChildNode(ROOT)); + } + + @Override + protected void contentChanged(NodeState root, CommitInfo info) { + changeDispatcher.contentChanged(root, info); + } + + @Override + public Closeable addObserver(Observer observer) { + return changeDispatcher.addObserver(observer); + } + } + private final class CPCreator implements Callable { private final String name; diff --git oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/scheduler/Scheduler.java oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/scheduler/Scheduler.java index 63ae20b5a7..039efad8e7 100644 --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/scheduler/Scheduler.java +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/scheduler/Scheduler.java @@ -17,13 +17,11 @@ package org.apache.jackrabbit.oak.segment.scheduler; -import java.io.Closeable; import java.util.Map; import javax.annotation.Nonnull; import org.apache.jackrabbit.oak.api.CommitFailedException; -import org.apache.jackrabbit.oak.spi.commit.Observer; import org.apache.jackrabbit.oak.spi.state.NodeState; /** @@ -90,13 +88,4 @@ public interface Scheduler { * @return the latest state. */ NodeState getHeadNodeState(); - - /** - * Register a new {@code Observer}. Clients need to call {@link Closeable#close()} - * to stop getting notifications on the registered observer and to free up any resources - * associated with the registration. - * - * @return a {@code Closeable} instance. - */ - Closeable addObserver(Observer observer); } \ No newline at end of file