use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class EventTracker method recordEvent.
/** record the event's threadid/sequenceid to prevent replay */
public void recordEvent(InternalCacheEvent event) {
EventID eventID = event.getEventId();
if (ignoreEvent(event, eventID)) {
// not tracked
return;
}
LocalRegion lr = (LocalRegion) event.getRegion();
ThreadIdentifier membershipID = new ThreadIdentifier(eventID.getMembershipID(), eventID.getThreadID());
VersionTag tag = null;
if (lr.getServerProxy() == null) /* && event.hasClientOrigin() */
{
// clients do not need to
// store version tags for
// replayed events
tag = event.getVersionTag();
RegionVersionVector v = ((LocalRegion) event.getRegion()).getVersionVector();
// bug #46453 - make sure ID references are canonical before storing
if (v != null && tag != null) {
tag.setMemberID(v.getCanonicalId(tag.getMemberID()));
if (tag.getPreviousMemberID() != null) {
tag.setPreviousMemberID(v.getCanonicalId(tag.getPreviousMemberID()));
}
}
}
EventSeqnoHolder newEvh = new EventSeqnoHolder(eventID.getSequenceID(), tag);
if (logger.isTraceEnabled()) {
logger.trace("region event tracker recording {}", event);
}
recordSeqno(membershipID, newEvh);
// recordedBulkOpVersionTags
if (lr.getConcurrencyChecksEnabled() && (event.getOperation().isPutAll() || event.getOperation().isRemoveAll()) && lr.getServerProxy() == null) {
recordBulkOpEvent(event, membershipID);
}
}
use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class EventTracker method recordBulkOpEvent.
/**
* Record a version tag for a bulk operation
*/
private void recordBulkOpEvent(InternalCacheEvent event, ThreadIdentifier tid) {
EventID eventID = event.getEventId();
VersionTag tag = event.getVersionTag();
if (tag == null) {
return;
}
if (logger.isDebugEnabled()) {
logger.debug("recording bulkOp event {} {} {} op={}", tid.expensiveToString(), eventID, tag, event.getOperation());
}
RegionVersionVector v = ((LocalRegion) event.getRegion()).getVersionVector();
// bug #46453 - make sure ID references are canonical before storing
if (v != null) {
tag.setMemberID(v.getCanonicalId(tag.getMemberID()));
if (tag.getPreviousMemberID() != null) {
tag.setPreviousMemberID(v.getCanonicalId(tag.getPreviousMemberID()));
}
}
// Loop until we can successfully update the recorded bulk operations
// For this thread id.
boolean retry = false;
do {
BulkOpHolder bulkOpTracker = recordedBulkOpVersionTags.get(tid);
if (bulkOpTracker == null) {
bulkOpTracker = new BulkOpHolder();
BulkOpHolder old = recordedBulkOpVersionTags.putIfAbsent(tid, bulkOpTracker);
if (old != null) {
retry = true;
continue;
}
}
synchronized (bulkOpTracker) {
if (bulkOpTracker.removed) {
retry = true;
continue;
}
// Add the version tag for bulkOp event.
bulkOpTracker.putVersionTag(eventID, event.getVersionTag());
retry = false;
}
} while (retry);
}
use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class AbstractRegionEntry method initialImageInit.
@Override
public boolean initialImageInit(final LocalRegion region, final long lastModified, final Object newValue, final boolean create, final boolean wasRecovered, final boolean acceptedVersionTag) throws RegionClearedException {
// note that the caller has already write synced this RegionEntry
boolean result = false;
// if it has been destroyed then don't do anything
Token vTok = getValueAsToken();
if (acceptedVersionTag || create || (vTok != Token.DESTROYED || vTok != Token.TOMBSTONE)) {
// OFFHEAP noop
Object newValueToWrite = newValue;
// OFFHEAP noop
boolean putValue = acceptedVersionTag || create || (newValueToWrite != Token.LOCAL_INVALID && (wasRecovered || (vTok == Token.LOCAL_INVALID)));
if (region.isUsedForPartitionedRegionAdmin() && newValueToWrite instanceof CachedDeserializable) {
// Special case for partitioned region meta data
// We do not need the RegionEntry on this case.
// Because the pr meta data region will not have an LRU.
newValueToWrite = ((CachedDeserializable) newValueToWrite).getDeserializedValue(region, null);
if (!create && newValueToWrite instanceof Versionable) {
// Heap value should always be deserialized at this point // OFFHEAP will not be
// deserialized
final Object oldValue = getValueInVM(region);
// BUGFIX for 35029. If oldValue is null the newValue should be put.
if (oldValue == null) {
putValue = true;
} else if (oldValue instanceof Versionable) {
Versionable nv = (Versionable) newValueToWrite;
Versionable ov = (Versionable) oldValue;
putValue = nv.isNewerThan(ov);
}
}
}
if (putValue) {
// and current value is recovered
if (create || acceptedVersionTag) {
// At this point, since we now always recover from disk first,
// we only care about "isCreate" since "isRecovered" is impossible
// if we had a regionInvalidate or regionClear
ImageState imageState = region.getImageState();
// this method is called during loadSnapshot as well as getInitialImage
if (imageState.getRegionInvalidated()) {
if (newValueToWrite != Token.TOMBSTONE) {
newValueToWrite = Token.INVALID;
}
} else if (imageState.getClearRegionFlag()) {
boolean entryOK = false;
RegionVersionVector rvv = imageState.getClearRegionVersionVector();
if (rvv != null) {
// a filtered clear
VersionSource id = getVersionStamp().getMemberID();
if (id == null) {
id = region.getVersionMember();
}
if (!rvv.contains(id, getVersionStamp().getRegionVersion())) {
entryOK = true;
}
}
if (!entryOK) {
// If the region has been issued cleared during
// the GII , then those entries loaded before this one would have
// been cleared from the Map due to clear operation & for the
// currententry whose key may have escaped the clearance , will be
// cleansed by the destroy token.
// TODO: never used
newValueToWrite = Token.DESTROYED;
imageState.addDestroyedEntry(this.getKey());
throw new RegionClearedException(LocalizedStrings.AbstractRegionEntry_DURING_THE_GII_PUT_OF_ENTRY_THE_REGION_GOT_CLEARED_SO_ABORTING_THE_OPERATION.toLocalizedString());
}
}
}
setValue(region, this.prepareValueForCache(region, newValueToWrite, false));
result = true;
if (newValueToWrite != Token.TOMBSTONE) {
if (create) {
region.getCachePerfStats().incCreates();
}
region.updateStatsForPut(this, lastModified, false);
}
if (logger.isTraceEnabled()) {
if (newValueToWrite instanceof CachedDeserializable) {
logger.trace("ProcessChunk: region={}; put a CachedDeserializable ({},{})", region.getFullPath(), getKey(), ((CachedDeserializable) newValueToWrite).getStringForm());
} else {
logger.trace("ProcessChunk: region={}; put({},{})", region.getFullPath(), getKey(), StringUtils.forceToString(newValueToWrite));
}
}
}
}
return result;
}
use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class DistributedRegion method getInitialImageAndRecovery.
// TODO: cleanup getInitialImageAndRecovery
private void getInitialImageAndRecovery(InputStream snapshotInputStream, InternalDistributedMember imageSrc, InternalRegionArguments internalRegionArgs, boolean recoverFromDisk, PersistentMemberID persistentId) throws TimeoutException {
logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZING_REGION_0, this.getName()));
ImageState imgState = getImageState();
imgState.init();
boolean targetRecreated = internalRegionArgs.getRecreateFlag();
Boolean isCBool = (Boolean) isConversion.get();
boolean isForConversion = isCBool != null ? isCBool : false;
if (recoverFromDisk && snapshotInputStream != null && !isForConversion) {
throw new InternalGemFireError(LocalizedStrings.DistributedRegion_IF_LOADING_A_SNAPSHOT_THEN_SHOULD_NOT_BE_RECOVERING_ISRECOVERING_0_SNAPSHOTSTREAM_1.toLocalizedString(new Object[] { true, snapshotInputStream }));
}
ProfileExchangeProcessor targetProvider;
if (this.dataPolicy.withPersistence()) {
targetProvider = new CreatePersistentRegionProcessor(this, getPersistenceAdvisor(), recoverFromDisk);
} else {
// this will go in the advisor profile
targetProvider = new CreateRegionProcessor(this);
}
imgState.setInRecovery(false);
RegionVersionVector recovered_rvv = null;
if (this.dataPolicy.withPersistence()) {
recovered_rvv = this.getVersionVector() == null ? null : this.getVersionVector().getCloneForTransmission();
}
// initializeRegion will send out our profile
targetProvider.initializeRegion();
if (this.persistenceAdvisor != null) {
this.persistenceAdvisor.initialize();
}
// remote members
if (!isInternalRegion()) {
if (!this.isDestroyed) {
this.cache.getInternalResourceManager().addResourceListener(ResourceType.MEMORY, this);
}
}
releaseBeforeGetInitialImageLatch();
// allow GII to invoke test hooks. Do this just after releasing the
// before-gii latch for bug #48962. See ConcurrentLeaveDuringGIIDUnitTest
InitialImageOperation.beforeGetInitialImage(this);
if (snapshotInputStream != null) {
try {
if (logger.isDebugEnabled()) {
logger.debug("DistributedRegion.getInitialImageAndRecovery: About to load snapshot, isInitialized={}; {}", isInitialized(), getFullPath());
}
loadSnapshotDuringInitialization(snapshotInputStream);
} catch (IOException e) {
// TODO: change this exception?
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
// TODO: change this exception?
throw new RuntimeException(e);
}
cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus.NO_GII);
return;
}
// No snapshot provided, use the imageTarget(s)
// if we were given a recommended imageTarget, use that first, and
// treat it like it is a replicate (regardless of whether it actually is
// or not)
InitialImageOperation iiop = new InitialImageOperation(this, this.entries);
CacheDistributionAdvisor.InitialImageAdvice advice = null;
boolean done = false;
while (!done && !isDestroyed()) {
advice = targetProvider.getInitialImageAdvice(advice);
boolean attemptGetFromOne = // we were given a specific member
imageSrc != null || // this is a preloaded
this.dataPolicy.withPreloaded() && !advice.preloaded.isEmpty() || // region
(!advice.replicates.isEmpty());
if (attemptGetFromOne) {
if (recoverFromDisk) {
if (LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER) {
CacheObserverHolder.getInstance().afterMarkingGIIStarted();
}
}
{
// Plan A: use specified imageSrc, if specified
if (imageSrc != null) {
try {
GIIStatus ret = iiop.getFromOne(Collections.singleton(imageSrc), targetRecreated, advice, recoverFromDisk, recovered_rvv);
if (GIIStatus.didGII(ret)) {
this.giiMissingRequiredRoles = false;
cleanUpDestroyedTokensAndMarkGIIComplete(ret);
done = true;
return;
}
} finally {
imageSrc = null;
}
}
// Plan C: use a replicate, if one exists
GIIStatus ret = iiop.getFromOne(advice.replicates, false, advice, recoverFromDisk, recovered_rvv);
if (GIIStatus.didGII(ret)) {
cleanUpDestroyedTokensAndMarkGIIComplete(ret);
done = true;
return;
}
// Plan D: if this is a PRELOADED region, fetch from another PRELOADED
if (this.dataPolicy.isPreloaded()) {
GIIStatus ret_preload = iiop.getFromOne(advice.preloaded, false, advice, recoverFromDisk, recovered_rvv);
if (GIIStatus.didGII(ret_preload)) {
cleanUpDestroyedTokensAndMarkGIIComplete(ret_preload);
done = true;
return;
}
}
// isPreloaded
}
// If we got to this point, we failed in the GII. Cleanup
// any partial image we received
cleanUpAfterFailedGII(recoverFromDisk);
} else // attemptGetFromOne
{
if (!isDestroyed()) {
if (recoverFromDisk) {
logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZED_FROM_DISK, new Object[] { this.getFullPath(), persistentId, getPersistentID() }));
if (persistentId != null) {
RegionLogger.logRecovery(this.getFullPath(), persistentId, getDistributionManager().getDistributionManagerId());
}
} else {
RegionLogger.logCreate(this.getFullPath(), getDistributionManager().getDistributionManagerId());
if (getPersistentID() != null) {
RegionLogger.logPersistence(this.getFullPath(), getDistributionManager().getDistributionManagerId(), getPersistentID());
logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_NEW_PERSISTENT_REGION_CREATED, new Object[] { this.getFullPath(), getPersistentID() }));
}
}
cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus.NO_GII);
done = true;
return;
}
break;
}
}
}
use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class DistributedRegion method cleanUpDestroyedTokensAndMarkGIIComplete.
// called by InitialImageOperation to clean up destroyed tokens
// release afterGetInitialImageInitializationLatch before unlocking
// cleanUpLock
@SuppressWarnings("UL_UNRELEASED_LOCK")
protected void cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus giiStatus) {
// We need to clean up the disk before we release the after get initial image latch
DiskRegion dskRgn = getDiskRegion();
if (dskRgn != null && dskRgn.isBackup()) {
dskRgn.finishInitializeOwner(this, giiStatus);
}
ImageState is = getImageState();
is.lockGII();
// clear the version tag and left-members sets
is.getVersionTags();
is.getLeftMembers();
// remove DESTROYED tokens
RegionVersionVector rvv = is.getClearRegionVersionVector();
try {
Iterator /* <Object> */
keysIt = getImageState().getDestroyedEntries();
while (keysIt.hasNext()) {
this.entries.removeIfDestroyed(keysIt.next());
}
if (rvv != null) {
// clear any entries received in the GII that are older than the RVV versions.
// this can happen if entry chunks were received prior to the clear() being
// processed
clearEntries(rvv);
}
// need to do this before we release the afterGetInitialImageLatch
if (this.persistenceAdvisor != null) {
this.persistenceAdvisor.setOnline(GIIStatus.didGII(giiStatus), false, getPersistentID());
}
} finally {
// when they get the cleanUp lock.
try {
releaseAfterGetInitialImageLatch();
} finally {
// make sure unlockGII is done for bug 40001
is.unlockGII();
}
}
if (LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER) {
CacheObserverHolder.getInstance().afterMarkingGIICompleted();
}
// "Initializing region {0}" which is not acompanied by a completed message. Users think thread
// is stuck in some operation. Hence adding this log
logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZING_REGION_COMPLETED_0, this.getName()));
}
Aggregations