use of org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore in project jackrabbit-oak by apache.
the class AsyncIndexUpdateTest method testReindexMissingProvider_NonRoot.
@Test
public void testReindexMissingProvider_NonRoot() throws Exception {
MemoryNodeStore store = new MemoryNodeStore();
IndexEditorProvider provider = new PropertyIndexEditorProvider();
NodeBuilder builder = store.getRoot().builder();
String missingAsyncName = "missing-async";
createIndexDefinition(builder.child("subNodeIndex").child(INDEX_DEFINITIONS_NAME), "rootIndex2", true, false, ImmutableSet.of("foo"), null).setProperty(ASYNC_PROPERTY_NAME, missingAsyncName);
builder.child("subNodeIndex").child("testRoot").setProperty("foo", "abc");
store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
AsyncIndexUpdate async = new AsyncIndexUpdate(missingAsyncName, store, provider);
//first run, creates a checkpoint and a ref to it as the last indexed state
async.run();
assertFalse(async.isFailing());
assertTrue("Expecting one checkpoint", store.listCheckpoints().size() == 1);
String firstCp = store.listCheckpoints().iterator().next();
assertEquals(firstCp, store.getRoot().getChildNode(ASYNC).getString(missingAsyncName));
builder = store.getRoot().builder();
builder.child("subNodeIndex").child("testRoot2").setProperty("foo", "abc");
store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
// second run, simulate an index going away
provider = CompositeIndexEditorProvider.compose(new ArrayList<IndexEditorProvider>());
async = new AsyncIndexUpdate(missingAsyncName, store, provider);
async.run();
assertTrue(async.isFailing());
// don't set reindex=true but skip the update
NodeState rootIndex2 = NodeStateUtils.getNode(store.getRoot(), "/subNodeIndex/oak:index/rootIndex2");
assertTrue(rootIndex2.exists());
PropertyState reindex2 = rootIndex2.getProperty(REINDEX_PROPERTY_NAME);
assertTrue(reindex2 == null || !reindex2.getValue(Type.BOOLEAN));
assertTrue("Expecting one checkpoint", store.listCheckpoints().size() == 1);
String secondCp = store.listCheckpoints().iterator().next();
assertTrue("Store should not create a new checkpoint", secondCp.equals(firstCp));
assertEquals(firstCp, store.getRoot().getChildNode(ASYNC).getString(missingAsyncName));
}
use of org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore in project jackrabbit-oak by apache.
the class AsyncIndexUpdateTest method checkpointLostEventualConsistent.
@Test
public void checkpointLostEventualConsistent() throws Exception {
MemoryNodeStore store = new MemoryNodeStore();
final List<NodeState> rootStates = Lists.newArrayList();
store.addObserver(new Observer() {
@Override
public void contentChanged(@Nonnull NodeState root, @Nullable CommitInfo info) {
rootStates.add(root);
}
});
IndexEditorProvider provider = new PropertyIndexEditorProvider();
NodeBuilder builder = store.getRoot().builder();
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "rootIndex", true, false, ImmutableSet.of("foo"), null).setProperty(ASYNC_PROPERTY_NAME, "async");
builder.child("testRoot").setProperty("foo", "abc");
store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
AsyncIndexUpdate pre = new AsyncIndexUpdate("async", store, provider);
pre.run();
//Create another commit so that we have two checkpoints
builder = store.getRoot().builder();
builder.child("testRoot2").setProperty("foo", "abc");
store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
pre.run();
pre.close();
//Look for the nodestate just before the final merge in AsyncIndexUpdate
//i.e. where older checkpoint was still referred and which has been "released"
//post last run
Collections.reverse(rootStates);
final AtomicReference<NodeState> oldRootState = new AtomicReference<NodeState>();
for (NodeState ns : rootStates) {
NodeState async = ns.getChildNode(ASYNC);
String checkpointName = async.getString("async");
if (store.retrieve(checkpointName) == null && async.getProperty(AsyncIndexUpdate.leasify("async")) == null) {
oldRootState.set(ns);
break;
}
}
assertNotNull(oldRootState.get());
final AtomicBoolean intiLeaseCalled = new AtomicBoolean(false);
//Here for the call to read existing NodeState we would return the old
//"stale" state where we have a stale checkpoint
store = new MemoryNodeStore(store.getRoot()) {
@Override
public NodeState getRoot() {
//Keep returning stale view untill initlease is not invoked
if (!intiLeaseCalled.get()) {
return oldRootState.get();
}
return super.getRoot();
}
};
final AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, provider) {
@Override
protected AsyncUpdateCallback newAsyncUpdateCallback(NodeStore store, String name, long leaseTimeOut, String beforeCheckpoint, AsyncIndexStats indexStats, AtomicBoolean stopFlag) {
return new AsyncUpdateCallback(store, name, leaseTimeOut, beforeCheckpoint, indexStats, stopFlag) {
@Override
protected void initLease() throws CommitFailedException {
intiLeaseCalled.set(true);
super.initLease();
}
};
}
};
async.run();
//This run should fail
assertTrue(async.getIndexStats().isFailing());
async.close();
}
use of org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore in project jackrabbit-oak by apache.
the class AsyncIndexUpdateTest method abortedRun.
@Test
public void abortedRun() throws Exception {
NodeStore store = new MemoryNodeStore();
IndexEditorProvider provider = new PropertyIndexEditorProvider();
NodeBuilder builder = store.getRoot().builder();
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "rootIndex", true, false, ImmutableSet.of("foo"), null).setProperty(ASYNC_PROPERTY_NAME, "async");
builder.child("testRoot").setProperty("foo", "abc");
store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
final Semaphore asyncLock = new Semaphore(1);
final AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, provider) {
@Override
protected AsyncUpdateCallback newAsyncUpdateCallback(NodeStore store, String name, long leaseTimeOut, String beforeCheckpoint, AsyncIndexStats indexStats, AtomicBoolean stopFlag) {
return new AsyncUpdateCallback(store, name, leaseTimeOut, beforeCheckpoint, indexStats, stopFlag) {
@Override
public void indexUpdate() throws CommitFailedException {
try {
asyncLock.acquire();
} catch (InterruptedException ignore) {
}
try {
super.indexUpdate();
} finally {
asyncLock.release();
}
}
};
}
};
runOneCycle(async);
assertEquals(IndexStatsMBean.STATUS_DONE, async.getIndexStats().getStatus());
//Below we ensure that we interrupt while the indexing is in progress
//hence the use of asyncLock which ensures the abort is called at right time
//Now make some changes to
builder = store.getRoot().builder();
builder.child("testRoot2").setProperty("foo", "abc");
store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
Thread t = new Thread(async);
//Lock to ensure that AsyncIndexUpdate waits
asyncLock.acquire();
t.start();
//Wait till async gets to wait state i.e. inside run
while (!asyncLock.hasQueuedThreads()) ;
assertEquals(IndexStatsMBean.STATUS_RUNNING, async.getIndexStats().getStatus());
assertThat(async.getIndexStats().abortAndPause(), containsString("Abort request placed"));
asyncLock.release();
retry(5, 5, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return IndexStatsMBean.STATUS_INTERRUPTED.equals(async.getIndexStats().getStatus());
}
});
//Post abort indexing should be fine
runOneCycle(async);
assertTrue(async.getIndexStats().isPaused());
//Now resume indexing
async.getIndexStats().resume();
runOneCycle(async);
assertEquals(IndexStatsMBean.STATUS_DONE, async.getIndexStats().getStatus());
assertFalse(async.isClosed());
}
use of org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore in project jackrabbit-oak by apache.
the class AsyncIndexUpdateTest method closeWithSoftLimit.
@Test
public void closeWithSoftLimit() throws Exception {
NodeStore store = new MemoryNodeStore();
IndexEditorProvider provider = new PropertyIndexEditorProvider();
NodeBuilder builder = store.getRoot().builder();
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "rootIndex", true, false, ImmutableSet.of("foo"), null).setProperty(ASYNC_PROPERTY_NAME, "async");
builder.child("testRoot").setProperty("foo", "abc");
store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
final Semaphore asyncLock = new Semaphore(1);
final AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, provider) {
@Override
protected AsyncUpdateCallback newAsyncUpdateCallback(NodeStore store, String name, long leaseTimeOut, String beforeCheckpoint, AsyncIndexStats indexStats, AtomicBoolean stopFlag) {
try {
asyncLock.acquire();
} catch (InterruptedException ignore) {
}
return super.newAsyncUpdateCallback(store, name, leaseTimeOut, beforeCheckpoint, indexStats, stopFlag);
}
};
async.setCloseTimeOut(1000);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
async.run();
}
});
Thread closer = new Thread(new Runnable() {
@Override
public void run() {
async.close();
}
});
asyncLock.acquire();
t.start();
//Wait till async gets to wait state i.e. inside run
while (!asyncLock.hasQueuedThreads()) ;
LogCustomizer lc = createLogCustomizer(Level.DEBUG);
closer.start();
//Wait till closer is in waiting state
while (!async.isClosing()) ;
//For softLimit case the flag should not be set
assertFalse(async.isClosed());
assertLogPhrase(lc.getLogs(), "[WAITING]");
//Let indexing run complete now
asyncLock.release();
//Wait for both threads
t.join();
closer.join();
//Close call should complete
assertLogPhrase(lc.getLogs(), "[CLOSED OK]");
}
use of org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore in project jackrabbit-oak by apache.
the class AsyncIndexUpdateTest method taskSplitNoMatch.
@Test
public void taskSplitNoMatch() throws Exception {
MemoryNodeStore store = new MemoryNodeStore();
IndexEditorProvider provider = new PropertyIndexEditorProvider();
NodeBuilder builder = store.getRoot().builder();
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "rootIndex", true, false, ImmutableSet.of("foo"), null).setProperty(ASYNC_PROPERTY_NAME, "async");
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "ignored", true, false, ImmutableSet.of("baz"), null).setProperty(ASYNC_PROPERTY_NAME, "async-ignored");
builder.child("testRoot").setProperty("foo", "abc");
store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
assertTrue("Expecting no checkpoints", store.listCheckpoints().size() == 0);
AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, provider);
async.run();
assertTrue("Expecting one checkpoint", store.listCheckpoints().size() == 1);
String firstCp = store.listCheckpoints().iterator().next();
builder = store.getRoot().builder();
builder.child("testRoot").setProperty("foo", "def");
store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
IndexTaskSpliter splitter = async.getTaskSplitter();
// no match on the provided path
splitter.registerSplit(newHashSet("/oak:index/ignored"), "async-slow");
async.run();
Set<String> checkpoints = newHashSet(store.listCheckpoints());
assertTrue("Expecting a single checkpoint", checkpoints.size() == 1);
String secondCp = checkpoints.iterator().next();
NodeState asyncNode = store.getRoot().getChildNode(ASYNC);
assertEquals(secondCp, asyncNode.getString("async"));
assertNull(firstCp, asyncNode.getString("async-slow"));
}
Aggregations