Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion oak-doc/src/site/markdown/query/hybrid-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ For such use-cases, it's required that indexes are synchronous and results provi
### <a name="drawbacks-of-current-property-indexes"></a>Drawbacks of current property indexes
Oak has support for synchronous property indexes, which are used to meet above use-cases. However the current implementation has certain drawbacks:

* Slow reads over remote storage - The property indexes are stores as normal NodeState and hence reading them over remote storage like Mongo performs poorly (with Prefetch, OAK-9780, this is improved).
* Slow reads over remote storage - The property indexes are stores as normal NodeState and hence reading them over remote storage like Mongo performs poorly (with Prefetch, this is now improved).
* Storage overhead - The final storage overhead is larger, specially for remote storage where each NodeState is mapped to 1 document. (On the other hand, temporary disk usage for Lucene indexes might be higher than for node stores, due to write amplification with Lucene.)
---
### <a name="proposal"></a>Proposal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,13 @@
import javax.jcr.query.RowIterator;

import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.oak.commons.junit.TemporarySystemProperty;
import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
import org.apache.jackrabbit.oak.plugins.document.prefetch.CacheWarming;
import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
import org.apache.jackrabbit.oak.spi.mount.Mounts;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.ProvideSystemProperty;
import org.junit.contrib.java.lang.system.RestoreSystemProperties;
import org.junit.runners.Parameterized.Parameters;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -80,21 +75,10 @@ public static Collection<Object[]> data() {
private final String cacheWarmingLogger = CacheWarming.class.getName();


@Rule
public final ProvideSystemProperty updateSystemProperties
= new ProvideSystemProperty(DocumentNodeStore.SYS_PROP_PREFETCH, "true");

@Rule
public final RestoreSystemProperties restoreSystemProperties
= new RestoreSystemProperties();

public PrefetchTest(NodeStoreKind root, NodeStoreKind mounts) {
super(root, mounts);
}

@Rule
public TemporarySystemProperty temporarySystemProperty = new TemporarySystemProperty();

@Before
public void loggingAppenderStart() {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
Expand Down
5 changes: 1 addition & 4 deletions oak-store-document/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,7 @@ every 10 `create` calls.
## Prefetch

`PrefetchDispatcher` pre-fetches visible external changes in a background thread before delivery
to local observers, hiding MongoDB/RDB read latency during observer dispatch. Controlled by
feature toggle `FT_PREFETCH_OAK-9780` (disabled by default); wired via
`DocumentNodeStoreBuilder.setPrefetchFeature()`.
to local observers, hiding MongoDB/RDB read latency during observer dispatch.

## Persistent Cache

Expand Down Expand Up @@ -354,7 +352,6 @@ Registered in `DocumentNodeStoreService`, wired into `DocumentNodeStoreBuilder`.

| Toggle name | Builder method | Purpose |
|---|---|---|
| `FT_PREFETCH_OAK-9780` | `setPrefetchFeature` | Enable async pre-fetching of external changes |
| `FT_THROTTLING_OAK-9909` | `setDocStoreThrottlingFeature` | Enable write throttling on MongoDB |
| `FT_DISABLE_THROTTLING_OAK-12119` | `setDocStoreDisableThrottlingFeature` | Runtime kill-switch to disable throttling |
| `FT_NOCOCLEANUP_OAK-10660` | `setNoChildOrderCleanupFeature` | Disable child-order property cleanup |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,6 @@
static final long DEFAULT_MAX_SERVER_TIME_DIFFERENCE = 2000L;
private final long maxTimeDiffMillis = SystemPropertySupplier.create("oak.documentMK.maxServerTimeDiffMillis", DEFAULT_MAX_SERVER_TIME_DIFFERENCE).loggingTo(LOG).get();

public static final String SYS_PROP_PREFETCH = "oak.documentstore.prefetch";
private final boolean prefetchEnabled = SystemPropertySupplier.create(SYS_PROP_PREFETCH, false).loggingTo(LOG).get();

/**
* The document store without potentially lease checking wrapper.
*/
Expand Down Expand Up @@ -559,8 +556,6 @@

private final Predicate<Path> nodeCachePredicate;

private final Feature prefetchFeature;

private final Feature cancelInvalidationFeature;

private final Feature noChildOrderCleanupFeature;
Expand Down Expand Up @@ -640,7 +635,6 @@
leaseUpdateThread.start();
}

this.prefetchFeature = builder.getPrefetchFeature();
this.cancelInvalidationFeature = builder.getCancelInvalidationFeature();
this.noChildOrderCleanupFeature = builder.getNoChildOrderCleanupFeature();
this.avoidMergeLock = isAvoidMergeLockEnabled(builder);
Expand Down Expand Up @@ -1657,7 +1651,7 @@
* @param changed the list of changed child nodes
*
*/
void applyChanges(RevisionVector before, RevisionVector after,

Check warning on line 1654 in oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 87 to 64, Complexity from 21 to 14, Nesting Level from 4 to 2, Number of Variables from 31 to 6.

See more on https://sonarcloud.io/project/issues?id=org.apache.jackrabbit%3Ajackrabbit-oak&issues=AZ6YG7C7WneQtRL6TOFR&open=AZ6YG7C7WneQtRL6TOFR&pullRequest=2934
Revision rev, Path path,
boolean isNew, List<Path> added,
List<Path> removed, List<Path> changed) {
Expand Down Expand Up @@ -4046,18 +4040,11 @@
@Override
public void prefetch(java.util.Collection<String> paths, NodeState rootState) {
if (paths != null
&& rootState instanceof DocumentNodeState
&& isPrefetchEnabled()) {
cacheWarming.prefetch(paths, (DocumentNodeState) rootState);
&& rootState instanceof DocumentNodeState documentNodeState) {
cacheWarming.prefetch(paths, documentNodeState);
}
}

private boolean isPrefetchEnabled() {
// feature can be enabled with system property or feature toggle
return prefetchEnabled
|| (prefetchFeature != null && prefetchFeature.isEnabled());
}

/**
* Configures the performance logger with the specified info log interval.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import org.apache.jackrabbit.oak.cache.api.Cache;
import org.apache.jackrabbit.oak.cache.api.CacheBuilder;
import org.apache.jackrabbit.oak.cache.api.CacheStatsAdapter;
import org.apache.jackrabbit.oak.cache.api.EvictionCause;
import org.apache.jackrabbit.oak.cache.api.Weigher;
import org.apache.jackrabbit.oak.cache.AbstractCacheStats;
import org.apache.jackrabbit.oak.cache.CacheValue;
Expand Down Expand Up @@ -128,7 +127,6 @@ public class DocumentNodeStoreBuilder<T extends DocumentNodeStoreBuilder<T>> {
private String loggingPrefix;
private LeaseCheckMode leaseCheck = ClusterNodeInfo.DEFAULT_LEASE_CHECK_MODE; // OAK-2739 is enabled by default also for non-osgi
private boolean isReadOnlyMode = false;
private Feature prefetchFeature;
private Feature docStoreThrottlingFeature;
private Feature noChildOrderCleanupFeature;
private Feature cancelInvalidationFeature;
Expand Down Expand Up @@ -466,16 +464,6 @@ public boolean getReadOnlyMode() {
return isReadOnlyMode;
}

public T setPrefetchFeature(@Nullable Feature prefetch) {
this.prefetchFeature = prefetch;
return thisBuilder();
}

@Nullable
public Feature getPrefetchFeature() {
return prefetchFeature;
}

public T setDocStoreThrottlingFeature(@Nullable Feature docStoreThrottling) {
this.docStoreThrottlingFeature = docStoreThrottling;
return thisBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,6 @@ public class DocumentNodeStoreService {
*/
static final long DEFAULT_BLOB_SNAPSHOT_INTERVAL = 12 * 60 * 60;

/**
* Feature toggle name to enable prefetch operation in DocumentStore
*/
private static final String FT_NAME_PREFETCH = "FT_PREFETCH_OAK-9780";

/**
* Feature toggle name to enable document store throttling for Mongo Document Store
*/
Expand Down Expand Up @@ -276,7 +271,6 @@ static DocumentStoreType fromString(String type) {
private DocumentNodeStore nodeStore;
private ObserverTracker observerTracker;
private JournalPropertyHandlerFactory journalPropertyHandlerFactory = new JournalPropertyHandlerFactory();
private Feature prefetchFeature;
private Feature docStoreThrottlingFeature;
private Feature noChildOrderCleanupFeature;
private Feature cancelInvalidationFeature;
Expand Down Expand Up @@ -316,7 +310,6 @@ protected void activate(ComponentContext context, Configuration config) throws E
executor.start(whiteboard);
customBlobStore = this.config.customBlobStore();
documentStoreType = DocumentStoreType.fromString(this.config.documentStoreType());
prefetchFeature = Feature.newFeature(FT_NAME_PREFETCH, whiteboard);
docStoreThrottlingFeature = Feature.newFeature(FT_NAME_DOC_STORE_THROTTLING, whiteboard);
noChildOrderCleanupFeature = Feature.newFeature(FT_NAME_DOC_STORE_NOCOCLEANUP, whiteboard);
cancelInvalidationFeature = Feature.newFeature(FT_NAME_CANCEL_INVALIDATION, whiteboard);
Expand Down Expand Up @@ -554,7 +547,6 @@ private void configureBuilder(DocumentNodeStoreBuilder<?> builder) {
setBundlingDisabled(config.bundlingDisabled()).
setJournalPropertyHandlerFactory(journalPropertyHandlerFactory).
setLeaseCheckMode(ClusterNodeInfo.DEFAULT_LEASE_CHECK_DISABLED ? LeaseCheckMode.DISABLED : LeaseCheckMode.valueOf(config.leaseCheckMode())).
setPrefetchFeature(prefetchFeature).
setDocStoreThrottlingFeature(docStoreThrottlingFeature).
setNoChildOrderCleanupFeature(noChildOrderCleanupFeature).
setCancelInvalidationFeature(cancelInvalidationFeature).
Expand Down Expand Up @@ -720,7 +712,7 @@ protected void deactivate() {
journalPropertyHandlerFactory.stop();
}

closeFeatures(prefetchFeature, docStoreThrottlingFeature, cancelInvalidationFeature, docStoreFullGCFeature,
closeFeatures(docStoreThrottlingFeature, cancelInvalidationFeature, docStoreFullGCFeature,
docStoreEmbeddedVerificationFeature, prevNoPropCacheFeature, docStoreAvoidMergeLockFeature);

unregisterNodeStore();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import org.apache.jackrabbit.oak.plugins.document.util.Utils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

Expand All @@ -53,7 +52,6 @@ public class ConcurrentPrefetchAndUpdateIT extends AbstractMongoConnectionTest {
@Before
@Override
public void setUpConnection() throws Exception {
System.setProperty(DocumentNodeStore.SYS_PROP_PREFETCH, String.valueOf(true));
mongoConnection = connectionFactory.getConnection();
assertNotNull(mongoConnection);
MongoDatabase db = mongoConnection.getDatabase();
Expand All @@ -64,11 +62,6 @@ public void setUpConnection() throws Exception {
mk = builder.setDocumentStore(store).open();
}

@After
public void clearSystemProperty() {
System.clearProperty(DocumentNodeStore.SYS_PROP_PREFETCH);
}

@Test
public void cacheConsistency() throws Exception {
Revision r = newRevision();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.oak.plugins.document.prefetch;

import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore.SYS_PROP_PREFETCH;
import static org.apache.jackrabbit.oak.plugins.document.util.Utils.getIdFromPath;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
Expand All @@ -34,7 +33,6 @@

import com.mongodb.MongoTimeoutException;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.commons.junit.TemporarySystemProperty;
import org.apache.jackrabbit.oak.commons.time.Stopwatch;
import org.apache.jackrabbit.oak.plugins.document.Collection;
import org.apache.jackrabbit.oak.plugins.document.CountingDocumentStore;
Expand All @@ -55,17 +53,13 @@
import org.apache.jackrabbit.oak.stats.Clock;
import org.jetbrains.annotations.Nullable;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CacheWarmingTest {

@Rule
public TemporarySystemProperty systemProperties = new TemporarySystemProperty();

@Rule
public DocumentMKBuilderProvider builderProvider = new DocumentMKBuilderProvider();

Expand All @@ -78,11 +72,6 @@ public class CacheWarmingTest {

private CountingMongoDatabase db;

@Before
public void enablePrefetch() {
System.setProperty(SYS_PROP_PREFETCH, "true");
}

@AfterClass

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After dropping sys-prop setup, consider adding a test that calls DocumentNodeStore.prefetch() (not CacheWarming directly) with default builder setup and asserts cache warming — that would lock in the always-on store path this PR introduces.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand; is this about adding a test that we should have had before?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public static void cleanUp() {
MongoUtils.dropCollections(MongoUtils.DB);
Expand Down
Loading