use of org.apache.jackrabbit.oak.stats.Clock in project jackrabbit-oak by apache.
the class DocumentNodeStoreTest method modifiedReset.
@Test
public void modifiedReset() throws Exception {
Clock clock = new Clock.Virtual();
clock.waitUntil(System.currentTimeMillis());
Revision.setClock(clock);
MemoryDocumentStore docStore = new MemoryDocumentStore();
DocumentNodeStore ns1 = builderProvider.newBuilder().setDocumentStore(docStore).setClusterId(1).setAsyncDelay(0).clock(clock).getNodeStore();
NodeBuilder builder1 = ns1.getRoot().builder();
builder1.child("node");
ns1.merge(builder1, EmptyHook.INSTANCE, CommitInfo.EMPTY);
ns1.runBackgroundOperations();
DocumentNodeStore ns2 = builderProvider.newBuilder().setDocumentStore(docStore).setClusterId(2).setAsyncDelay(0).clock(clock).getNodeStore();
NodeBuilder builder2 = ns2.getRoot().builder();
builder2.child("node").child("child-2");
ns2.merge(builder2, EmptyHook.INSTANCE, CommitInfo.EMPTY);
// wait at least _modified resolution. in reality the wait may
// not be necessary. e.g. when the clock passes the resolution boundary
// exactly at this time
clock.waitUntil(System.currentTimeMillis() + SECONDS.toMillis(MODIFIED_IN_SECS_RESOLUTION + 1));
builder1 = ns1.getRoot().builder();
builder1.child("node").child("child-1");
ns1.merge(builder1, EmptyHook.INSTANCE, CommitInfo.EMPTY);
ns1.runBackgroundOperations();
// get current _modified timestamp on /node
NodeDocument doc = docStore.find(NODES, Utils.getIdFromPath("/node"));
Long mod1 = (Long) doc.get(MODIFIED_IN_SECS);
assertNotNull(mod1);
ns2.runBackgroundOperations();
doc = docStore.find(NODES, Utils.getIdFromPath("/node"));
Long mod2 = (Long) doc.get(MODIFIED_IN_SECS);
assertTrue("" + mod2 + " < " + mod1, mod2 >= mod1);
}
use of org.apache.jackrabbit.oak.stats.Clock in project jackrabbit-oak by apache.
the class DocumentNodeStoreTest method clusterWithClockDifferences2.
// OAK-3388
@Test
public void clusterWithClockDifferences2() throws Exception {
MemoryDocumentStore store = new MemoryDocumentStore();
long now = System.currentTimeMillis();
Clock c1 = new Clock.Virtual();
c1.waitUntil(now);
Revision.setClock(c1);
DocumentNodeStore ns1 = builderProvider.newBuilder().clock(c1).setDocumentStore(store).setAsyncDelay(0).setClusterId(1).getNodeStore();
NodeBuilder b1 = ns1.getRoot().builder();
b1.child("node").setProperty("p", 1);
merge(ns1, b1);
// make /node visible
ns1.runBackgroundOperations();
Revision.resetClockToDefault();
Clock c2 = new Clock.Virtual();
// c2 is five seconds ahead
c2.waitUntil(now + 5000);
Revision.setClock(c2);
DocumentNodeStore ns2 = builderProvider.newBuilder().clock(c2).setDocumentStore(store).setAsyncDelay(0).setClusterId(2).getNodeStore();
// ns2 sees /node
assertTrue(ns2.getRoot().hasChildNode("node"));
assertEquals(1, ns2.getRoot().getChildNode("node").getProperty("p").getValue(Type.LONG).longValue());
// increment /node/p ns2
NodeBuilder b2 = ns2.getRoot().builder();
b2.child("node").setProperty("p", 2);
merge(ns2, b2);
ns2.runBackgroundOperations();
// increment /node/p2 on ns1
Revision.resetClockToDefault();
Revision.setClock(c1);
ns1.runBackgroundOperations();
b1 = ns1.getRoot().builder();
assertEquals(2, b1.getChildNode("node").getProperty("p").getValue(Type.LONG).longValue());
b1.child("node").setProperty("p", 3);
merge(ns1, b1);
ns1.runBackgroundOperations();
// check if /node/p=3 is visible on ns2
Revision.resetClockToDefault();
Revision.setClock(c2);
ns2.runBackgroundOperations();
b2 = ns2.getRoot().builder();
assertEquals(3, b2.getChildNode("node").getProperty("p").getValue(Type.LONG).longValue());
}
use of org.apache.jackrabbit.oak.stats.Clock in project jackrabbit-oak by apache.
the class DocumentNodeStoreTest method diffExternalChanges.
// OAK-2232
@Test
public void diffExternalChanges() throws Exception {
long modifiedResMillis = SECONDS.toMillis(MODIFIED_IN_SECS_RESOLUTION);
Clock clock = new Clock.Virtual();
clock.waitUntil(System.currentTimeMillis());
Revision.setClock(clock);
DocumentStore docStore = new MemoryDocumentStore();
DocumentNodeStore ns1 = builderProvider.newBuilder().setAsyncDelay(0).clock(clock).setDocumentStore(docStore).setClusterId(1).getNodeStore();
DocumentNodeStore ns2 = builderProvider.newBuilder().setAsyncDelay(0).clock(clock).setDocumentStore(docStore).setClusterId(2).getNodeStore();
NodeBuilder builder = ns1.getRoot().builder();
NodeBuilder test = builder.child("test");
for (int i = 0; i < DocumentMK.MANY_CHILDREN_THRESHOLD * 2; i++) {
test.child("node-" + i);
}
ns1.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
ns1.runBackgroundOperations();
ns2.runBackgroundOperations();
// make sure next change has a different _modified value
clock.waitUntil(clock.getTime() + modifiedResMillis * 2);
builder = ns2.getRoot().builder();
builder.child("test").child("foo");
ns2.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
// 'wait' again for a different _modified value
clock.waitUntil(clock.getTime() + modifiedResMillis * 2);
builder = ns1.getRoot().builder();
builder.child("test").child("bar");
ns1.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
// remember current root for diff
NodeState r1 = ns1.getRoot();
ns2.runBackgroundOperations();
ns1.runBackgroundOperations();
NodeState r2 = ns1.getRoot();
// are we able to see foo?
boolean found = false;
for (ChildNodeEntry entry : r2.getChildNode("test").getChildNodeEntries()) {
if (entry.getName().equals("foo")) {
found = true;
break;
}
}
assertTrue(found);
// diff must report '/test' modified and '/test/foo' added
TrackingDiff diff = new TrackingDiff();
r2.compareAgainstBaseState(r1, diff);
assertEquals(1, diff.modified.size());
assertTrue(diff.modified.contains("/test"));
assertEquals(1, diff.added.size());
assertTrue(diff.added.contains("/test/foo"));
}
use of org.apache.jackrabbit.oak.stats.Clock in project jackrabbit-oak by apache.
the class DocumentNodeStoreTest method noSweepOnNewClusterNode.
@Test
public void noSweepOnNewClusterNode() throws Exception {
Clock clock = new Clock.Virtual();
clock.waitUntil(System.currentTimeMillis());
Revision.setClock(clock);
DocumentStore store = new MemoryDocumentStore();
builderProvider.newBuilder().clock(clock).setDocumentStore(store).setAsyncDelay(0).setClusterId(1).getNodeStore();
// now startup second node store with a custom lastRev seeker
final AtomicInteger candidateCalls = new AtomicInteger();
DocumentMK.Builder nsBuilder = new DocumentMK.Builder() {
@Override
public MissingLastRevSeeker createMissingLastRevSeeker() {
return new MissingLastRevSeeker(getDocumentStore(), getClock()) {
@Nonnull
@Override
public Iterable<NodeDocument> getCandidates(long startTime) {
candidateCalls.incrementAndGet();
return super.getCandidates(startTime);
}
};
}
};
DocumentNodeStore ns2 = nsBuilder.clock(clock).setDocumentStore(store).setAsyncDelay(0).setClusterId(2).getNodeStore();
try {
assertEquals(0, candidateCalls.get());
} finally {
ns2.dispose();
}
}
use of org.apache.jackrabbit.oak.stats.Clock in project jackrabbit-oak by apache.
the class DocumentNodeStoreTest method updateHeadWhenIdle.
@Test
public void updateHeadWhenIdle() throws Exception {
Clock clock = new Clock.Virtual();
clock.waitUntil(System.currentTimeMillis());
Revision.setClock(clock);
DocumentNodeStore ns = builderProvider.newBuilder().clock(clock).setAsyncDelay(0).getNodeStore();
doSomeChange(ns);
ns.runBackgroundOperations();
Revision head1 = ns.getHeadRevision().getRevision(ns.getClusterId());
assertNotNull(head1);
clock.waitUntil(clock.getTimeIncreasing() + TimeUnit.SECONDS.toMillis(30));
// background operations must not update head yet
ns.runBackgroundOperations();
Revision head2 = ns.getHeadRevision().getRevision(ns.getClusterId());
assertNotNull(head2);
assertEquals(head1, head2);
clock.waitUntil(clock.getTimeIncreasing() + TimeUnit.SECONDS.toMillis(30));
// next run of background operations must update head
ns.runBackgroundOperations();
Revision head3 = ns.getHeadRevision().getRevision(ns.getClusterId());
assertNotNull(head3);
assertTrue(head1.compareRevisionTime(head3) < 0);
}
Aggregations