use of org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException in project geode by apache.
the class AbstractRegionMap method processAndGenerateTXVersionTag.
/**
* called from txApply* methods to process and generate versionTags.
*/
private void processAndGenerateTXVersionTag(final LocalRegion owner, EntryEventImpl cbEvent, RegionEntry re, TXEntryState txEntryState) {
if (shouldPerformConcurrencyChecks(owner, cbEvent)) {
try {
if (txEntryState != null && txEntryState.getRemoteVersionTag() != null) {
// to generate a version based on a remote VersionTag, we will
// have to put the remote versionTag in the regionEntry
VersionTag remoteTag = txEntryState.getRemoteVersionTag();
if (re instanceof VersionStamp) {
VersionStamp stamp = (VersionStamp) re;
stamp.setVersions(remoteTag);
}
}
processVersionTag(re, cbEvent);
} catch (ConcurrentCacheModificationException ignore) {
// ignore this execption, however invoke callbacks for this operation
}
// just apply it and not regenerate it in phase-2 commit
if (cbEvent != null && txEntryState != null && txEntryState.getDistTxEntryStates() != null) {
cbEvent.setNextRegionVersion(txEntryState.getDistTxEntryStates().getRegionVersion());
}
// cbEvent.setNextRegionVersion(txEntryState.getNextRegionVersion());
owner.generateAndSetVersionTag(cbEvent, re);
}
}
use of org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException in project geode by apache.
the class PartitionedRegion method invalidateInBucket.
/**
* Invalidate the entry in the bucket identified by the key
*/
void invalidateInBucket(final EntryEventImpl event) throws EntryNotFoundException {
final boolean isDebugEnabled = logger.isDebugEnabled();
final Integer bucketId = event.getKeyInfo().getBucketId();
assert bucketId != KeyInfo.UNKNOWN_BUCKET;
final InternalDistributedMember targetNode = getOrCreateNodeForBucketWrite(bucketId, null);
final int retryAttempts = calcRetry();
int count = 0;
RetryTimeKeeper retryTime = null;
InternalDistributedMember retryNode = targetNode;
while (count <= retryAttempts) {
// It's possible this is a GemFire thread e.g. ServerConnection
// which got to this point because of a distributed system shutdown or
// region closure which uses interrupt to break any sleep() or wait()
// calls
// e.g. waitForPrimary or waitForBucketRecovery
checkShutdown();
if (retryNode == null) {
checkReadiness();
if (retryTime == null) {
retryTime = new RetryTimeKeeper(this.retryTimeout);
}
try {
retryNode = getOrCreateNodeForBucketWrite(bucketId, retryTime);
} catch (TimeoutException ignore) {
if (getRegionAdvisor().isStorageAssignedForBucket(bucketId)) {
// bucket no longer exists
throw new EntryNotFoundException(LocalizedStrings.PartitionedRegion_ENTRY_NOT_FOUND_FOR_KEY_0.toLocalizedString(event.getKey()));
}
// fall out to failed exception
break;
}
if (retryNode == null) {
checkEntryNotFound(event.getKey());
}
continue;
}
final boolean isLocal = (this.localMaxMemory > 0) && retryNode.equals(getMyId());
try {
if (isLocal) {
event.setInvokePRCallbacks(true);
this.dataStore.invalidateLocally(bucketId, event);
} else {
invalidateRemotely(retryNode, bucketId, event);
}
return;
} catch (ConcurrentCacheModificationException e) {
if (isDebugEnabled) {
logger.debug("invalidateInBucket: caught concurrent cache modification exception", e);
}
event.isConcurrencyConflict(true);
if (isDebugEnabled) {
logger.debug("ConcurrentCacheModificationException received for invalidateInBucket for bucketId: {}{}{} for event: {} No reattampt is done, returning from here", getPRId(), BUCKET_ID_SEPARATOR, bucketId, event);
}
return;
} catch (ForceReattemptException prce) {
prce.checkKey(event.getKey());
if (isDebugEnabled) {
logger.debug("invalidateInBucket: retry attempt:{} of {}", count, retryAttempts, prce);
}
checkReadiness();
InternalDistributedMember lastNode = retryNode;
retryNode = getOrCreateNodeForBucketWrite(bucketId, retryTime);
if (lastNode.equals(retryNode)) {
if (retryTime == null) {
retryTime = new RetryTimeKeeper(this.retryTimeout);
}
if (retryTime.overMaximum()) {
break;
}
retryTime.waitToRetryNode();
}
event.setPossibleDuplicate(true);
} catch (PrimaryBucketException notPrimary) {
if (isDebugEnabled) {
logger.debug("invalidateInBucket {} on Node {} not primary", notPrimary.getLocalizedMessage(), retryNode);
}
getRegionAdvisor().notPrimary(bucketId, retryNode);
retryNode = getOrCreateNodeForBucketWrite(bucketId, retryTime);
}
count++;
if (count == 1) {
this.prStats.incInvalidateOpsRetried();
}
this.prStats.incInvalidateRetries();
if (isDebugEnabled) {
logger.debug("invalidateInBucket: Attempting to resend invalidate to node {} after {} failed attempts", retryNode, count);
}
}
// while
// No target was found
PartitionedRegionDistributionException e = new PartitionedRegionDistributionException(LocalizedStrings.PartitionedRegion_NO_VM_AVAILABLE_FOR_INVALIDATE_IN_0_ATTEMPTS.toLocalizedString(// Fix for bug 36014
count));
if (!isDebugEnabled) {
logger.warn(LocalizedMessage.create(LocalizedStrings.PartitionedRegion_NO_VM_AVAILABLE_FOR_INVALIDATE_IN_0_ATTEMPTS, count));
} else {
logger.warn(e.getMessage(), e);
}
throw e;
}
use of org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException in project geode by apache.
the class LocalRegion method basicGetAll.
// TODO: refactor basicGetAll
@Override
Map basicGetAll(Collection keys, Object callback) {
final boolean isDebugEnabled = logger.isDebugEnabled();
final boolean isTraceEnabled = logger.isTraceEnabled();
if (isDebugEnabled) {
logger.debug("Processing getAll request for: {}", keys);
}
discoverJTA();
Map allResults = new HashMap();
if (hasServerProxy()) {
// Some of our implementation expects a list of keys so make sure it is a list
List keysList;
if (keys instanceof List) {
keysList = (List) keys;
} else {
keysList = new ArrayList(keys);
}
// We only need to do this if this region has local storage
if (getTXState() == null && hasStorage()) {
if (keysList == keys) {
// Create a copy of the collection of keys
// to keep the original collection intact
keysList = new ArrayList(keys);
}
for (Iterator iterator = keysList.iterator(); iterator.hasNext(); ) {
Object key = iterator.next();
Object value;
Region.Entry entry = accessEntry(key, true);
if (entry != null && (value = entry.getValue()) != null) {
allResults.put(key, value);
iterator.remove();
}
}
if (isDebugEnabled) {
logger.debug("Added local results for getAll request: {}", allResults);
}
}
// Send the rest of the keys to the server (if necessary)
if (!keysList.isEmpty()) {
VersionedObjectList remoteResults = getServerProxy().getAll(keysList, callback);
if (isDebugEnabled) {
logger.debug("remote getAll results are {}", remoteResults);
}
// Add remote results to local cache and all results if successful
for (VersionedObjectList.Iterator it = remoteResults.iterator(); it.hasNext(); ) {
VersionedObjectList.Entry entry = it.next();
Object key = entry.getKey();
boolean notOnServer = entry.isKeyNotOnServer();
// in 8.0 we added transfer of tombstones with RI/getAll results for bug #40791
boolean createTombstone = false;
if (notOnServer) {
createTombstone = entry.getVersionTag() != null && this.concurrencyChecksEnabled;
allResults.put(key, null);
if (isDebugEnabled) {
logger.debug("Added remote result for missing key: {}", key);
}
if (!createTombstone) {
continue;
}
}
Object value;
if (createTombstone) {
// the value is null in this case, so use TOKEN_TOMBSTONE
value = Token.TOMBSTONE;
} else {
value = entry.getObject();
}
if (value instanceof Throwable) {
continue;
}
// The following basicPutEntry needs to be done
// even if we do not have storage so that the
// correct events will be delivered to any callbacks we have.
long startPut = CachePerfStats.getStatTime();
validateKey(key);
@Released EntryEventImpl event = EntryEventImpl.create(this, Operation.LOCAL_LOAD_CREATE, key, value, callback, false, getMyId(), true);
try {
event.setFromServer(true);
event.setVersionTag(entry.getVersionTag());
if (!alreadyInvalid(key, event)) {
// bug #47716 - don't update if it's already here & invalid
TXStateProxy txState = this.cache.getTXMgr().internalSuspend();
try {
basicPutEntry(event, 0L);
} catch (ConcurrentCacheModificationException e) {
if (isDebugEnabled) {
logger.debug("getAll result for {} not stored in cache due to concurrent modification", key, e);
}
} finally {
this.cache.getTXMgr().internalResume(txState);
}
getCachePerfStats().endPut(startPut, event.isOriginRemote());
}
if (!createTombstone) {
allResults.put(key, value);
if (isTraceEnabled) {
logger.trace("Added remote result for getAll request: {}, {}", key, value);
}
}
} finally {
event.release();
}
}
}
} else {
// functionality. It needs to be rewritten more efficiently.
for (Object key : keys) {
try {
allResults.put(key, get(key, callback));
} catch (Exception e) {
logger.warn(LocalizedMessage.create(LocalizedStrings.LocalRegion_THE_FOLLOWING_EXCEPTION_OCCURRED_ATTEMPTING_TO_GET_KEY_0, key), e);
}
}
}
return allResults;
}
use of org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException in project geode by apache.
the class LocalRegion method basicBridgePut.
public boolean basicBridgePut(Object key, Object value, byte[] deltaBytes, boolean isObject, Object callbackArg, ClientProxyMembershipID memberId, boolean fromClient, EntryEventImpl clientEvent) throws TimeoutException, CacheWriterException {
EventID eventID = clientEvent.getEventId();
Object theCallbackArg = callbackArg;
long startPut = CachePerfStats.getStatTime();
if (fromClient) {
// GatewayEventCallbackArgument to store the event id.
if (isGatewaySenderEnabled()) {
theCallbackArg = new GatewaySenderEventCallbackArgument(theCallbackArg);
}
}
@Released final EntryEventImpl event = EntryEventImpl.create(this, Operation.UPDATE, key, null, /* new value */
theCallbackArg, false, /* origin remote */
memberId.getDistributedMember(), true, /* generateCallbacks */
eventID);
try {
event.setContext(memberId);
event.setDeltaBytes(deltaBytes);
// if this is a replayed operation we may already have a version tag
event.setVersionTag(clientEvent.getVersionTag());
// carry over the possibleDuplicate flag from clientEvent
event.setPossibleDuplicate(clientEvent.isPossibleDuplicate());
// serialized in a CachedDeserializable; otherwise store it directly as a byte[].
if (isObject && value instanceof byte[]) {
event.setSerializedNewValue((byte[]) value);
} else {
event.setNewValue(value);
}
boolean success = false;
try {
// can overwrite an existing key
boolean ifNew = false;
// can create a new key
boolean ifOld = false;
// use now
long lastModified = 0L;
// not okay to overwrite the DESTROYED token
boolean overwriteDestroyed = false;
success = basicUpdate(event, ifNew, ifOld, lastModified, overwriteDestroyed);
} catch (ConcurrentCacheModificationException ignore) {
// thrown by WAN conflicts
event.isConcurrencyConflict(true);
}
clientEvent.isConcurrencyConflict(event.isConcurrencyConflict());
if (success) {
clientEvent.setVersionTag(event.getVersionTag());
getCachePerfStats().endPut(startPut, event.isOriginRemote());
} else {
this.stopper.checkCancelInProgress(null);
}
return success;
} finally {
event.release();
}
}
use of org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException in project geode by apache.
the class CacheClientUpdater method handleDestroy.
/**
* locally destroy an entry
*
* @param clientMessage message describing the entry
*/
private void handleDestroy(Message clientMessage) {
String regionName = null;
Object key = null;
final boolean isDebugEnabled = logger.isDebugEnabled();
try {
this.isOpCompleted = false;
// Retrieve the data from the local-destroy message parts
if (isDebugEnabled) {
logger.debug("Received destroy message of length ({} bytes)", clientMessage.getPayloadLength());
}
int partCnt = 0;
Part regionNamePart = clientMessage.getPart(partCnt++);
Part keyPart = clientMessage.getPart(partCnt++);
Part callbackArgumentPart = clientMessage.getPart(partCnt++);
VersionTag versionTag = (VersionTag) clientMessage.getPart(partCnt++).getObject();
if (versionTag != null) {
versionTag.replaceNullIDs((InternalDistributedMember) this.endpoint.getMemberId());
}
regionName = regionNamePart.getString();
key = keyPart.getStringOrObject();
Part isInterestListPassedPart = clientMessage.getPart(partCnt++);
Part hasCqsPart = clientMessage.getPart(partCnt++);
boolean withInterest = ((Boolean) isInterestListPassedPart.getObject()).booleanValue();
boolean withCQs = ((Boolean) hasCqsPart.getObject()).booleanValue();
Object callbackArgument = callbackArgumentPart.getObject();
if (isDebugEnabled) {
logger.debug("Destroying entry for region: {} key: {} callbackArgument: {} withInterest={} withCQs={} version={}", regionName, key, callbackArgument, withInterest, withCQs, versionTag);
}
LocalRegion region = (LocalRegion) this.cacheHelper.getRegion(regionName);
if (region == null) {
if (isDebugEnabled && !quitting()) {
logger.debug("Region named {} does not exist", regionName);
}
} else if (region.hasServerProxy() && (withInterest || !withCQs)) {
EventID eventId = null;
try {
Part eid = clientMessage.getPart(clientMessage.getNumberOfParts() - 1);
eventId = (EventID) eid.getObject();
try {
region.basicBridgeClientDestroy(eventId.getDistributedMember(), key, callbackArgument, this.qManager.getState().getProcessedMarker() || !this.isDurableClient, eventId, versionTag);
} catch (ConcurrentCacheModificationException ignore) {
// allow CQs to be processed
}
this.isOpCompleted = true;
if (isDebugEnabled) {
logger.debug("Destroyed entry for region: {} key: {} callbackArgument: {}", regionName, key, callbackArgument);
}
} catch (EntryNotFoundException ignore) {
if (isDebugEnabled && !quitting()) {
logger.debug("Already destroyed entry for region: {} key: {} callbackArgument: {} eventId={}", regionName, key, callbackArgument, eventId.expensiveToString());
}
this.isOpCompleted = true;
}
}
if (withCQs) {
Part numCqsPart = clientMessage.getPart(partCnt++);
if (isDebugEnabled) {
logger.debug("Received message has CQ Event. Number of cqs interested in the event : {}", numCqsPart.getInt() / 2);
}
partCnt = processCqs(clientMessage, partCnt, numCqsPart.getInt(), clientMessage.getMessageType(), key, null);
this.isOpCompleted = true;
}
} catch (Exception e) {
String message = LocalizedStrings.CacheClientUpdater_THE_FOLLOWING_EXCEPTION_OCCURRED_WHILE_ATTEMPTING_TO_DESTROY_ENTRY_REGION_0_KEY_1.toLocalizedString(regionName, key);
handleException(message, e);
}
}
Aggregations