use of org.apache.geode.internal.cache.versions.VersionStamp in project geode by apache.
the class UpdateVersionDUnitTest method testUpdateVersionAfterCreateWithConcurrentSerialSender.
@Test
public void testUpdateVersionAfterCreateWithConcurrentSerialSender() {
Host host = Host.getHost(0);
// server1 site1
VM vm0 = host.getVM(0);
// server2 site1
VM vm1 = host.getVM(1);
// server1 site2
VM vm2 = host.getVM(2);
// server2 site2
VM vm3 = host.getVM(3);
// Site 1
Integer lnPort = (Integer) vm0.invoke(() -> UpdateVersionDUnitTest.createFirstLocatorWithDSId(1));
final String key = "key-1";
vm0.invoke(() -> UpdateVersionDUnitTest.createCache(lnPort));
vm0.invoke(() -> UpdateVersionDUnitTest.createConcurrentSender("ln1", 2, false, 10, 2, false, false, null, true, 2));
vm0.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "ln1", 1, 1));
vm0.invoke(() -> UpdateVersionDUnitTest.startSender("ln1"));
vm0.invoke(() -> UpdateVersionDUnitTest.waitForSenderRunningState("ln1"));
// Site 2
Integer nyPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createFirstRemoteLocator(2, lnPort));
Integer nyRecPort = (Integer) vm2.invoke(() -> UpdateVersionDUnitTest.createReceiver(nyPort));
vm2.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "", 1, 1));
vm3.invoke(() -> UpdateVersionDUnitTest.createCache(nyPort));
vm3.invoke(() -> UpdateVersionDUnitTest.createPartitionedRegion(regionName, "", 1, 1));
final VersionTag tag = (VersionTag) vm0.invoke(new SerializableCallable("Put a single entry and get its version") {
@Override
public Object call() throws CacheException {
Cache cache = CacheFactory.getAnyInstance();
Region region = cache.getRegion(regionName);
assertTrue(region instanceof PartitionedRegion);
region.put(key, "value-1");
region.put(key, "value-2");
Entry entry = region.getEntry(key);
assertTrue(entry instanceof EntrySnapshot);
RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry();
VersionStamp stamp = regionEntry.getVersionStamp();
// Create a duplicate entry version tag from stamp with newer
// time-stamp.
VersionSource memberId = (VersionSource) cache.getDistributedSystem().getDistributedMember();
VersionTag tag = VersionTag.create(memberId);
int entryVersion = stamp.getEntryVersion() - 1;
int dsid = stamp.getDistributedSystemId();
long time = System.currentTimeMillis();
tag.setEntryVersion(entryVersion);
tag.setDistributedSystemId(dsid);
tag.setVersionTimeStamp(time);
tag.setIsRemoteForTesting();
EntryEventImpl event = createNewEvent((PartitionedRegion) region, tag, entry.getKey(), "value-3");
((LocalRegion) region).basicUpdate(event, false, true, 0L, false);
// Verify the new stamp
entry = region.getEntry(key);
assertTrue(entry instanceof EntrySnapshot);
regionEntry = ((EntrySnapshot) entry).getRegionEntry();
stamp = regionEntry.getVersionStamp();
assertEquals("Time stamp did NOT get updated by UPDATE_VERSION operation on LocalRegion", time, stamp.getVersionTimeStamp());
assertEquals(++entryVersion, stamp.getEntryVersion());
assertEquals(dsid, stamp.getDistributedSystemId());
return stamp.asVersionTag();
}
});
VersionTag remoteTag = (VersionTag) vm3.invoke(new SerializableCallable("Get timestamp from remote site") {
@Override
public Object call() throws Exception {
Cache cache = CacheFactory.getAnyInstance();
final PartitionedRegion region = (PartitionedRegion) cache.getRegion(regionName);
// wait for entry to be received
WaitCriterion wc = new WaitCriterion() {
public boolean done() {
Entry<?, ?> entry = null;
try {
entry = region.getDataStore().getEntryLocally(0, key, false, false);
} catch (EntryNotFoundException e) {
// expected
} catch (ForceReattemptException e) {
// expected
} catch (PRLocallyDestroyedException e) {
throw new RuntimeException("unexpected exception", e);
}
if (entry != null) {
LogWriterUtils.getLogWriter().info("found entry " + entry);
}
return (entry != null);
}
public String description() {
return "Expected key-1 to be received on remote WAN site";
}
};
Wait.waitForCriterion(wc, 30000, 500, true);
wc = new WaitCriterion() {
public boolean done() {
Entry entry = region.getEntry(key);
assertTrue(entry instanceof EntrySnapshot);
RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry();
return regionEntry.getVersionStamp().getVersionTimeStamp() == tag.getVersionTimeStamp();
}
public String description() {
return "waiting for timestamp to be updated";
}
};
Wait.waitForCriterion(wc, 30000, 500, true);
Entry entry = region.getEntry(key);
assertTrue(entry instanceof EntrySnapshot);
RegionEntry regionEntry = ((EntrySnapshot) entry).getRegionEntry();
VersionStamp stamp = regionEntry.getVersionStamp();
return stamp.asVersionTag();
}
});
assertEquals("Local and remote site have different timestamps", tag.getVersionTimeStamp(), remoteTag.getVersionTimeStamp());
}
use of org.apache.geode.internal.cache.versions.VersionStamp in project geode by apache.
the class DiskStoreImpl method shouldClear.
private boolean shouldClear(LocalRegion r, RegionVersionVector rvv, AsyncDiskEntry ade) {
if (ade.region != r) {
return false;
}
// If no RVV, remove all of the async items for this region.
if (rvv == null) {
return true;
}
// entries contained in the RVV
if (ade.versionOnly) {
return rvv.contains(ade.tag.getMemberID(), ade.tag.getRegionVersion());
} else {
VersionStamp stamp = ade.de.getVersionStamp();
VersionSource member = stamp.getMemberID();
if (member == null) {
// For overflow only regions, the version member may be null
// because that represents the local internal distributed member
member = r.getVersionMember();
}
return rvv.contains(member, stamp.getRegionVersion());
}
}
use of org.apache.geode.internal.cache.versions.VersionStamp in project geode by apache.
the class Oplog method offlineModify.
public void offlineModify(DiskRegionView drv, DiskEntry entry, byte[] value, boolean isSerializedObject) {
try {
ValueWrapper vw = new DiskEntry.Helper.ByteArrayValueWrapper(isSerializedObject, value);
byte userBits = calcUserBits(vw);
// save versions for creates and updates even if value is bytearrary in 7.0
VersionStamp vs = entry.getVersionStamp();
if (vs != null) {
if (vs.getMemberID() == null) {
throw new AssertionError("Version stamp should have a member at this point for entry " + entry);
}
// Since we are modifying this entry's value while offline make sure its version stamp
// has this disk store as its member id and bump the version
vs.setMemberID(getParent().getDiskStoreID());
VersionTag vt = vs.asVersionTag();
vt.setRegionVersion(drv.getRegionVersionVector().getNextVersion());
vt.setEntryVersion(vt.getEntryVersion() + 1);
vt.setVersionTimeStamp(System.currentTimeMillis());
vs.setVersions(vt);
userBits = EntryBits.setWithVersions(userBits, true);
}
basicModify(drv, entry, vw, userBits, false, false);
} catch (IOException ex) {
throw new DiskAccessException(LocalizedStrings.Oplog_FAILED_WRITING_KEY_TO_0.toLocalizedString(this.diskFile.getPath()), ex, drv.getName());
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new DiskAccessException(LocalizedStrings.Oplog_FAILED_WRITING_KEY_TO_0_DUE_TO_FAILURE_IN_ACQUIRING_READ_LOCK_FOR_ASYNCH_WRITING.toLocalizedString(this.diskFile.getPath()), ie, drv.getName());
}
}
use of org.apache.geode.internal.cache.versions.VersionStamp in project geode by apache.
the class BaseCommand method appendNewRegisterInterestResponseChunk.
public static void appendNewRegisterInterestResponseChunk(LocalRegion region, VersionedObjectList values, Object riKeys, Set<Map.Entry> set, ServerConnection servConn) throws IOException {
for (Entry entry : set) {
if (entry instanceof Region.Entry) {
// local entries
VersionTag vt;
Object key;
Object value;
if (entry instanceof EntrySnapshot) {
vt = ((EntrySnapshot) entry).getVersionTag();
key = ((EntrySnapshot) entry).getRegionEntry().getKey();
value = ((EntrySnapshot) entry).getRegionEntry().getValue(null);
updateValues(values, key, value, vt);
} else {
VersionStamp vs = ((NonTXEntry) entry).getRegionEntry().getVersionStamp();
vt = vs == null ? null : vs.asVersionTag();
key = entry.getKey();
value = ((NonTXEntry) entry).getRegionEntry()._getValueRetain(region, true);
try {
updateValues(values, key, value, vt);
} finally {
OffHeapHelper.release(value);
}
}
} else {
// Map.Entry (remote entries)
List list = (List) entry.getValue();
Object value = list.get(0);
VersionTag tag = (VersionTag) list.get(1);
updateValues(values, entry.getKey(), value, tag);
}
if (values.size() == MAXIMUM_CHUNK_SIZE) {
// Send the chunk and clear the list
sendNewRegisterInterestResponseChunk(region, riKeys != null ? riKeys : "ALL_KEYS", values, false, servConn);
values.clear();
}
}
// for
}
use of org.apache.geode.internal.cache.versions.VersionStamp in project geode by apache.
the class AbstractRegionEntry method generateVersionTag.
/**
* This generates version tags for outgoing messages for all subclasses supporting concurrency
* versioning. It also sets the entry's version stamp to the tag's values.
*/
@Override
public VersionTag generateVersionTag(VersionSource member, boolean withDelta, LocalRegion region, EntryEventImpl event) {
VersionStamp stamp = this.getVersionStamp();
if (stamp != null && region.getServerProxy() == null) {
// clients do not generate versions
int v = stamp.getEntryVersion() + 1;
if (v > 0xFFFFFF) {
// roll-over
v -= 0x1000000;
}
VersionSource previous = stamp.getMemberID();
// space.
if (member == null) {
VersionSource regionMember = region.getVersionMember();
if (regionMember instanceof DiskStoreID) {
member = regionMember;
}
}
VersionTag tag = VersionTag.create(member);
tag.setEntryVersion(v);
if (region.getVersionVector() != null) {
// Use region version if already provided, else generate
long nextRegionVersion = event.getNextRegionVersion();
if (nextRegionVersion != -1) {
// Set on the tag and record it locally
tag.setRegionVersion(nextRegionVersion);
RegionVersionVector rvv = region.getVersionVector();
rvv.recordVersion(rvv.getOwnerId(), nextRegionVersion);
if (logger.isDebugEnabled()) {
logger.debug("recorded region version {}; region={}", nextRegionVersion, region.getFullPath());
}
} else {
tag.setRegionVersion(region.getVersionVector().getNextVersion());
}
}
if (withDelta) {
tag.setPreviousMemberID(previous);
}
VersionTag remoteTag = event.getVersionTag();
if (remoteTag != null && remoteTag.isGatewayTag()) {
// if this event was received from a gateway we use the remote system's
// timestamp and dsid.
tag.setVersionTimeStamp(remoteTag.getVersionTimeStamp());
tag.setDistributedSystemId(remoteTag.getDistributedSystemId());
tag.setAllowedByResolver(remoteTag.isAllowedByResolver());
} else {
long time = region.cacheTimeMillis();
int dsid = region.getDistributionManager().getDistributedSystemId();
// one received from a wan gateway, so fake a timestamp if necessary
if (time <= stamp.getVersionTimeStamp() && dsid != tag.getDistributedSystemId()) {
time = stamp.getVersionTimeStamp() + 1;
}
tag.setVersionTimeStamp(time);
tag.setDistributedSystemId(dsid);
}
stamp.setVersions(tag);
stamp.setMemberID(member);
event.setVersionTag(tag);
if (logger.isDebugEnabled()) {
logger.debug("generated tag {}; key={}; oldvalue={} newvalue={} client={} region={}; rvv={}", tag, event.getKey(), event.getOldValueStringForm(), event.getNewValueStringForm(), event.getContext() == null ? "none" : event.getContext().getDistributedMember().getName(), region.getFullPath(), region.getVersionVector());
}
return tag;
}
return null;
}
Aggregations