Преглед изворни кода

feature #I4E5NX 异步线程池自定义

bryan31 пре 3 година
родитељ
комит
8ca854c188
29 измењених фајлова са 452 додато и 52 уклоњено
  1. 2 3
      liteflow-core/src/main/java/com/yomahub/liteflow/entity/flow/Chain.java
  2. 25 0
      liteflow-core/src/main/java/com/yomahub/liteflow/exception/ThreadExecutorServiceCreateException.java
  3. 15 0
      liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java
  4. 13 0
      liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorBuilder.java
  5. 19 47
      liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorHelper.java
  6. 41 0
      liteflow-core/src/main/java/com/yomahub/liteflow/thread/LiteFlowDefaultExecutorBuilder.java
  7. 1 0
      liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowExecutorPoolShutdown.java
  8. 11 0
      liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java
  9. 9 2
      liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowExecutorAutoConfiguration.java
  10. 1 0
      liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java
  11. 6 0
      liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
  12. 1 0
      liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties
  13. 2 0
      liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java
  14. 13 0
      liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadExecutor.java
  15. 43 0
      liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadPoolSpringbootTest.java
  16. 20 0
      liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java
  17. 22 0
      liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java
  18. 21 0
      liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java
  19. 2 0
      liteflow-testcase-springboot/src/test/resources/customThreadPool/application.properties
  20. 6 0
      liteflow-testcase-springboot/src/test/resources/customThreadPool/flow.xml
  21. 6 0
      liteflow-testcase-springnative/pom.xml
  22. 13 0
      liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadExecutor.java
  23. 37 0
      liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/CustomThreadPoolSpringTest.java
  24. 20 0
      liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java
  25. 22 0
      liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java
  26. 21 0
      liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java
  27. 24 0
      liteflow-testcase-springnative/src/test/resources/customThreadPool/application.xml
  28. 6 0
      liteflow-testcase-springnative/src/test/resources/customThreadPool/flow.xml
  29. 30 0
      liteflow-testcase-springnative/src/test/resources/logback.xml

+ 2 - 3
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();

+ 25 - 0
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;
+    }
+}

+ 15 - 0
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;
+    }
 }

+ 13 - 0
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();
+}

+ 19 - 47
liteflow-core/src/main/java/com/yomahub/liteflow/util/ExecutorHelper.java → 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;
+    }
 }

+ 41 - 0
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()));
+    }
+}

+ 1 - 0
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;
 

+ 11 - 0
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;
+    }
 }

+ 9 - 2
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();
     }

+ 1 - 0
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());

+ 6 - 0
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",

+ 1 - 0
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

+ 2 - 0
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);
     }
 }

+ 13 - 0
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();
+    }
+}

+ 43 - 0
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<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "arg");
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertFalse(response.getSlot().getData("threadName").toString().startsWith("lf-when-thead"));
+    }
+}

+ 20 - 0
liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java

@@ -0,0 +1,20 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @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!");
+	}
+}

+ 22 - 0
liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java

@@ -0,0 +1,22 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @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!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java

@@ -0,0 +1,21 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @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!");
+	}
+
+}

+ 2 - 0
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

+ 6 - 0
liteflow-testcase-springboot/src/test/resources/customThreadPool/flow.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+    <chain name="chain1">
+        <when value="a,b,c"/>
+    </chain>
+</flow>

+ 6 - 0
liteflow-testcase-springnative/pom.xml

@@ -18,6 +18,12 @@
             <version>${project.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.2.3</version>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>

+ 13 - 0
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();
+    }
+}

+ 37 - 0
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<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "arg");
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertFalse(response.getSlot().getData("threadName").toString().startsWith("lf-when-thead"));
+    }
+}

+ 20 - 0
liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/ACmp.java

@@ -0,0 +1,20 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @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!");
+	}
+}

+ 22 - 0
liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/BCmp.java

@@ -0,0 +1,22 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @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!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/customThreadPool/cmp/CCmp.java

@@ -0,0 +1,21 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @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!");
+	}
+
+}

+ 24 - 0
liteflow-testcase-springnative/src/test/resources/customThreadPool/application.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="http://www.springframework.org/schema/beans"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
+       http://www.springframework.org/schema/context
+       http://www.springframework.org/schema/context/spring-context-4.0.xsd">
+
+    <context:component-scan base-package="com.yomahub.liteflow.test.customThreadPool.cmp" />
+
+    <bean id="springAware" class="com.yomahub.liteflow.util.SpringAware"/>
+
+    <bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
+
+    <bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
+        <property name="ruleSource" value="customThreadPool/flow.xml"/>
+        <property name="threadExecutorClass" value="com.yomahub.liteflow.test.customThreadPool.CustomThreadExecutor"/>
+    </bean>
+
+    <bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
+        <property name="liteflowConfig" ref="liteflowConfig"/>
+    </bean>
+</beans>

+ 6 - 0
liteflow-testcase-springnative/src/test/resources/customThreadPool/flow.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+    <chain name="chain1">
+        <when value="a,b,c"/>
+    </chain>
+</flow>

+ 30 - 0
liteflow-testcase-springnative/src/test/resources/logback.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright 2010-2011 The myBatis Team
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+        http://www.apache.org/licenses/LICENSE-2.0
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<configuration debug="false">
+    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
+    <property name="APP_NAME" value="testcase"/>
+    <property name="LOG_HOME" value="./logs" />
+    <!-- 控制台输出 -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 日志输出级别 -->
+    <root level="INFO">
+        <appender-ref ref="STDOUT" />
+    </root>
+</configuration>