Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java (revision 1615896) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java (working copy) @@ -17,6 +17,7 @@ package org.apache.jackrabbit.oak.plugins.segment; import static com.google.common.base.Preconditions.checkState; +import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toLong; import static org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.registerMBean; import java.io.Closeable; @@ -24,6 +25,8 @@ import java.io.IOException; import java.util.Dictionary; import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.TimeUnit; import org.apache.commons.io.FilenameUtils; import org.apache.felix.scr.annotations.Activate; @@ -30,6 +33,7 @@ import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.ConfigurationPolicy; import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Modified; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; @@ -106,6 +110,13 @@ private WhiteboardExecutor executor; private boolean customBlobStore; + /** + * Blob modified before this time duration would be considered for Blob GC + */ + private static final long DEFAULT_BLOB_GC_MAX_AGE = TimeUnit.HOURS.toSeconds(24); + public static final String PROP_BLOB_GC_MAX_AGE = "blobGcMaxAgeInSecs"; + private long blobGcMaxAgeInSecs = DEFAULT_BLOB_GC_MAX_AGE; + @Override protected synchronized SegmentNodeStore getNodeStore() { checkState(delegate != null, "service must be activated when used"); @@ -113,9 +124,10 @@ } @Activate - private void activate(ComponentContext context) throws IOException { + private void activate(ComponentContext context, Map config) throws IOException { this.context = context; this.customBlobStore = Boolean.parseBoolean(lookup(context, CUSTOM_BLOB_STORE)); + modified(config); if(blobStore == null && customBlobStore){ log.info("BlobStore use enabled. SegmentNodeStore would be initialized when BlobStore would be available"); @@ -194,7 +206,7 @@ MarkSweepGarbageCollector gc = new MarkSweepGarbageCollector( new SegmentBlobReferenceRetriever(store.getTracker()), (GarbageCollectableBlobStore) store.getBlobStore(), - executor); + executor, blobGcMaxAgeInSecs); gc.collectGarbage(); } }; @@ -216,6 +228,14 @@ return null; } + /** + * At runtime DocumentNodeStore only pickup modification of certain properties + */ + @Modified + protected void modified(Map config){ + blobGcMaxAgeInSecs = toLong(config.get(PROP_BLOB_GC_MAX_AGE), DEFAULT_BLOB_GC_MAX_AGE); + } + @Deactivate public synchronized void deactivate() { unregisterNodeStore();