diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/flow/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/flow/Chain.java index 336cc0b07..4568bd40c 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/flow/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/flow/Chain.java @@ -22,12 +22,11 @@ import com.yomahub.liteflow.exception.FlowSystemException; import com.yomahub.liteflow.exception.WhenExecuteException; import com.yomahub.liteflow.property.LiteflowConfig; import com.yomahub.liteflow.property.LiteflowConfigGetter; -import com.yomahub.liteflow.util.ExecutorHelper; +import com.yomahub.liteflow.thread.ExecutorHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; import java.util.concurrent.*; -import java.util.function.Predicate; import java.util.stream.Collectors; /** @@ -116,7 +115,7 @@ public class Chain implements Executable { //这块涉及到挺多的多线程逻辑,所以注释比较详细,看到这里的童鞋可以仔细阅读 private void executeAsyncCondition(WhenCondition condition, Integer slotIndex, String requestId) throws Exception{ //此方法其实只会初始化一次Executor,不会每次都会初始化。Executor是唯一的 - ExecutorService parallelExecutor = TtlExecutors.getTtlExecutorService(ExecutorHelper.loadInstance().buildExecutor()); + ExecutorService parallelExecutor = ExecutorHelper.loadInstance().buildExecutor(); //获得liteflow的参数 LiteflowConfig liteflowConfig = LiteflowConfigGetter.get(); diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/ThreadExecutorServiceCreateException.java b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/ThreadExecutorServiceCreateException.java new file mode 100644 index 000000000..6c3442231 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/ThreadExecutorServiceCreateException.java @@ -0,0 +1,25 @@ +package com.yomahub.liteflow.exception; + +/** + * 并行多线程创建异常 + * @author Bryan.Zhang + * @since 2.6.6 + */ +public class ThreadExecutorServiceCreateException extends RuntimeException { + private static final long serialVersionUID = 1L; + + /** 异常信息 */ + private String message; + + public ThreadExecutorServiceCreateException(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java index 209615c56..f9873696c 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java @@ -36,6 +36,9 @@ public class LiteflowConfig { //slot的数量 private Integer slotSize; + //并行线程执行器class路径 + private String threadExecutorClass; + //异步线程最大等待秒数 private Integer whenMaxWaitSeconds; @@ -246,4 +249,16 @@ public class LiteflowConfig { public void setPrintBanner(Boolean printBanner) { this.printBanner = printBanner; } + + public String getThreadExecutorClass() { + if (StrUtil.isBlank(threadExecutorClass)){ + return "com.yomahub.liteflow.thread.LiteFlowDefaultExecutorBuilder"; + }else{ + return threadExecutorClass; + } + } + + public void setThreadExecutorClass(String threadExecutorClass) { + this.threadExecutorClass = threadExecutorClass; + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorBuilder.java new file mode 100644 index 000000000..a974a2261 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorBuilder.java @@ -0,0 +1,13 @@ +package com.yomahub.liteflow.thread; + +import java.util.concurrent.*; + +/** + * 并行多线程执行器构造器接口 + * @author Bryan.Zhang + * @since 2.6.6 + */ +public interface ExecutorBuilder { + + ExecutorService buildExecutor(); +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/util/ExecutorHelper.java b/liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorHelper.java similarity index 53% rename from liteflow-core/src/main/java/com/yomahub/liteflow/util/ExecutorHelper.java rename to liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorHelper.java index cd06e527c..cf9a78822 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/util/ExecutorHelper.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorHelper.java @@ -5,15 +5,15 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.util; +package com.yomahub.liteflow.thread; import cn.hutool.core.util.ObjectUtil; +import com.yomahub.liteflow.exception.ThreadExecutorServiceCreateException; import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.util.SpringAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicLong; /** @@ -71,56 +71,28 @@ public class ExecutorHelper { } } - /** - * 返回一个线程工厂,这是一个可以定义线程名字的线程工厂,返回的线程都将被命名. - * 创建的线程都是非后台线程. - * - * @param name 名称. - * @return 线程工厂实例. - */ - public ThreadFactory buildExecutorFactory(final String name) { - return buildExecutorFactory(name, false); - } - - /** - * 返回一个线程工厂,这是一个可以定义线程名字的线程工厂,返回的线程都将被命名. - * - * @param name 名称. - * @param daemon 是否为后台线程. - * @return 线程工厂实例. - */ - public ThreadFactory buildExecutorFactory(final String name, final boolean daemon) { - return new ThreadFactory() { - - private final AtomicLong number = new AtomicLong(); - - @Override - public Thread newThread(Runnable r) { - Thread newThread = Executors.defaultThreadFactory().newThread(r); - newThread.setName(name + "-" + number.getAndIncrement()); - newThread.setDaemon(daemon); - return newThread; - } - - }; - } - public ExecutorService buildExecutor() { if (ObjectUtil.isNull(executorService)){ LiteflowConfig liteflowConfig = SpringAware.getBean(LiteflowConfig.class); - //只有在非spring的场景下liteflowConfig才会为null - if (ObjectUtil.isNull(liteflowConfig)){ - liteflowConfig = new LiteflowConfig(); + + try{ + assert liteflowConfig != null; + ExecutorBuilder executorBuilder = (ExecutorBuilder)Class.forName(liteflowConfig.getThreadExecutorClass()).newInstance(); + executorService = executorBuilder.buildExecutor(); + }catch (Exception e){ + LOG.error(e.getMessage(), e); + throw new ThreadExecutorServiceCreateException(e.getMessage()); } - - executorService = new ThreadPoolExecutor(liteflowConfig.getWhenMaxWorkers(), - liteflowConfig.getWhenMaxWorkers(), - 0L, TimeUnit.MILLISECONDS, - new ArrayBlockingQueue<>(liteflowConfig.getWhenQueueLimit()), - buildExecutorFactory("liteflow-when-thead", false), - new ThreadPoolExecutor.AbortPolicy()); } return executorService; } + + public ExecutorService getExecutorService() { + return executorService; + } + + public void setExecutorService(ExecutorService executorService) { + this.executorService = executorService; + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/thread/LiteFlowDefaultExecutorBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/thread/LiteFlowDefaultExecutorBuilder.java new file mode 100644 index 000000000..c0ea6878f --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/thread/LiteFlowDefaultExecutorBuilder.java @@ -0,0 +1,41 @@ +package com.yomahub.liteflow.thread; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.ttl.threadpool.TtlExecutors; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.util.SpringAware; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicLong; + +/** + * LiteFlow默认的并行多线程执行器实现 + * @author Bryan.Zhang + * @since 2.6.6 + */ +public class LiteFlowDefaultExecutorBuilder implements ExecutorBuilder{ + @Override + public ExecutorService buildExecutor() { + LiteflowConfig liteflowConfig = SpringAware.getBean(LiteflowConfig.class); + //只有在非spring的场景下liteflowConfig才会为null + if (ObjectUtil.isNull(liteflowConfig)){ + liteflowConfig = new LiteflowConfig(); + } + + return TtlExecutors.getTtlExecutorService(new ThreadPoolExecutor(liteflowConfig.getWhenMaxWorkers(), + liteflowConfig.getWhenMaxWorkers(), + 0L, TimeUnit.MILLISECONDS, + new ArrayBlockingQueue<>(liteflowConfig.getWhenQueueLimit()), + new ThreadFactory() { + private final AtomicLong number = new AtomicLong(); + @Override + public Thread newThread(Runnable r) { + Thread newThread = Executors.defaultThreadFactory().newThread(r); + newThread.setName("lf-when-thead-" + number.getAndIncrement()); + newThread.setDaemon(false); + return newThread; + } + }, + new ThreadPoolExecutor.AbortPolicy())); + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowExecutorPoolShutdown.java b/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowExecutorPoolShutdown.java index a2eade017..bae10f630 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowExecutorPoolShutdown.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowExecutorPoolShutdown.java @@ -1,5 +1,6 @@ package com.yomahub.liteflow.util; +import com.yomahub.liteflow.thread.ExecutorHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java index 98e180f7d..aa2df2ae6 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java @@ -21,6 +21,9 @@ public class LiteflowProperty { //slot的数量 private int slotSize; + //并行线程执行器class路径 + private String threadExecutorClass; + //异步线程最大等待描述 private int whenMaxWaitSeconds; @@ -131,4 +134,12 @@ public class LiteflowProperty { public void setPrintBanner(boolean printBanner) { this.printBanner = printBanner; } + + public String getThreadExecutorClass() { + return threadExecutorClass; + } + + public void setThreadExecutorClass(String threadExecutorClass) { + this.threadExecutorClass = threadExecutorClass; + } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowExecutorAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowExecutorAutoConfiguration.java index f87967171..4219f16da 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowExecutorAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowExecutorAutoConfiguration.java @@ -1,7 +1,7 @@ package com.yomahub.liteflow.springboot.config; import com.yomahub.liteflow.property.LiteflowConfig; -import com.yomahub.liteflow.util.ExecutorHelper; +import com.yomahub.liteflow.thread.ExecutorHelper; import com.yomahub.liteflow.util.LiteFlowExecutorPoolShutdown; import com.yomahub.liteflow.util.SpringAware; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -30,7 +30,14 @@ public class LiteflowExecutorAutoConfiguration { return ExecutorHelper.loadInstance().buildExecutor(); } - @Bean + //为什么要注释掉这个@Bean? + //LiteFlowExecutorPoolShutdown这个类会在spring上下文移除这个bean的时候执行,也就是应用被停止或者kill的时候 + //这个类主要用于卸载掉线程池,会等待线程池中的线程执行完,再卸载掉,相当于一个钩子 + //但这段代码在实际中并没有太多用户,就算结束掉应用进程时很多公司也会优雅停机。就显得这段代码很鸡肋 + //之所以注释掉,是因为在单元测试中,每一个testcase结束时都会调这个方法。 + //当异步线程配置超时的时候。由于这个方法会去关闭掉线程池,会导致单元测试在所有一起运行时(单个运行没有问题)会出错 + //按理说这个方法会等待线程池里的全部线程执行完再销毁,但是事实上在单元测试中的确会报错。具体原因还没深究,由于这个类比较鸡肋,就干脆不注册了。 + //@Bean public LiteFlowExecutorPoolShutdown liteFlowExecutorPoolShutdown() { return new LiteFlowExecutorPoolShutdown(); } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java index 5967f9d6e..f242ed0bf 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java @@ -27,6 +27,7 @@ public class LiteflowPropertyAutoConfiguration { LiteflowConfig liteflowConfig = new LiteflowConfig(); liteflowConfig.setRuleSource(property.getRuleSource()); liteflowConfig.setSlotSize(property.getSlotSize()); + liteflowConfig.setThreadExecutorClass(property.getThreadExecutorClass()); liteflowConfig.setWhenMaxWaitSeconds(property.getWhenMaxWaitSeconds()); liteflowConfig.setEnableLog(liteflowMonitorProperty.isEnableLog()); liteflowConfig.setQueueLimit(liteflowMonitorProperty.getQueueLimit()); diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json index e63b086c7..b5b9a7880 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -30,6 +30,12 @@ "description": "Node definition for ZK configuration.", "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty" }, + { + "name": "liteflow.thread-executor-class", + "type": "java.lang.String", + "description": "Multi thread pool.", + "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty" + }, { "name": "liteflow.when-max-wait-seconds", "type": "java.lang.Integer", diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties index fcdaf5d7b..e23f1ae08 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties @@ -3,6 +3,7 @@ liteflow.print-banner=true liteflow.rule-source=config/flow.xml liteflow.zk-node=/lite-flow/flow liteflow.slot-size=1024 +liteflow.thread-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultExecutorBuilder liteflow.when-max-wait-seconds=15 liteflow.when-max-workers=16 liteflow.when-queue-limit=512 diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java index 5c2c4bd4d..5ff84fcb3 100644 --- a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java @@ -3,6 +3,7 @@ package com.yomahub.liteflow.test; import com.yomahub.liteflow.entity.data.DataBus; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.spring.ComponentScanner; +import com.yomahub.liteflow.thread.ExecutorHelper; import org.junit.AfterClass; public class BaseTest { @@ -11,5 +12,6 @@ public class BaseTest { public static void cleanScanCache(){ ComponentScanner.cleanCache(); FlowBus.cleanCache(); + ExecutorHelper.loadInstance().setExecutorService(null); } } diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadExecutor.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadExecutor.java new file mode 100644 index 000000000..0985362bb --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadExecutor.java @@ -0,0 +1,13 @@ +package com.yomahub.liteflow.test.customThreadPool; + +import com.yomahub.liteflow.thread.ExecutorBuilder; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class CustomThreadExecutor implements ExecutorBuilder { + @Override + public ExecutorService buildExecutor() { + return Executors.newCachedThreadPool(); + } +} diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadPoolSpringbootTest.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadPoolSpringbootTest.java new file mode 100644 index 000000000..67a7a2ebd --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadPoolSpringbootTest.java @@ -0,0 +1,43 @@ +package com.yomahub.liteflow.test.customThreadPool; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.entity.data.DefaultSlot; +import com.yomahub.liteflow.entity.data.LiteflowResponse; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; + +/** + * springboot环境下异步线程超时日志打印测试 + * @author Bryan.Zhang + * @since 2.6.4 + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/customThreadPool/application.properties") +@SpringBootTest(classes = CustomThreadPoolSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.customThreadPool.cmp"}) +public class CustomThreadPoolSpringbootTest extends BaseTest { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + @Resource + private FlowExecutor flowExecutor; + + @Test + public void testCustomThreadPool() throws Exception{ + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assert.assertTrue(response.isSuccess()); + Assert.assertFalse(response.getSlot().getData("threadName").toString().startsWith("lf-when-thead")); + } +} diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java new file mode 100644 index 000000000..32e859264 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.customThreadPool.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java new file mode 100644 index 000000000..cc7e0310c --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java @@ -0,0 +1,22 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.customThreadPool.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + this.getSlot().setData("threadName", Thread.currentThread().getName()); + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java new file mode 100644 index 000000000..276e035ba --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.customThreadPool.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } + +} diff --git a/liteflow-testcase-springboot/src/test/resources/customThreadPool/application.properties b/liteflow-testcase-springboot/src/test/resources/customThreadPool/application.properties new file mode 100644 index 000000000..c50032c04 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/resources/customThreadPool/application.properties @@ -0,0 +1,2 @@ +liteflow.rule-source=customThreadPool/flow.xml +liteflow.thread-executor-class=com.yomahub.liteflow.test.customThreadPool.CustomThreadExecutor \ No newline at end of file diff --git a/liteflow-testcase-springboot/src/test/resources/customThreadPool/flow.xml b/liteflow-testcase-springboot/src/test/resources/customThreadPool/flow.xml new file mode 100644 index 000000000..657f64cc3 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/resources/customThreadPool/flow.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/liteflow-testcase-springnative/pom.xml b/liteflow-testcase-springnative/pom.xml index 1bf509cdc..3c3fc7809 100644 --- a/liteflow-testcase-springnative/pom.xml +++ b/liteflow-testcase-springnative/pom.xml @@ -18,6 +18,12 @@ ${project.version} + + ch.qos.logback + logback-classic + 1.2.3 + + org.springframework spring-test diff --git a/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadExecutor.java b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadExecutor.java new file mode 100644 index 000000000..0985362bb --- /dev/null +++ b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadExecutor.java @@ -0,0 +1,13 @@ +package com.yomahub.liteflow.test.customThreadPool; + +import com.yomahub.liteflow.thread.ExecutorBuilder; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class CustomThreadExecutor implements ExecutorBuilder { + @Override + public ExecutorService buildExecutor() { + return Executors.newCachedThreadPool(); + } +} diff --git a/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadPoolSpringTest.java b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadPoolSpringTest.java new file mode 100644 index 000000000..05ab24f34 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadPoolSpringTest.java @@ -0,0 +1,37 @@ +package com.yomahub.liteflow.test.customThreadPool; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.entity.data.DefaultSlot; +import com.yomahub.liteflow.entity.data.LiteflowResponse; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; + +/** + * springboot环境下异步线程超时日志打印测试 + * @author Bryan.Zhang + * @since 2.6.4 + */ +@RunWith(SpringRunner.class) +@ContextConfiguration("classpath:/customThreadPool/application.xml") +public class CustomThreadPoolSpringTest extends BaseTest { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + @Resource + private FlowExecutor flowExecutor; + + @Test + public void testCustomThreadPool() throws Exception{ + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assert.assertTrue(response.isSuccess()); + Assert.assertFalse(response.getSlot().getData("threadName").toString().startsWith("lf-when-thead")); + } +} diff --git a/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java new file mode 100644 index 000000000..32e859264 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.customThreadPool.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java new file mode 100644 index 000000000..cc7e0310c --- /dev/null +++ b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java @@ -0,0 +1,22 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.customThreadPool.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + this.getSlot().setData("threadName", Thread.currentThread().getName()); + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java new file mode 100644 index 000000000..276e035ba --- /dev/null +++ b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.customThreadPool.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } + +} diff --git a/liteflow-testcase-springnative/src/test/resources/customThreadPool/application.xml b/liteflow-testcase-springnative/src/test/resources/customThreadPool/application.xml new file mode 100644 index 000000000..8641315a2 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/resources/customThreadPool/application.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/liteflow-testcase-springnative/src/test/resources/customThreadPool/flow.xml b/liteflow-testcase-springnative/src/test/resources/customThreadPool/flow.xml new file mode 100644 index 000000000..657f64cc3 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/resources/customThreadPool/flow.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/liteflow-testcase-springnative/src/test/resources/logback.xml b/liteflow-testcase-springnative/src/test/resources/logback.xml new file mode 100644 index 000000000..bfc3d1c5d --- /dev/null +++ b/liteflow-testcase-springnative/src/test/resources/logback.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + + + + + +