feature #IAY66T 修复LifeCycle重复载入问题

This commit is contained in:
DaleLee
2025-02-09 15:13:28 +08:00
parent 9e7be57e17
commit c3c64ce6e4
5 changed files with 66 additions and 27 deletions

View File

@@ -20,6 +20,7 @@ import com.yomahub.liteflow.enums.ParseModeEnum;
import com.yomahub.liteflow.exception.*;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.lifecycle.PostProcessChainExecuteLifeCycle;
import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.Node;
@@ -656,8 +657,14 @@ public class FlowExecutor {
LOG.warn("The rule cache capacity {} is too small, it is recommended to be greater than 30% of the number of chains", capacity);
}
RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity);
LifeCycleHolder.addLifeCycle(ruleCacheLifeCycle);
// 添加规则缓存生命周期
List<PostProcessChainExecuteLifeCycle> lifeCycleList = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList();
boolean exist = lifeCycleList.stream()
.anyMatch(lifeCycle -> lifeCycle instanceof RuleCacheLifeCycle);
if (!exist) {
RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity);
LifeCycleHolder.addLifeCycle(ruleCacheLifeCycle);
}
// 执行时才解析chain
liteflowConfig.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC);
}

View File

@@ -263,7 +263,8 @@ public class Chain implements Executable{
}
// 打印警告可用于排查临时chain与已有chain重名几乎不可能发生而将已有chain覆盖的情况
LOG.warn("The conditionList of chain[{}] is empty, temporarily using chain[{}] (now removed) to build it.", chainId, tempChainId);
LOG.warn("The conditionList of chain[{}] is empty, " +
"temporarily using chain[{}] (now removed) to build it.", chainId, tempChainId);
return tempConditionList;
}
}

View File

@@ -7,19 +7,17 @@ import com.github.benmanes.caffeine.cache.RemovalCause;
import com.github.benmanes.caffeine.cache.RemovalListener;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle;
import com.yomahub.liteflow.lifecycle.PostProcessChainExecuteLifeCycle;
import com.yomahub.liteflow.slot.Slot;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.concurrent.ConcurrentMap;
/**
* Chain执行前的缓存处理
* Chain 缓存处理
* @author DaleLee
* @since 2.13.0
*/
public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle {
public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle {
// 缓存
private final Cache<String, Object> cache;
// 在缓存中与key关联的虚拟值
@@ -33,7 +31,7 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle {
}
@Override
public void postProcessBeforeFlowExecute(String chainId, Slot slot) {
public void postProcessBeforeChainExecute(String chainId, Slot slot) {
// 记录chainId在缓存中
// 这里不记录实际的chain是因为chainId对应的chain之后有可能在FlowBus中被移除
// 或被更新替换以FlowBus中实际存在的chain为准
@@ -41,19 +39,21 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle {
}
@Override
public void postProcessAfterFlowExecute(String chainId, Slot slot) {
public void postProcessAfterChainExecute(String chainId, Slot slot) {
// chain执行时有可能在未编译前就被淘汰
// 结果使被淘汰的chain仍持有condition淘汰后就立刻编译
// 这里做兜底操作,执行完后再次判断其是否在缓存中
// 若不在则清空chain的condition
ConcurrentMap<@NonNull String, @NonNull Object> concurrentMap = cache.asMap();
concurrentMap.computeIfAbsent(chainId, key -> {
cleanChain(chainId);
return null;
});
// ConcurrentMap<@NonNull String, @NonNull Object> concurrentMap = cache.asMap();
// concurrentMap.computeIfAbsent(chainId, key -> {
// cleanChain(key);
// return null;
// });
}
public Cache<String, Object> getCache() {
return cache;
}
@@ -75,8 +75,11 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle {
if (ObjectUtil.isNull(chain)) {
return;
}
// 清空condition并将chain设置为未编译
chain.setConditionList(null);
// if (CollUtil.isEmpty(chain.getConditionList())) {
// return;
// }
// 将chain设置为未编译并清空condition
chain.setCompiled(false);
chain.setConditionList(null);
}
}

View File

@@ -10,6 +10,7 @@ import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.Condition;
import com.yomahub.liteflow.lifecycle.LifeCycleHolder;
import com.yomahub.liteflow.lifecycle.PostProcessChainExecuteLifeCycle;
import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle;
import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle;
import com.yomahub.liteflow.test.BaseTest;
@@ -90,7 +91,8 @@ public class RuleCacheSpringbootTest extends BaseTest {
Assertions.assertNull(conditionList);
}
}
Assertions.assertTrue(count <= 5);
//Assertions.assertTrue(count <= 5);
Assertions.assertEquals(count, 5);
}
// 测试开启规则缓存后进入缓存的chain可以正常被更新
@@ -191,7 +193,15 @@ public class RuleCacheSpringbootTest extends BaseTest {
Assertions.assertNull(conditionList);
}
}
Assertions.assertTrue(count <= 5);
//Assertions.assertTrue(count <= 5);
Assertions.assertEquals(5, count);
}
@Test
public void test7() {
for (int i = 0; i < 1000; i++) {
test6();
}
}
// 加载缓存, chain1~chain5
@@ -223,9 +233,9 @@ public class RuleCacheSpringbootTest extends BaseTest {
}
public Cache<String, Object> getCache() {
List<PostProcessFlowExecuteLifeCycle> lifeCycleList
= LifeCycleHolder.getPostProcessFlowExecuteLifeCycleList();
for (PostProcessFlowExecuteLifeCycle lifeCycle : lifeCycleList) {
List<PostProcessChainExecuteLifeCycle> lifeCycleList
= LifeCycleHolder.getPostProcessChainExecuteLifeCycleList();
for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) {
if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) {
RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle;
return ruleCacheLifeCycle.getCache();

View File

@@ -10,6 +10,7 @@ import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.Condition;
import com.yomahub.liteflow.lifecycle.LifeCycleHolder;
import com.yomahub.liteflow.lifecycle.PostProcessChainExecuteLifeCycle;
import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle;
import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle;
import com.yomahub.liteflow.test.BaseTest;
@@ -185,10 +186,26 @@ public class RuleCacheSpringTest extends BaseTest {
Assertions.assertTrue(CollUtil.isNotEmpty(conditionList));
count++;
} else {
Assertions.assertNull(conditionList);
Assertions.assertTrue(CollUtil.isEmpty(conditionList));
}
}
Assertions.assertTrue(count <= 5);
//Assertions.assertTrue(count <= 5);
//System.out.println(getCache().asMap().size());
Assertions.assertEquals(5, count);
}
@Test
public void test7() {
for (int i = 0; i < 1000; i++) {
test6();
}
}
@Test
public void test8() {
for (int i = 0; i < 1000; i++) {
testRuleCache2();
}
}
// 加载缓存, chain1~chain5
@@ -199,6 +216,7 @@ public class RuleCacheSpringTest extends BaseTest {
}
}
private void loadCache(int count) {
// 随机执行chain
Random random = new Random();
@@ -220,9 +238,9 @@ public class RuleCacheSpringTest extends BaseTest {
}
public Cache<String, Object> getCache() {
List<PostProcessFlowExecuteLifeCycle> lifeCycleList
= LifeCycleHolder.getPostProcessFlowExecuteLifeCycleList();
for (PostProcessFlowExecuteLifeCycle lifeCycle : lifeCycleList) {
List<PostProcessChainExecuteLifeCycle> lifeCycleList
= LifeCycleHolder.getPostProcessChainExecuteLifeCycleList();
for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) {
if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) {
RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle;
return ruleCacheLifeCycle.getCache();