Search in sources :

Example 1 with StoppableReadLock

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;
}
Also used : StoppableReadLock(org.apache.geode.internal.util.concurrent.StoppableReentrantReadWriteLock.StoppableReadLock)

Example 2 with StoppableReadLock

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);
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) StoppableReadLock(org.apache.geode.internal.util.concurrent.StoppableReentrantReadWriteLock.StoppableReadLock)

Aggregations

StoppableReadLock (org.apache.geode.internal.util.concurrent.StoppableReentrantReadWriteLock.StoppableReadLock)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1