Java Code Examples for java.util.concurrent.locks.StampedLock#validate()

The following examples show how to use java.util.concurrent.locks.StampedLock#validate() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RegionRouteTable.java    From sofa-jraft with Apache License 2.0 6 votes vote down vote up
public Region getRegionById(final long regionId) {
    final StampedLock stampedLock = this.stampedLock;
    long stamp = stampedLock.tryOptimisticRead();
    // validate() emit a load-fence, but no store-fence.  So you should only have
    // load instructions inside a block of tryOptimisticRead() / validate(),
    // because it is meant to the a read-only operation, and therefore, it is fine
    // to use the loadFence() function to avoid re-ordering.
    Region region = safeCopy(this.regionTable.get(regionId));
    if (!stampedLock.validate(stamp)) {
        stamp = stampedLock.readLock();
        try {
            region = safeCopy(this.regionTable.get(regionId));
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
    return region;
}
 
Example 2
Source File: RegionRouteTable.java    From sofa-jraft with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the startKey of next region.
 */
public byte[] findStartKeyOfNextRegion(final byte[] key) {
    Requires.requireNonNull(key, "key");
    final StampedLock stampedLock = this.stampedLock;
    long stamp = stampedLock.tryOptimisticRead();
    // get the least key strictly greater than the given key
    byte[] nextStartKey = this.rangeTable.higherKey(key);
    if (!stampedLock.validate(stamp)) {
        stamp = stampedLock.readLock();
        try {
            // get the least key strictly greater than the given key
            nextStartKey = this.rangeTable.higherKey(key);
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
    return nextStartKey;
}
 
Example 3
Source File: RouteTable.java    From sofa-jraft with Apache License 2.0 6 votes vote down vote up
/**
 * Get the cached leader of the group, return it when found, null otherwise.
 * Make sure calls {@link #refreshLeader(CliClientService, String, int)} already
 * before invoke this method.
 *
 * @param groupId raft group id
 * @return peer of leader
 */
public PeerId selectLeader(final String groupId) {
    Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");

    final GroupConf gc = this.groupConfTable.get(groupId);
    if (gc == null) {
        return null;
    }
    final StampedLock stampedLock = gc.stampedLock;
    long stamp = stampedLock.tryOptimisticRead();
    PeerId leader = gc.leader;
    if (!stampedLock.validate(stamp)) {
        stamp = stampedLock.readLock();
        try {
            leader = gc.leader;
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
    return leader;
}
 
Example 4
Source File: RouteTable.java    From sofa-jraft with Apache License 2.0 6 votes vote down vote up
/**
 * Get the configuration by groupId, returns null when not found.
 *
 * @param groupId raft group id
 * @return configuration of the group id
 */
public Configuration getConfiguration(final String groupId) {
    Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");

    final GroupConf gc = this.groupConfTable.get(groupId);
    if (gc == null) {
        return null;
    }
    final StampedLock stampedLock = gc.stampedLock;
    long stamp = stampedLock.tryOptimisticRead();
    Configuration conf = gc.conf;
    if (!stampedLock.validate(stamp)) {
        stamp = stampedLock.readLock();
        try {
            conf = gc.conf;
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
    return conf;
}
 
Example 5
Source File: AbstractRegistryService.java    From Jupiter with Apache License 2.0 6 votes vote down vote up
@Override
public Map<ServiceMeta, Integer> consumers() {
    Map<ServiceMeta, Integer> result = Maps.newHashMap();
    for (Map.Entry<RegisterMeta.ServiceMeta, RegisterValue> entry : registries.entrySet()) {
        RegisterValue value = entry.getValue();
        final StampedLock stampedLock = value.lock;
        long stamp = stampedLock.tryOptimisticRead();
        int optimisticVal = value.metaSet.size();
        if (stampedLock.validate(stamp)) {
            result.put(entry.getKey(), optimisticVal);
            continue;
        }
        stamp = stampedLock.readLock();
        try {
            result.put(entry.getKey(), value.metaSet.size());
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
    return result;
}
 
Example 6
Source File: KeyedLockManager.java    From blazingcache with Apache License 2.0 5 votes vote down vote up
LockID useClientProvidedLockForKey(RawString key, long stamp) {
    StampedLock lock = getLockForKey(key);
    if (lock.validate(stamp)) {
        return LockID.VALIDATED_CLIENT_PROVIDED_LOCK;
    } else {
        return null;
    }
}
 
Example 7
Source File: ForkChainsMonitor.java    From nuls-v2 with MIT License 4 votes vote down vote up
@Override
protected void process(int chainId, ChainContext context, NulsLogger commonLog) {
    StampedLock lock = context.getLock();
    long stamp = lock.tryOptimisticRead();
    try {
        for (; ; stamp = lock.writeLock()) {
            if (stamp == 0L) {
                continue;
            }
            // possibly racy reads
            SortedSet<Chain> forkChains = BlockChainManager.getForkChains(chainId);
            if (!lock.validate(stamp)) {
                continue;
            }
            if (forkChains.isEmpty()) {
                break;
            }
            context.printChains();
            //遍历当前分叉链,与主链进行比对,找出最大高度差,与默认参数chainSwtichThreshold对比,确定要切换的分叉链
            Chain masterChain = BlockChainManager.getMasterChain(chainId);
            ChainParameters parameters = context.getParameters();
            int chainSwtichThreshold = parameters.getChainSwtichThreshold();
            Chain switchChain = new Chain();
            int maxHeightDifference = 0;
            for (Chain forkChain : forkChains) {
                int temp = (int) (forkChain.getEndHeight() - masterChain.getEndHeight());
                if (temp > maxHeightDifference) {
                    maxHeightDifference = temp;
                    switchChain = forkChain;
                }
            }
            commonLog.debug("chainId-" + chainId + ", maxHeightDifference:" + maxHeightDifference + ", chainSwtichThreshold:" + chainSwtichThreshold);
            //高度差不够
            if (maxHeightDifference < chainSwtichThreshold) {
                break;
            }
            stamp = lock.tryConvertToWriteLock(stamp);
            if (stamp == 0L) {
                continue;
            }
            // exclusive access
            //进行切换,切换前变更模块运行状态
            context.setStatus(StatusEnum.SWITCHING);
            ConsensusCall.notice(chainId, MODULE_WAITING);
            TransactionCall.notice(chainId, MODULE_WAITING);
            if (BlockChainManager.switchChain(chainId, masterChain, switchChain)) {
                commonLog.info("chainId-" + chainId + ", switchChain success");
            } else {
                commonLog.info("chainId-" + chainId + ", switchChain fail, auto rollback success");
            }
            context.printChains();
            ConsensusCall.notice(chainId, MODULE_WORKING);
            TransactionCall.notice(chainId, MODULE_WORKING);
            break;
        }
    } finally {
        context.setStatus(StatusEnum.RUNNING);
        if (StampedLock.isWriteLockStamp(stamp)) {
            lock.unlockWrite(stamp);
        }
    }
}
 
Example 8
Source File: OrphanChainsMaintainer.java    From nuls-v2 with MIT License 4 votes vote down vote up
@Override
protected void process(int chainId, ChainContext context, NulsLogger commonLog) {
    ChainParameters parameters = context.getParameters();
    int orphanChainMaxAge = parameters.getOrphanChainMaxAge();

    StampedLock lock = context.getLock();
    long stamp = lock.tryOptimisticRead();
    try {
        for (; ; stamp = lock.writeLock()) {
            if (stamp == 0L) {
                continue;
            }
            // possibly racy reads
            SortedSet<Chain> orphanChains = BlockChainManager.getOrphanChains(chainId);
            if (!lock.validate(stamp)) {
                continue;
            }
            if (orphanChains.isEmpty()) {
                break;
            }
            stamp = lock.tryConvertToWriteLock(stamp);
            if (stamp == 0L) {
                continue;
            }
            // exclusive access
            List<Node> availableNodes = NetworkCall.getAvailableNodes(chainId);
            //维护现有孤儿链,尝试在链首增加区块
            context.setStatus(UPDATE_ORPHAN_CHAINS);
            long l = System.nanoTime();
            for (Chain orphanChain : orphanChains) {
                maintainOrphanChain(chainId, orphanChain, availableNodes, orphanChainMaxAge);
                //孤儿链维护时间超过十秒,就退出
                if (System.nanoTime() - l > 10000000000L) {
                    break;
                }
            }
            break;
        }
    } finally {
        context.setStatus(RUNNING);
        if (StampedLock.isWriteLockStamp(stamp)) {
            lock.unlockWrite(stamp);
        }
    }
}
 
Example 9
Source File: StorageSizeMonitor.java    From nuls-v2 with MIT License 4 votes vote down vote up
/**
 * 清理分叉链
 *
 * @param chainId
 * @param heightRange
 * @param context
 */
private void forkChainsCleaner(int chainId, int heightRange, ChainContext context) {
    StampedLock lock = context.getLock();
    long stamp = lock.tryOptimisticRead();
    NulsLogger logger = context.getLogger();
    try {
        for (; ; stamp = lock.writeLock()) {
            if (stamp == 0L) {
                continue;
            }
            // possibly racy reads
            //1.清理链起始高度位于主链最新高度增减30(可配置)范围外的分叉链
            SortedSet<Chain> forkChains = BlockChainManager.getForkChains(chainId);
            if (!lock.validate(stamp)) {
                continue;
            }
            if (forkChains.isEmpty()) {
                break;
            }
            stamp = lock.tryConvertToWriteLock(stamp);
            if (stamp == 0L) {
                continue;
            }
            // exclusive access
            Chain masterChain = BlockChainManager.getMasterChain(chainId);
            long latestHeight = masterChain.getEndHeight();
            SortedSet<Chain> deleteSet = new TreeSet<>(Chain.COMPARATOR);
            //1.标记
            for (Chain forkChain : forkChains) {
                if (latestHeight - forkChain.getStartHeight() > heightRange || masterChain.getHashList().contains(forkChain.getEndHash())) {
                    //清理orphanChain,并递归清理orphanChain的所有子链
                    deleteSet.add(forkChain);
                }
            }
            //2.清理
            for (Chain chain : deleteSet) {
                BlockChainManager.deleteForkChain(chainId, chain, true);
                logger.info("remove fork chain, chain:" + chain);
            }
            break;
        }
    } finally {
        if (StampedLock.isWriteLockStamp(stamp)) {
            lock.unlockWrite(stamp);
        }
    }
}
 
Example 10
Source File: StorageSizeMonitor.java    From nuls-v2 with MIT License 4 votes vote down vote up
/**
 * 清理孤儿链
 * @param chainId
 * @param heightRange
 * @param context
 * @param orphanChainMaxAge
 */
private void orphanChainsCleaner(int chainId, int heightRange, ChainContext context, int orphanChainMaxAge) {
    StampedLock lock = context.getLock();
    long stamp = lock.tryOptimisticRead();
    NulsLogger logger = context.getLogger();
    try {
        for (; ; stamp = lock.writeLock()) {
            if (stamp == 0L) {
                continue;
            }
            // possibly racy reads
            //1.清理链起始高度位于主链最新高度增减30(可配置)范围外的孤儿链
            SortedSet<Chain> orphanChains = BlockChainManager.getOrphanChains(chainId);
            if (!lock.validate(stamp)) {
                continue;
            }
            if (orphanChains.isEmpty()) {
                break;
            }
            stamp = lock.tryConvertToWriteLock(stamp);
            if (stamp == 0L) {
                continue;
            }
            // exclusive access
            Chain masterChain = BlockChainManager.getMasterChain(chainId);
            long latestHeight = masterChain.getEndHeight();
            SortedSet<Chain> deleteSet = new TreeSet<>(Chain.COMPARATOR);
            //1.标记
            for (Chain orphanChain : orphanChains) {
                if (Math.abs(orphanChain.getStartHeight() - latestHeight) > heightRange || orphanChain.getAge().get() > orphanChainMaxAge) {
                    //清理orphanChain,并递归清理orphanChain的所有子链
                    deleteSet.add(orphanChain);
                }
            }
            //2.清理
            for (Chain chain : deleteSet) {
                BlockChainManager.deleteOrphanChain(chainId, chain);
                logger.info("remove orphan chain, chain:" + chain);
            }
            break;
        }
    } finally {
        if (StampedLock.isWriteLockStamp(stamp)) {
            lock.unlockWrite(stamp);
        }
    }
}