@Override void expireDestroy(EntryEventImpl event, boolean cacheWrite) { /* Early out before we throw a PrimaryBucketException because we're not primary */ if (needWriteLock(event) && !getBucketAdvisor().isPrimary()) { return; } try { super.expireDestroy(event, cacheWrite); return; } catch (PrimaryBucketException e) { // must have concurrently removed the primary return; } }
@Test public void lockKeysAndPrimaryReturnFalseIfDoesNotNeedWriteLock() { BucketRegion bucketRegion = spy(new BucketRegion(regionName, regionAttributes, partitionedRegion, cache, internalRegionArgs)); doReturn(false).when(bucketRegion).needWriteLock(event); assertThat(bucketRegion.lockKeysAndPrimary(event)).isFalse(); }
@Override protected DistributedRegion createAndDefineRegion(boolean isConcurrencyChecksEnabled, RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache) { BucketRegion br = new BucketRegion("testRegion", ra, null, cache, ira); // it is necessary to set the event tracker to initialized, since initialize() in not being // called on the instantiated region br.getEventTracker().setInitialized(); // since br is a real bucket region object, we need to tell mockito to monitor it br = spy(br); // doNothing().when(dm).addMembershipListener(any()); doNothing().when(br).distributeUpdateOperation(any(), anyLong()); doNothing().when(br).distributeDestroyOperation(any()); doNothing().when(br).distributeInvalidateOperation(any()); doNothing().when(br).distributeUpdateEntryVersionOperation(any()); doNothing().when(br).checkForPrimary(); doNothing().when(br).handleWANEvent(any()); doReturn(false).when(br).needWriteLock(any()); return br; }
/** * Checks to make sure that this node is primary, and locks the bucket to make sure the bucket * stays the primary bucket while the write is in progress. This method must be followed with * a call to releaseLockForKeysAndPrimary() if keys and primary are locked. */ boolean lockKeysAndPrimary(EntryEventImpl event) { if (!needWriteLock(event)) { return false; } if (cache.isCacheAtShutdownAll()) { throw cache.getCacheClosedException("Cache is shutting down"); } Object[] keys = getKeysToBeLocked(event); waitUntilLocked(keys); // it might wait for long time boolean lockedForPrimary = false; try { lockedForPrimary = doLockForPrimary(false); // tryLock is false means doLockForPrimary won't return false. // either the method returns true or fails with an exception assert lockedForPrimary : "expected doLockForPrimary returns true"; return lockedForPrimary; } finally { if (!lockedForPrimary) { removeAndNotifyKeys(keys); } } }