Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java (revision 1772838) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java (working copy) @@ -18,7 +18,6 @@ */ package org.apache.jackrabbit.oak.segment; -import static com.google.common.base.Preconditions.checkState; import static java.util.Collections.emptyMap; import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toBoolean; import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toInteger; @@ -25,6 +24,7 @@ import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toLong; import static org.apache.jackrabbit.oak.osgi.OsgiUtil.lookupConfigurationThenFramework; import static org.apache.jackrabbit.oak.segment.SegmentNotFoundExceptionListener.IGNORE_SNFE; +import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.DISABLE_ESTIMATION_DEFAULT; import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.FORCE_TIMEOUT_DEFAULT; import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.GC_PROGRESS_LOG_DEFAULT; import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.MEMORY_THRESHOLD_DEFAULT; @@ -32,13 +32,11 @@ import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.RETAINED_GENERATIONS_DEFAULT; import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.RETRY_COUNT_DEFAULT; import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.SIZE_DELTA_ESTIMATION_DEFAULT; -import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.DISABLE_ESTIMATION_DEFAULT; import static org.apache.jackrabbit.oak.segment.file.FileStoreBuilder.fileStoreBuilder; import static org.apache.jackrabbit.oak.spi.blob.osgi.SplitBlobStoreService.ONLY_STANDALONE_TARGET; import static org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.registerMBean; import java.io.ByteArrayInputStream; -import java.io.Closeable; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -48,6 +46,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; +import com.google.common.base.Strings; +import com.google.common.base.Supplier; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.ConfigurationPolicy; @@ -85,12 +85,9 @@ import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException; import org.apache.jackrabbit.oak.spi.blob.BlobStore; import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore; -import org.apache.jackrabbit.oak.spi.commit.Observable; -import org.apache.jackrabbit.oak.spi.commit.Observer; import org.apache.jackrabbit.oak.spi.gc.GCMonitor; import org.apache.jackrabbit.oak.spi.gc.GCMonitorTracker; import org.apache.jackrabbit.oak.spi.state.NodeStore; -import org.apache.jackrabbit.oak.spi.state.ProxyNodeStore; import org.apache.jackrabbit.oak.spi.state.RevisionGC; import org.apache.jackrabbit.oak.spi.state.RevisionGCMBean; import org.apache.jackrabbit.oak.spi.whiteboard.CompositeRegistration; @@ -105,9 +102,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Strings; -import com.google.common.base.Supplier; - /** * An OSGi wrapper for the segment node store. */ @@ -120,9 +114,23 @@ "should be done via file system based config file and this view should ONLY be used to determine which " + "options are supported" ) -public class SegmentNodeStoreService extends ProxyNodeStore - implements Observable, SegmentStoreProvider { +public class SegmentNodeStoreService { + private static class DefaultSegmentStoreProvider implements SegmentStoreProvider { + + private final SegmentStore segmentStore; + + DefaultSegmentStoreProvider(SegmentStore segmentStore) { + this.segmentStore = segmentStore; + } + + @Override + public SegmentStore getSegmentStore() { + return segmentStore; + } + + } + public static final String NAME = "name"; @Property( @@ -325,12 +333,6 @@ ) public static final String PROP_BLOB_SNAPSHOT_INTERVAL = "blobTrackSnapshotIntervalInSecs"; - @Override - protected SegmentNodeStore getNodeStore() { - checkState(segmentNodeStore != null, "service must be activated when used"); - return segmentNodeStore; - } - @Activate public void activate(ComponentContext context) throws IOException { this.context = context; @@ -356,21 +358,6 @@ @Deactivate public void deactivate() { unregisterNodeStore(); - - synchronized (this) { - if (observerTracker != null) { - observerTracker.stop(); - } - if (gcMonitor != null) { - gcMonitor.stop(); - } - segmentNodeStore = null; - - if (store != null) { - store.close(); - store = null; - } - } } private synchronized void registerNodeStore() throws IOException { @@ -383,7 +370,7 @@ Dictionary props = new Hashtable(); props.put(Constants.SERVICE_PID, SegmentNodeStore.class.getName()); props.put("oak.nodestore.description", new String[] {"nodeStoreType=segment"}); - storeRegistration = context.getBundleContext().registerService(NodeStore.class.getName(), this, props); + storeRegistration = context.getBundleContext().registerService(NodeStore.class.getName(), segmentNodeStore, props); } private boolean registerSegmentStore() throws IOException { @@ -646,7 +633,11 @@ // Register a factory service to expose the FileStore - providerRegistration = context.getBundleContext().registerService(SegmentStoreProvider.class.getName(), this, null); + providerRegistration = context.getBundleContext().registerService( + SegmentStoreProvider.class.getName(), + new DefaultSegmentStoreProvider(store), + null + ); return true; } @@ -676,19 +667,49 @@ } private void unregisterNodeStore() { - new CompositeRegistration(registrations).unregister(); + CompositeRegistration registrations; + ServiceRegistration providerRegistration; + ServiceRegistration storeRegistration; + WhiteboardExecutor executor; + ObserverTracker observerTracker; + GCMonitorTracker gcMonitor; + FileStore store; + synchronized (this) { + registrations = new CompositeRegistration(new ArrayList<>(this.registrations)); + this.registrations.clear(); + providerRegistration = this.providerRegistration; + this.providerRegistration = null; + storeRegistration = this.storeRegistration; + this.storeRegistration = null; + executor = this.executor; + this.executor = null; + observerTracker = this.observerTracker; + this.observerTracker = null; + gcMonitor = this.gcMonitor; + this.gcMonitor = null; + store = this.store; + this.store = null; + this.segmentNodeStore = null; + } + registrations.unregister(); if (providerRegistration != null) { providerRegistration.unregister(); - providerRegistration = null; } if (storeRegistration != null) { storeRegistration.unregister(); - storeRegistration = null; } if (executor != null) { executor.stop(); - executor = null; } + if (observerTracker != null) { + observerTracker.stop(); + } + if (gcMonitor != null) { + gcMonitor.stop(); + } + if (store != null) { + store.close(); + } } private File getBaseDirectory() { @@ -779,22 +800,6 @@ return lookupConfigurationThenFramework(context, name); } - /** - * needed for situations where you have to unwrap the - * SegmentNodeStoreService, to get the SegmentStore, like the failover - */ - @Override - public SegmentStore getSegmentStore() { - return store; - } - - //------------------------------------------------------------< Observable >--- - - @Override - public Closeable addObserver(Observer observer) { - return getNodeStore().addObserver(observer); - } - //------------------------------------------------------------< Object >-- @Override