use of org.apache.geode.internal.util.concurrent.StoppableReentrantReadWriteLock.StoppableReadLock in project geode by apache.
the class PartitionedRegionDataStore method getParentBucketCreationLock.
private StoppableReadLock getParentBucketCreationLock() {
PartitionedRegion colocatedRegion = ColocationHelper.getColocatedRegion(this.partitionedRegion);
StoppableReadLock parentLock = null;
if (colocatedRegion != null) {
parentLock = colocatedRegion.getDataStore().bucketCreationLock.readLock();
return parentLock;
}
return null;
}
use of org.apache.geode.internal.util.concurrent.StoppableReentrantReadWriteLock.StoppableReadLock in project geode by apache.
the class PartitionedRegionDataStore method grabFreeBucket.
/**
* Attempts to map a bucket id to this node. Creates real storage for the bucket by adding a new
* Region to bucket2Map. Bucket creation is done under the d-lock on b2n region.
*
* @param possiblyFreeBucketId the identity of the bucket + @param mustBeNew boolean enforcing
* that the bucket must not already exist
* @param sender the member requesting the bucket
* @param moveSource Where we are moving the bucket from, if this is a move.
* @param forceCreation avoid any checks (with in reason) which might prevent bucket creation
* @param isRebalance true if bucket creation is directed by rebalancing
* @param replaceOffineData
* @return true if successful
*/
CreateBucketResult grabFreeBucket(final int possiblyFreeBucketId, final DistributedMember sender, final InternalDistributedMember moveSource, final boolean forceCreation, final boolean isRebalance, final boolean lockRedundancyLock, boolean replaceOffineData, InternalDistributedMember creationRequestor) {
final boolean isDebugEnabled = logger.isDebugEnabled();
long startTime = this.partitionedRegion.getPrStats().startBucketCreate(isRebalance);
boolean createdBucket = false;
PartitionedRegionObserver observer = PartitionedRegionObserverHolder.getInstance();
observer.beforeBucketCreation(this.partitionedRegion, possiblyFreeBucketId);
try {
CreateBucketResult result = CreateBucketResult.FAILED;
if (isManagingBucket(possiblyFreeBucketId)) {
if (isDebugEnabled) {
logger.debug("grabFreeBucket: VM {} already contains the bucket with bucketId={}{}{}", this.partitionedRegion.getMyId(), partitionedRegion.getPRId(), PartitionedRegion.BUCKET_ID_SEPARATOR, possiblyFreeBucketId);
}
this.partitionedRegion.checkReadiness();
return CreateBucketResult.ALREADY_EXISTS;
}
StoppableReadLock parentBucketCreationLock = getParentBucketCreationLock();
if (parentBucketCreationLock != null) {
parentBucketCreationLock.lock();
}
try {
if (!okToCreateChildBucket(possiblyFreeBucketId)) {
return CreateBucketResult.FAILED;
}
StoppableReadLock lock = this.bucketCreationLock.readLock();
// prevent destruction while creating buckets
lock.lock();
try {
// This counter is used by canAccomodateAnotherBucket to estimate if this member should
// accept another bucket
bucketCreatesInProgress.incrementAndGet();
if (this.partitionedRegion.isDestroyed()) {
return CreateBucketResult.FAILED;
}
// final boolean needsAllocation;
if (isDebugEnabled) {
this.logger.debug("grabFreeBucket: node list {} for bucketId={}{}{}", PartitionedRegionHelper.printCollection(this.partitionedRegion.getRegionAdvisor().getBucketOwners(possiblyFreeBucketId)), partitionedRegion.getPRId(), PartitionedRegion.BUCKET_ID_SEPARATOR, possiblyFreeBucketId);
}
// a stable view of bucket creation
if (!forceCreation) {
// ifRedudnancyNotSatisfied is false during bucket recovery
if (!canAccommodateAnotherBucket()) {
result = CreateBucketResult.FAILED;
return result;
}
}
ProxyBucketRegion buk = partitionedRegion.getRegionAdvisor().getProxyBucketArray()[possiblyFreeBucketId];
// also needs to be done under this lock
synchronized (buk) {
// DAN - this just needs to be done holding a lock for this particular bucket
if (!verifyBucketBeforeGrabbing(possiblyFreeBucketId)) {
result = CreateBucketResult.FAILED;
return result;
}
if (!this.isManagingBucket(possiblyFreeBucketId)) {
Integer possiblyFreeBucketIdInt = Integer.valueOf(possiblyFreeBucketId);
BucketRegion bukReg = null;
Object redundancyLock = lockRedundancyLock(moveSource, possiblyFreeBucketId, replaceOffineData);
// DAN - I hope this is ok to do without that bucket admin lock
try {
buk.initializePrimaryElector(creationRequestor);
if (getPartitionedRegion().getColocatedWith() == null) {
buk.getBucketAdvisor().setShadowBucketDestroyed(false);
}
if (getPartitionedRegion().isShadowPR()) {
getPartitionedRegion().getColocatedWithRegion().getRegionAdvisor().getBucketAdvisor(possiblyFreeBucketId).setShadowBucketDestroyed(false);
}
bukReg = createBucketRegion(possiblyFreeBucketId);
// won't think they need to satisfy redundancy
if (bukReg != null) {
// Let the data store know about the real bucket at this point
// so that other VMs which discover the real bucket via a
// profile exchange can send messages to the data store and
// safely use the bucket.
observer.beforeAssignBucket(this.partitionedRegion, possiblyFreeBucketId);
assignBucketRegion(bukReg.getId(), bukReg);
buk.setHosting(true);
bukReg.invokePartitionListenerAfterBucketCreated();
} else {
if (buk.getPartitionedRegion().getColocatedWith() == null) {
buk.getBucketAdvisor().setShadowBucketDestroyed(true);
// clear tempQueue for all the shadowPR buckets
clearAllTempQueueForShadowPR(buk.getBucketId());
}
}
} finally {
releaseRedundancyLock(redundancyLock);
if (bukReg == null) {
buk.clearPrimaryElector();
}
}
if (bukReg != null) {
if (isDebugEnabled) {
logger.debug("grabFreeBucket: mapped bucketId={}{}{} on node = {}", this.partitionedRegion.getPRId(), PartitionedRegion.BUCKET_ID_SEPARATOR, possiblyFreeBucketId, this.partitionedRegion.getMyId());
}
createdBucket = true;
result = CreateBucketResult.CREATED;
} else {
Assert.assertTrue(this.localBucket2RegionMap.get(possiblyFreeBucketIdInt) == null);
result = CreateBucketResult.FAILED;
}
} else {
// the bucket and the creator may have died
if (isDebugEnabled) {
logger.debug("grabFreeBucket: bucketId={}{}{} already mapped on VM = {}", this.partitionedRegion.getPRId(), PartitionedRegion.BUCKET_ID_SEPARATOR, possiblyFreeBucketId, partitionedRegion.getMyId());
}
result = CreateBucketResult.ALREADY_EXISTS;
}
if (isDebugEnabled) {
logger.debug("grabFreeBucket: Mapped bucketId={}{}{}", this.partitionedRegion.getPRId(), PartitionedRegion.BUCKET_ID_SEPARATOR, possiblyFreeBucketId);
}
}
} catch (RegionDestroyedException rde) {
RegionDestroyedException rde2 = new RegionDestroyedException(toString(), this.partitionedRegion.getFullPath());
rde2.initCause(rde);
throw rde2;
} catch (RedundancyAlreadyMetException e) {
if (isDebugEnabled) {
logger.debug("Redundancy already met {}{}{} assignment {}", this.partitionedRegion.getPRId(), PartitionedRegion.BUCKET_ID_SEPARATOR, possiblyFreeBucketId, localBucket2RegionMap.get(Integer.valueOf(possiblyFreeBucketId)));
}
result = CreateBucketResult.REDUNDANCY_ALREADY_SATISFIED;
} finally {
bucketCreatesInProgress.decrementAndGet();
// prevent destruction while creating buckets
lock.unlock();
}
} finally {
if (parentBucketCreationLock != null) {
parentBucketCreationLock.unlock();
}
}
this.partitionedRegion.checkReadiness();
this.partitionedRegion.checkClosed();
return result;
} finally {
this.partitionedRegion.getPrStats().endBucketCreate(startTime, createdBucket, isRebalance);
}
}
Aggregations