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);
}
}
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;
}
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);
}
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());
}
}
}
Aggregations