Search in sources :

Example 1 with TokenCacheNode

use of com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode in project Sentinel by alibaba.

the class TokenCacheNodeManagerTest method testPutTokenCacheNode.

@Test
public void testPutTokenCacheNode() throws InterruptedException {
    setCurrentMillis(System.currentTimeMillis());
    for (long i = 0; i < 100; i++) {
        final TokenCacheNode node = new TokenCacheNode();
        node.setTokenId(i);
        node.setFlowId(111L);
        node.setResourceTimeout(10000L);
        node.setClientTimeout(10000L);
        node.setClientAddress("localhost");
        if (TokenCacheNodeManager.validToken(node)) {
            TokenCacheNodeManager.putTokenCacheNode(node.getTokenId(), node);
        }
    }
    Assert.assertEquals(100, TokenCacheNodeManager.getSize());
    for (int i = 0; i < 100; i++) {
        TokenCacheNodeManager.getTokenCacheNode((long) (Math.random() * 100));
    }
    List<Long> keyList = new ArrayList<>(TokenCacheNodeManager.getCacheKeySet());
    for (int i = 0; i < 100; i++) {
        Assert.assertEquals(i, (long) keyList.get(i));
        TokenCacheNodeManager.removeTokenCacheNode(i);
    }
}
Also used : TokenCacheNode(com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode) ArrayList(java.util.ArrayList) AbstractTimeBasedTest(com.alibaba.csp.sentinel.test.AbstractTimeBasedTest) Test(org.junit.Test)

Example 2 with TokenCacheNode

use of com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode in project Sentinel by alibaba.

the class ConcurrentClusterFlowChecker method acquireConcurrentToken.

public static TokenResult acquireConcurrentToken(/*@Valid*/
String clientAddress, FlowRule rule, int acquireCount) {
    long flowId = rule.getClusterConfig().getFlowId();
    AtomicInteger nowCalls = CurrentConcurrencyManager.get(flowId);
    if (nowCalls == null) {
        RecordLog.warn("[ConcurrentClusterFlowChecker] Fail to get nowCalls by flowId<{}>", flowId);
        return new TokenResult(TokenResultStatus.FAIL);
    }
    // check before enter the lock to improve the efficiency
    if (nowCalls.get() + acquireCount > calcGlobalThreshold(rule)) {
        ClusterServerStatLogUtil.log("concurrent|block|" + flowId, acquireCount);
        return new TokenResult(TokenResultStatus.BLOCKED);
    }
    // lock different nowCalls to improve the efficiency
    synchronized (nowCalls) {
        // check again whether the request can pass.
        if (nowCalls.get() + acquireCount > calcGlobalThreshold(rule)) {
            ClusterServerStatLogUtil.log("concurrent|block|" + flowId, acquireCount);
            return new TokenResult(TokenResultStatus.BLOCKED);
        } else {
            nowCalls.getAndAdd(acquireCount);
        }
    }
    ClusterServerStatLogUtil.log("concurrent|pass|" + flowId, acquireCount);
    TokenCacheNode node = TokenCacheNode.generateTokenCacheNode(rule, acquireCount, clientAddress);
    TokenCacheNodeManager.putTokenCacheNode(node.getTokenId(), node);
    TokenResult tokenResult = new TokenResult(TokenResultStatus.OK);
    tokenResult.setTokenId(node.getTokenId());
    return tokenResult;
}
Also used : TokenCacheNode(com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult)

Example 3 with TokenCacheNode

use of com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode in project Sentinel by alibaba.

the class ConcurrentClusterFlowChecker method releaseConcurrentToken.

public static TokenResult releaseConcurrentToken(/*@Valid*/
long tokenId) {
    TokenCacheNode node = TokenCacheNodeManager.getTokenCacheNode(tokenId);
    if (node == null) {
        RecordLog.info("[ConcurrentClusterFlowChecker] Token<{}> is already released", tokenId);
        return new TokenResult(TokenResultStatus.ALREADY_RELEASE);
    }
    FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(node.getFlowId());
    if (rule == null) {
        RecordLog.info("[ConcurrentClusterFlowChecker] Fail to get rule by flowId<{}>", node.getFlowId());
        return new TokenResult(TokenResultStatus.NO_RULE_EXISTS);
    }
    if (TokenCacheNodeManager.removeTokenCacheNode(tokenId) == null) {
        RecordLog.info("[ConcurrentClusterFlowChecker] Token<{}> is already released for flowId<{}>", tokenId, node.getFlowId());
        return new TokenResult(TokenResultStatus.ALREADY_RELEASE);
    }
    int acquireCount = node.getAcquireCount();
    AtomicInteger nowCalls = CurrentConcurrencyManager.get(node.getFlowId());
    nowCalls.getAndAdd(-1 * acquireCount);
    ClusterServerStatLogUtil.log("concurrent|release|" + rule.getClusterConfig().getFlowId(), acquireCount);
    return new TokenResult(TokenResultStatus.RELEASE_OK);
}
Also used : TokenCacheNode(com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode) TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule)

Example 4 with TokenCacheNode

use of com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode in project Sentinel by alibaba.

the class RegularExpireStrategy method clearToken.

private void clearToken() {
    long start = System.currentTimeMillis();
    List<Long> keyList = new ArrayList<>(localCache.keySet());
    for (int i = 0; i < executeCount && i < keyList.size(); i++) {
        // time out execution exit
        if (System.currentTimeMillis() - start > executeDuration) {
            RecordLog.info("[RegularExpireStrategy] End the process of expired token detection because of execute time is more than executeDuration: {}", executeDuration);
            break;
        }
        Long key = keyList.get(i);
        TokenCacheNode node = localCache.get(key);
        if (node == null) {
            continue;
        }
        // remove the token whose client is offline and saved for more than clientTimeout
        if (!ConnectionManager.isClientOnline(node.getClientAddress()) && node.getClientTimeout() - System.currentTimeMillis() < 0) {
            removeToken(key, node);
            RecordLog.info("[RegularExpireStrategy] Delete the expired token<{}> because of client offline for ruleId<{}>", node.getTokenId(), node.getFlowId());
            continue;
        }
        // If we find that token's save time is more than 2 times of the client's call resource timeout time,
        // the token will be determined to timeout.
        long resourceTimeout = ClusterFlowRuleManager.getFlowRuleById(node.getFlowId()).getClusterConfig().getResourceTimeout();
        if (System.currentTimeMillis() - node.getResourceTimeout() > resourceTimeout) {
            removeToken(key, node);
            RecordLog.info("[RegularExpireStrategy] Delete the expired token<{}> because of resource timeout for ruleId<{}>", node.getTokenId(), node.getFlowId());
        }
    }
}
Also used : TokenCacheNode(com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode) ArrayList(java.util.ArrayList)

Aggregations

TokenCacheNode (com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode)4 TokenResult (com.alibaba.csp.sentinel.cluster.TokenResult)2 ArrayList (java.util.ArrayList)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 FlowRule (com.alibaba.csp.sentinel.slots.block.flow.FlowRule)1 AbstractTimeBasedTest (com.alibaba.csp.sentinel.test.AbstractTimeBasedTest)1 Test (org.junit.Test)1