前言

首先,感谢大家对上一篇文章[业务可视化-让你的流程图”Run”起来]的支持。

分享一下近期我对这个项目的一些改进。

问题&改进

问题1:

流程运行开始后,异步执行,无法同步等待流程运行结束。

改进方法:
修正后流程(黄色部分为修改点):

调用代码:

// 异步调用(默认)flow.start();// 或者flow.start(false);// 同步调用flow.start(true);

问题2:

工程需要自己下载编译,无法自动引用。

改进方法:

将代码发布到maven仓库,然后可以用下面的方法调用:

Maven
<!-- https://mvnrepository.com/artifact/io.github.nobuglady/ladybugflow --><dependency><groupId>io.github.nobuglady</groupId><artifactId>ladybugflow</artifactId><version>0.0.1</version></dependency>
Gradle
// https://mvnrepository.com/artifact/io.github.nobuglady/ladybugflowimplementation 'io.github.nobuglady:ladybugflow:0.0.1'

发布到maven仓库遇到的坑:

1. 自动发布到maven仓库后,无法release。

首先,在创建了maven仓库的账号,并且完成相关配置后,发布流程如下

  a) 执行命令 mvn clean deploy

  b) 登录sonatype仓库,选择Staging Repository,将发布的工程选中,选择close。

  c) 登录sonatype仓库,选择Staging Repository,将发布的工程选中,选择release。

我遇到的问题:

  步骤a)执行完毕正常结束后,在sonatype仓库中,在Staging Repository中看不到自己的工程。

  但是搜索自己的工程可以看到已经上传的文件,也可以删除(release状态的文件应该不能删除)。

  所以判断是没有自动release,但也没法手工release,也没有任何错误提示。

解决方法:

  本地打包,手工将bundle.jar上传到Staging Repository,这样可以看到中间状态文件出的问题。

  果然,在手工上传成功后,自动运行的一些校验提示了一些pom文件问题,这可能是导致之前没有自动release的原因。

本地打包方法:

  a) 执行

mvn release:clean release:prepare

  b) 在target目录会看到类似下面的文件

ladybugflow-0.0.2.jarladybugflow-0.0.2.jar.ascladybugflow-0.0.2.pomladybugflow-0.0.2.pom.ascladybugflow-0.0.2-javadoc.jarladybugflow-0.0.2-javadoc.jar.ascladybugflow-0.0.2-sources.jarladybugflow-0.0.2-sources.jar.asc

c)进入到target目录,运行下面命令来打包

jar -cvf bundle.jar ladybugflow*

d)将打包好的jar文件手工上传到sonatype仓库

e)在sonatype仓库等待自己上传的文件到close状态,检查没问题后,选择release。

2. 提示 can not upload bundle Because is xxxx is a RELEASE repository

解决方法:

在pom.xm的版本号中加入-SNAPSHOT,比如

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>io.github.nobuglady</groupId><artifactId>ladybugflow</artifactId><packaging>jar</packaging><version>0.0.2-SNAPSHOT</version><name>ladybugflow</name>......

 

项目优点

优点,也是难点,但不是亮点。设计过程复杂(花了很长时间做改进),设计结果的话又极其简单(光看结果甚至会认为这个设计花不了一天)。

这种流程图设计的最大问题就是流程图状态的更新,比如等待前面的一个或多个节点运行结束后,启动自身节点。

第一版:每个节点提交到线程池后留下Future句柄,存起来。

后续节点运行前检查前面所有join到自己节点的Future句柄,是否完成。

可以阻塞检查,也可以sleep循环检查。

问题:

看似解决了问题,但隐患多多,比如所有的Future句柄都要存起来,那就涉及到这些东东的管理问题,想起来又兴奋又头大。

还有检查的时候是阻塞检查,还是sleep循环检查,还是。。。还是给每个节点加一个计数器,计数器清零则触发本节点执行。。。

改进:

将多线程转化为单线程或者可控的几个线程,把图(流程图)单独管理。

简单的说,是一个人(一个逻辑)单独的只负责更新图,根据每个节点的状态更新图。更新图后,输出后续要运行的节点给调用者。

这样就将节点运行,流程图状态分开管理。更新图的流程入口和出口分别对应两个队列:

入口:运行完毕的节点队列
出口:将要运行的节点队列

更新图的流程监听入口,得到一个消息(节点运行完毕)后,更新该节点对应的流程图,然后将后续要运行的节点输出给出口(将要运行的队列)。

节点的运行逻辑监听出口队列,然后怎么运行节点都可以了,在本地,在远程,在云端都无所谓,只要节点运行后告知入口队列,自己运行完毕,

则流程图会自动更新,并且往出口上发消息(后续要运行的节点),如下图所示:

这样设计的优点:

将多线程转化为单线程或者有限的几个线程处理,避免了高并发编程带来的各种问题和风险。

可以***对流程图模块进行升级,比如每条边加条件,根据条件进行更新,异常后对流程的更新,根据节点返回值进行更新,绑定动态逻辑等等,我可以专心的设计路程图更新的方法,不用考虑节点运行的事情。实现了流程图更新***。

可以***对节点运行模块进行升级,云端运行,api调用运行,shell运行,本地运行,分布式集群运行等等,不用考虑流程图怎么更新的问题。实现了节点运行***。

感谢您看文章读到这里。

最后

源码:https://github.com/nobuglady/ladybugflow