use of org.apache.geode.internal.cache.wan.GatewaySenderEventImpl in project geode by apache.
the class AbstractRegionEntry method destroy.
/**
* @throws EntryNotFoundException if expectedOldValue is not null and is not equal to current
* value
*/
@Override
@Released
public boolean destroy(LocalRegion region, EntryEventImpl event, boolean inTokenMode, boolean cacheWrite, @Unretained Object expectedOldValue, boolean forceDestroy, boolean removeRecoveredEntry) throws CacheWriterException, EntryNotFoundException, TimeoutException, RegionClearedException {
// A design decision was made to not retrieve the old value from the disk
// if the entry has been evicted to only have the CacheListener afterDestroy
// method ignore it. We don't want to pay the performance penalty. The
// getValueInVM method does not retrieve the value from disk if it has been
// evicted. Instead, it uses the NotAvailable token.
//
// If the region is a WAN queue region, the old value is actually used by the
// afterDestroy callback on a secondary. It is not needed on a primary.
// Since the destroy that sets WAN_QUEUE_TOKEN always originates on the primary
// we only pay attention to WAN_QUEUE_TOKEN if the event is originRemote.
//
// We also read old value from disk or buffer
// in the case where there is a non-null expectedOldValue
// see PartitionedRegion#remove(Object key, Object value)
ReferenceCountHelper.skipRefCountTracking();
@Retained @Released Object curValue = _getValueRetain(region, true);
ReferenceCountHelper.unskipRefCountTracking();
boolean proceed;
try {
if (curValue == null) {
curValue = Token.NOT_AVAILABLE;
}
if (curValue == Token.NOT_AVAILABLE) {
// the state of the transmitting cache's entry & should be used here
if (event.getCallbackArgument() != null && event.getCallbackArgument().equals(RegionQueue.WAN_QUEUE_TOKEN) && event.isOriginRemote()) {
// check originRemote for bug 40508
// curValue = getValue(region); can cause deadlock if GII is occurring
curValue = getValueOnDiskOrBuffer(region);
} else {
FilterProfile fp = region.getFilterProfile();
if (fp != null && (fp.getCqCount() > 0 || expectedOldValue != null)) {
// curValue = getValue(region); can cause deadlock will fault in the value
// and will confuse LRU.
curValue = getValueOnDiskOrBuffer(region);
}
}
}
if (expectedOldValue != null) {
if (!checkExpectedOldValue(expectedOldValue, curValue, region)) {
throw new EntryNotFoundException(LocalizedStrings.AbstractRegionEntry_THE_CURRENT_VALUE_WAS_NOT_EQUAL_TO_EXPECTED_VALUE.toLocalizedString());
}
}
if (inTokenMode && event.hasOldValue()) {
proceed = true;
} else {
proceed = event.setOldValue(curValue, curValue instanceof GatewaySenderEventImpl) || removeRecoveredEntry || forceDestroy || region.getConcurrencyChecksEnabled() || (event.getOperation() == Operation.REMOVE && (curValue == null || curValue == Token.LOCAL_INVALID || curValue == Token.INVALID));
}
} finally {
OffHeapHelper.releaseWithNoTracking(curValue);
}
if (proceed) {
// after the entry not found exception above.
if (!removeRecoveredEntry) {
region.generateAndSetVersionTag(event, this);
}
if (cacheWrite) {
region.cacheWriteBeforeDestroy(event, expectedOldValue);
if (event.getRegion().getServerProxy() != null) {
// server will return a version tag
// update version information (may throw ConcurrentCacheModificationException)
VersionStamp stamp = getVersionStamp();
if (stamp != null) {
stamp.processVersionTag(event);
}
}
}
region.recordEvent(event);
// RegionEntry (the old value) is invalid
if (!region.isProxy() && !isInvalid()) {
IndexManager indexManager = region.getIndexManager();
if (indexManager != null) {
try {
if (isValueNull()) {
@Released Object value = getValueOffHeapOrDiskWithoutFaultIn(region);
try {
Object preparedValue = prepareValueForCache(region, value, false);
_setValue(preparedValue);
releaseOffHeapRefIfRegionBeingClosedOrDestroyed(region, preparedValue);
} finally {
OffHeapHelper.release(value);
}
}
indexManager.updateIndexes(this, IndexManager.REMOVE_ENTRY, IndexProtocol.OTHER_OP);
} catch (QueryException e) {
throw new IndexMaintenanceException(e);
}
}
}
boolean removeEntry = false;
VersionTag v = event.getVersionTag();
if (region.concurrencyChecksEnabled && !removeRecoveredEntry && !event.isFromRILocalDestroy()) {
// Destroy will write a tombstone instead
if (v == null || !v.hasValidVersion()) {
// localDestroy and eviction and ops received with no version tag
// should create a tombstone using the existing version stamp, as should
// (bug #45245) responses from servers that do not have valid version information
VersionStamp stamp = this.getVersionStamp();
if (stamp != null) {
// proxy has no stamps
v = stamp.asVersionTag();
event.setVersionTag(v);
}
}
removeEntry = v == null || !v.hasValidVersion();
} else {
removeEntry = true;
}
if (removeEntry) {
boolean isThisTombstone = isTombstone();
if (inTokenMode && !event.getOperation().isEviction()) {
setValue(region, Token.DESTROYED);
} else {
removePhase1(region, false);
}
if (isThisTombstone) {
region.unscheduleTombstone(this);
}
} else {
makeTombstone(region, v);
}
return true;
} else {
return false;
}
}
use of org.apache.geode.internal.cache.wan.GatewaySenderEventImpl in project geode by apache.
the class ParallelQueueRemovalMessage method destroyFromTempQueue.
private boolean destroyFromTempQueue(PartitionedRegion qPR, int bId, Object key) {
boolean isDestroyed = false;
Set queues = qPR.getParallelGatewaySender().getQueues();
if (queues != null) {
ConcurrentParallelGatewaySenderQueue prq = (ConcurrentParallelGatewaySenderQueue) queues.toArray()[0];
BlockingQueue<GatewaySenderEventImpl> tempQueue = prq.getBucketTmpQueue(bId);
if (tempQueue != null) {
Iterator<GatewaySenderEventImpl> itr = tempQueue.iterator();
while (itr.hasNext()) {
GatewaySenderEventImpl eventForFilter = itr.next();
// fix for #48082
afterAckForSecondary_EventInTempQueue(qPR.getParallelGatewaySender(), eventForFilter);
if (eventForFilter.getShadowKey().equals(key)) {
itr.remove();
// GEODE-1282
eventForFilter.release();
isDestroyed = true;
}
}
}
}
return isDestroyed;
}
use of org.apache.geode.internal.cache.wan.GatewaySenderEventImpl in project geode by apache.
the class ParallelGatewaySenderEventProcessor method enqueueEvent.
@Override
public void enqueueEvent(EnumListenerEvent operation, EntryEvent event, Object substituteValue) throws IOException, CacheException {
GatewaySenderEventImpl gatewayQueueEvent = null;
Region region = event.getRegion();
if (!(region instanceof DistributedRegion) && ((EntryEventImpl) event).getTailKey() == -1) {
// Fix for #49081 and EntryDestroyedException in #49367.
if (logger.isDebugEnabled()) {
logger.debug("ParallelGatewaySenderEventProcessor not enqueing the following event since tailKey is not set. {}", event);
}
return;
}
// TODO: Looks like for PDX region bucket id is set to -1.
boolean queuedEvent = false;
try {
EventID eventID = ((EntryEventImpl) event).getEventId();
// while merging 42004, kept substituteValue as it is(it is barry's
// change 42466). bucketID is merged with eventID.getBucketID
gatewayQueueEvent = new GatewaySenderEventImpl(operation, event, substituteValue, true, eventID.getBucketID());
if (getSender().beforeEnqueue(gatewayQueueEvent)) {
long start = getSender().getStatistics().startTime();
try {
queuedEvent = this.queue.put(gatewayQueueEvent);
} catch (InterruptedException e) {
e.printStackTrace();
}
getSender().getStatistics().endPut(start);
} else {
if (logger.isDebugEnabled()) {
logger.debug("The Event {} is filtered.", gatewayQueueEvent);
}
getSender().getStatistics().incEventsFiltered();
}
} finally {
if (!queuedEvent) {
// it was not queued for some reason
gatewayQueueEvent.release();
}
}
}
use of org.apache.geode.internal.cache.wan.GatewaySenderEventImpl in project geode by apache.
the class ParallelGatewaySenderQueue method remove.
@Override
public void remove() throws CacheException {
if (!this.peekedEvents.isEmpty()) {
GatewaySenderEventImpl event = this.peekedEvents.remove();
try {
PartitionedRegion prQ = null;
int bucketId = -1;
Object key = null;
if (event.getRegion() != null) {
if (isDREvent(event)) {
prQ = this.userRegionNameToshadowPRMap.get(event.getRegion().getFullPath());
bucketId = event.getEventId().getBucketID();
key = event.getEventId();
} else {
prQ = this.userRegionNameToshadowPRMap.get(ColocationHelper.getLeaderRegion((PartitionedRegion) event.getRegion()).getFullPath());
bucketId = event.getBucketId();
key = event.getShadowKey();
}
} else {
String regionPath = event.getRegionPath();
InternalCache cache = this.sender.getCache();
Region region = (PartitionedRegion) cache.getRegion(regionPath);
if (region != null && !region.isDestroyed()) {
// TODO: We have to get colocated parent region for this region
if (region instanceof DistributedRegion) {
prQ = this.userRegionNameToshadowPRMap.get(region.getFullPath());
event.getBucketId();
key = event.getEventId();
} else {
prQ = this.userRegionNameToshadowPRMap.get(ColocationHelper.getLeaderRegion((PartitionedRegion) region).getFullPath());
event.getBucketId();
key = event.getShadowKey();
}
}
}
if (prQ != null) {
destroyEventFromQueue(prQ, bucketId, key);
}
} finally {
try {
event.release();
} catch (IllegalStateException e) {
logger.error("Exception caught and logged. The thread will continue running", e);
}
}
}
}
use of org.apache.geode.internal.cache.wan.GatewaySenderEventImpl in project geode by apache.
the class ParallelGatewaySenderQueue method put.
public boolean put(Object object) throws InterruptedException, CacheException {
final boolean isDebugEnabled = logger.isDebugEnabled();
boolean putDone = false;
// Can this region ever be null? Should we work with regionName and not with region
// instance.
// It can't be as put is happeing on the region and its still under process
GatewaySenderEventImpl value = (GatewaySenderEventImpl) object;
boolean isDREvent = isDREvent(value);
Region region = value.getRegion();
String regionPath = null;
if (isDREvent) {
regionPath = region.getFullPath();
} else {
regionPath = ColocationHelper.getLeaderRegion((PartitionedRegion) region).getFullPath();
}
if (isDebugEnabled) {
logger.debug("Put is for the region {}", region);
}
if (!this.userRegionNameToshadowPRMap.containsKey(regionPath)) {
if (isDebugEnabled) {
logger.debug("The userRegionNameToshadowPRMap is {}", userRegionNameToshadowPRMap);
}
logger.warn(LocalizedMessage.create(LocalizedStrings.NOT_QUEUING_AS_USERPR_IS_NOT_YET_CONFIGURED, value));
// does not put into queue
return false;
}
PartitionedRegion prQ = this.userRegionNameToshadowPRMap.get(regionPath);
int bucketId = value.getBucketId();
Object key = null;
if (!isDREvent) {
key = value.getShadowKey();
if ((Long) key == -1) {
// through listener, so return.
if (isDebugEnabled) {
logger.debug("ParallelGatewaySenderOrderedQueue not putting key {} : Value : {}", key, value);
}
// does not put into queue
return false;
}
} else {
key = value.getEventId();
}
if (isDebugEnabled) {
logger.debug("ParallelGatewaySenderOrderedQueue putting key {} : Value : {}", key, value);
}
AbstractBucketRegionQueue brq = (AbstractBucketRegionQueue) prQ.getDataStore().getLocalBucketById(bucketId);
try {
if (brq == null) {
// Set the threadInitLevel to BEFORE_INITIAL_IMAGE.
int oldLevel = LocalRegion.setThreadInitLevelRequirement(LocalRegion.BEFORE_INITIAL_IMAGE);
try {
// Full path of the bucket:
final String bucketFullPath = Region.SEPARATOR + PartitionedRegionHelper.PR_ROOT_REGION_NAME + Region.SEPARATOR + prQ.getBucketName(bucketId);
brq = (AbstractBucketRegionQueue) prQ.getCache().getRegionByPath(bucketFullPath);
if (isDebugEnabled) {
logger.debug("ParallelGatewaySenderOrderedQueue : The bucket in the cache is bucketRegionName : {} bucket : {}", bucketFullPath, brq);
}
if (brq != null) {
brq.getInitializationLock().readLock().lock();
try {
putIntoBucketRegionQueue(brq, key, value);
putDone = true;
} finally {
brq.getInitializationLock().readLock().unlock();
}
} else if (isDREvent) {
// in case of DR with PGS, if shadow bucket is not found event after
// above search then it means that bucket is not intended for this
// node. So lets not add this event in temp queue event as we are
// doing it for PRevent
// does not put onto the queue
} else {
// In that case we don't want to store this event.
if (((PartitionedRegion) prQ.getColocatedWithRegion()).getRegionAdvisor().getBucketAdvisor(bucketId).getShadowBucketDestroyed()) {
if (isDebugEnabled) {
logger.debug("ParallelGatewaySenderOrderedQueue not putting key {} : Value : {} as shadowPR bucket is destroyed.", key, value);
}
// does not put onto the queue
} else {
/*
* This is to prevent data loss, in the scenario when bucket is not available in the
* cache but we know that it will be created.
*/
BlockingQueue tempQueue = null;
synchronized (this.bucketToTempQueueMap) {
tempQueue = this.bucketToTempQueueMap.get(bucketId);
if (tempQueue == null) {
tempQueue = new LinkedBlockingQueue();
this.bucketToTempQueueMap.put(bucketId, tempQueue);
}
}
synchronized (tempQueue) {
brq = (AbstractBucketRegionQueue) prQ.getCache().getRegionByPath(bucketFullPath);
if (brq != null) {
brq.getInitializationLock().readLock().lock();
try {
putIntoBucketRegionQueue(brq, key, value);
putDone = true;
} finally {
brq.getInitializationLock().readLock().unlock();
}
} else {
tempQueue.add(value);
putDone = true;
// For debugging purpose.
if (isDebugEnabled) {
logger.debug("The value {} is enqueued to the tempQueue for the BucketRegionQueue.", value);
}
}
}
}
}
} finally {
LocalRegion.setThreadInitLevelRequirement(oldLevel);
}
} else {
boolean thisbucketDestroyed = false;
if (!isDREvent) {
thisbucketDestroyed = ((PartitionedRegion) prQ.getColocatedWithRegion()).getRegionAdvisor().getBucketAdvisor(bucketId).getShadowBucketDestroyed() || brq.isDestroyed();
} else {
thisbucketDestroyed = brq.isDestroyed();
}
if (!thisbucketDestroyed) {
putIntoBucketRegionQueue(brq, key, value);
putDone = true;
} else {
if (isDebugEnabled) {
logger.debug("ParallelGatewaySenderOrderedQueue not putting key {} : Value : {} as shadowPR bucket is destroyed.", key, value);
}
// does not put onto the queue
}
}
} finally {
notifyEventProcessorIfRequired();
}
return putDone;
}
Aggregations