业务流程可视化-让你的流程图"Run"起来(7.运行状态持久化&轻量工作流支持)
前言
感谢大家阅读本项目系列文章和对项目的支持。
分享一下我对这个项目的新的改进。
之前项目做到了流程设计可视化和流程运行结果可视化。
本期发布的版本中实现了中间的运行过程的实时可视化,和流程状态持久化问题。
大家可以根据项目提供的接口自由扩展自己的工作流实现。
和大家分享一下:
流程状态实时可视化
首先看效果:
1. 不需要交互的自动化流程
点击预定按钮,自动完成预定的流程。
2. 需要交互的向导式流程
每点击一个按钮,流程向前走一步。
实现方式
工程基于SpringBoot实现,代码发布到下面的地址,大家可以自己酌情引用修改:
https://github.com/nobuglady/ladybugflow-ui
在ladybugFlow中,有一个接口,FlowUtil.dumpJson()
调用这个接口,可以实时的得到流程的状态的Json字符串,然后在页面上用得到Json来生成流程图即可。
对于【1. 不需要交互的自动化流程】,我们只需要启动流程后不停的拿到流程状态的Json即可完成实时可视化的效果。
流程启动代码:
@Service
public class Demo1Service {
@Autowired
private Demo1Flow demo1Flow;
/**
* 启动流程
*/
public void bookingHotel(String username) {
demo1Flow.startFlow(true, username);
}
}
对于【2. 需要交互的向导式流程】,流程运行到等待节点即进入等待状态。
这是需要外部运行节点,并将节点运行结果传给等待的节点,来唤醒该等待节点。
流程启动&节点状态更新代码:
@Service
public class Demo2Service {
@Autowired
private Demo2Flow demo2Flow;
/**
* 启动流程
*/
public String start(String username) {
return demo2Flow.startFlow(false, username);
}
/**
* 根据流程ID,节点ID和启动实例ID更新节点状态(点击【查询用户信息】结束后调用)
*/
public void searchUser(String historyId) {
FlowComponentFactory.getCompleteQueueSender().putCompleteNode(
"FLOW_2",
historyId,
"a1a38c2e-0e05-4c68-bd49-f12aea070876", // 节点ID【查询用户信息】
NodeStatusDetail.COMPLETE_SUCCESS,
"0");
}
/**
* 根据流程ID,节点ID和启动实例ID更新节点状态(点击【查询酒店信息】结束后调用)
*/
public void searchHotel(String historyId) {
FlowComponentFactory.getCompleteQueueSender().putCompleteNode(
"FLOW_2",
historyId,
"1a90a997-4390-470a-ae7c-626a725438d2",// 节点ID【查询酒店信息】
NodeStatusDetail.COMPLETE_SUCCESS,
"0");
}
/**
* 根据流程ID,节点ID和启动实例ID更新节点状态(点击【下单】结束后调用)
*/
public void order(String historyId) {
FlowComponentFactory.getCompleteQueueSender().putCompleteNode(
"FLOW_2",
historyId,
"52289e99-363d-4453-8077-ca8bdc6d35bf",// 节点ID【下单】
NodeStatusDetail.COMPLETE_SUCCESS,
"0");
}
/**
* 根据流程ID,节点ID和启动实例ID更新节点状态(点击【下单成功】结束后调用)
*/
public void success(String historyId) {
FlowComponentFactory.getCompleteQueueSender().putCompleteNode(
"FLOW_2",
historyId,
"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2",// 节点ID【下单成功】
NodeStatusDetail.COMPLETE_SUCCESS,
"0");
}
}
工作流的持久化方式设计
1. 工作流结构的持久化
ladybugflow用Json文件来做工作流结构的持久化。
工作流Json文件包括:流程信息,节点信息和边信息
ladybugflow提供了图形界面,可以用拖拽方式来完成工作流的设计和Json文件的生成。
2. 工作流状态的持久化
对于工作流状态的保存,我们默认提供了内存中保存的方式。
大家可以根据自己需要,选择数据库存储,文件存储,Redis,MogoDB存储等。
系统用三个实体来保存工作流的状态:
・流程历史实体
・节点历史实体
・边历史实体
和一个接口来描述对上述实体的操作:
io.github.nobuglady.network.fw.component.IFlowAccessor
大家只要实现上面的接口中的方法,即可以完成对工作流状态的保存。
比如存到数据库中,或者存到Redis中等。
对于自定义的持久化类,需要再ladybug.properties中做如下配置
flow.accessor = 你的持久化类全路径
下面我们以mysql为例,介绍数据操作接口的实现方式。
流程状态持久化实现(MySql)
接下来我们介绍mysql作为持久化的实现方式。
首先,需要做成实体对应的相关表,如下。
・流程历史表
・节点历史表
・边历史表
对应的SQL文件参考这里
https://github.com/nobuglady/ladybugflow-ui/blob/main/db/script.sql
然后,我们用sql的方式实现每个接口的方法。
我们针对每个表做一个Dao,实现针对表的操作
具体实现请参考这里:
最后我们将Dao集成到SpringBoot中,即完成了流程状态的持久化。
private HistoryFlowDao historyFlowDao;
private HistoryNodeDao historyNodeDao;
private HistoryEdgeDao historyEdgeDao;
public FlowAccessor() {
historyFlowDao = SpringContextBridge.getInstance().getHistoryFlowDao();
historyNodeDao = SpringContextBridge.getInstance().getHistoryNodeDao();
historyEdgeDao = SpringContextBridge.getInstance().getHistoryEdgeDao();
}
运行效果如下,可以看到系统已经通过发SQL的方式进行持久化查询与更新。
[I]2022/08/25 17:17:46.015 [your flow id][5bc43da8-7b11-4746-b886-31fd1c1bf754] pool-1-thread-2:execute node id:16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2
[I]2022/08/25 17:17:46.015 [your flow id][5bc43da8-7b11-4746-b886-31fd1c1bf754] pool-1-thread-2:execute node name:下单成功
下单成功开始 (模拟业务等待3秒)
下单成功结束
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Preparing: SELECT * FROM history_node WHERE flow_id = ? and node_id = ? and history_id = ?
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Parameters: your flow id(String), 16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2(String), 5bc43da8-7b11-4746-b886-31fd1c1bf754(String)
2022/08/25 17:17:49 DEBUG [Thread-4] - <== Total: 1
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Preparing: update history_node set node_status = ?, node_status_detail = ?, update_user = ?, update_time = now() where flow_id = ? and history_id = ? and node_id = ?
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Parameters: 22(Integer), 1(Integer), testUser(String), your flow id(String), 5bc43da8-7b11-4746-b886-31fd1c1bf754(String), 16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2(String)
2022/08/25 17:17:49 DEBUG [Thread-4] - <== Updates: 1
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Preparing: update history_node set node_status = ?, update_user = ?, update_time = now() where flow_id = ? and history_id = ? and node_id = ?
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Parameters: 100(Integer), testUser(String), your flow id(String), 5bc43da8-7b11-4746-b886-31fd1c1bf754(String), 16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2(String)
2022/08/25 17:17:49 DEBUG [Thread-4] - <== Updates: 1
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Preparing: SELECT * FROM history_edge WHERE flow_id = ? and history_id = ?
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Parameters: your flow id(String), 5bc43da8-7b11-4746-b886-31fd1c1bf754(String)
2022/08/25 17:17:49 DEBUG [Thread-4] - <== Total: 6
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Preparing: SELECT * FROM history_node WHERE flow_id = ? and history_id = ?
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Parameters: your flow id(String), 5bc43da8-7b11-4746-b886-31fd1c1bf754(String)
2022/08/25 17:17:49 DEBUG [Thread-4] - <== Total: 5
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Preparing: SELECT * FROM history_flow WHERE flow_id = ? and history_id = ?
2022/08/25 17:17:49 DEBUG [Thread-4] - ==> Parameters: your flow id(String), 5bc43da8-7b11-4746-b886-31fd1c1bf754(String)
2022/08/25 17:17:49 DEBUG [Thread-4] - <== Total: 1
大家可以根据自己的需要自由的扩展持久化的方式。
小型工作流的使用
对于工作流在业务系统中的使用,我们建议增加一个Flow层来处理工作流,如下:
Service层调用Flow层来实现工作流的启动,如下所示:
@Service
public class Demo1Service {
@Autowired
private Demo1Flow demo1Flow;
public void bookingHotel(String username) {
// 启动流程
demo1Flow.startFlow(true, username);
}
}
工作流的设计
首先需要在我们提供的工具中设计工作流。
然后点击【update json】按钮生成json文件。
然后将生成的Json文件放入Flow层中,并且建立一个同名的Java文件集成自FlowRunner,来提供工作流的启动。
工作流的监控
ladybugflow提供了一个监控工作流的例子,大家可以根据需要自己扩展。
浏览器打开 http://localhost:8080/list
可以显示所有的工作流,点击【detail】链接,即可查看工作流的详细状态。
点击【clear complete】按钮,即可删除所有已经完成的工作流,
点击【clear error】按钮,即可删除所有的运行错误的工作流。
后续会加入权限控制等功能,欢迎大家持续关注本项目。
感谢您阅读到这里
最后
源码:
https://github.com/nobuglady/ladybugflow
https://github.com/nobuglady/ladybugflow-ui
业务流程可视化-让你的流程图"Run"起来(7.运行状态持久化&轻量工作流支持)的更多相关文章
- 业务可视化-让你的流程图"Run"起来(2.问题与改进)
前言 首先,感谢大家对上一篇文章[业务可视化-让你的流程图"Run"起来]的支持. 分享一下近期我对这个项目的一些改进. 问题&改进 问题1: 流程运行开始后,异步执行,无 ...
- 业务可视化-让你的流程图"Run"起来(3.分支选择&跨语言分布式运行节点)
前言 首先,感谢大家对上一篇文章[业务可视化-让你的流程图"Run"起来(2.问题与改进)]的支持. 分享一下近期我对这个项目的一些改进. 1. 增加了分支选择工程,可以根据节点的 ...
- 业务可视化-让你的流程图"Run"起来(4.实际业务场景测试)
前言 首先,感谢大家对上一篇文章[业务可视化-让你的流程图"Run"起来(3.分支选择&跨语言分布式运行节点)]的支持. 下面我以实际业务场景为例,来介绍一下ladybug ...
- 业务可视化-让你的流程图"Run"起来(6.定时任务&Spring-Batch的集成)
前言 首先,感谢大家对上一篇文章[业务可视化-让你的流程图"Run"起来(5.SpringBoot集成&微服务编排)]的支持. 分享一下近期我对这个项目的一些改进. 在项目 ...
- 业务可视化-让你的流程图"Run"起来
前言 最近在研究业务可视化的问题,在日常的工作中,流程图和代码往往是分开管理的. 一个被维护多次的系统,到最后流程图和代码是否匹配这个都很难说. 于是一直有一个想法,让程序直接读流程图,根据流程图的配 ...
- FROONT – 超棒的可视化响应式网页设计工具
FROONT 是一个基于 Web 的设计工具,在浏览器中运行,使得各类可视化设计的人员都能进行响应式的网页设计,即使是那些没有任何编码技能的设计师.FROONT 使得响应式网页设计能够可视化操作,能够 ...
- easy-mock介绍
今天推荐一个好用的前端 mock 工具,Easy Mock,目前由大搜车无线架构团队进行维护,让我觉得特别好用的一点是 它支持 swagger(一个能称为框架的 API 书写工具),并能够基于 Swa ...
- 六种 主流ETL 工具的比较(DataPipeline,Kettle,Talend,Informatica,Datax ,Oracle Goldengate)
六种 主流ETL 工具的比较(DataPipeline,Kettle,Talend,Informatica,Datax ,Oracle Goldengate) 比较维度\产品 DataPipeline ...
- 自动化测试工具——JMeter
Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试静态和动态资源,例如静态文 ...
随机推荐
- go-zero微服务实战系列(五、缓存代码怎么写)
缓存是高并发服务的基础,毫不夸张的说没有缓存高并发服务就无从谈起.本项目缓存使用Redis,Redis是目前主流的缓存数据库,支持丰富的数据类型,其中集合类型的底层主要依赖:整数数组.双向链表.哈希表 ...
- 你真的很了解printf函数吗?
对C语言中经常使用的printf这个库函数,你是否真的吃透了呢? 系统化的学习C语言程序设计,是不是看过一两本C语言方面的经典著作就足够了呢?答案是显而易见的:不够.通过这种典型的入门级的学习方式,是 ...
- 【翻译】 For OData For C# play on RESTier
要获得统一的体验,请转到GitHub Issues询问问题,报告错误并要求功能.本文档适用于当前版本 1.0(第一个 GA).0.6.0版本文档参考0.6.0版本文档. 入门 1.1引言 OData ...
- Spring Data JPA系列3:JPA项目中核心场景与进阶用法介绍
大家好,又见面了. 到这里呢,已经是本SpringData JPA系列文档的第三篇了,先来回顾下前面两篇: 在第1篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring ...
- python——5行代码采集3000+上市公司信息
毕业季也到了找工作的季节了,很多小伙伴都会一家一家的公司去看,这得多浪费时间啊.今天用Python教大家怎么采集公司的信息,相信大家会很喜欢这个教程的,nice! 基本环境配置 版本:Python3 ...
- 这么强?!Erda MySQL Migrator:持续集成的数据库版本控制
为什么要进行数据库版本控制? 现代软件工程逐渐向持续集成.持续交付演进,软件一次性交付了事的场景逐渐无法满足复杂多变的业务需求,"如何高效地进行软件版本控制"成为我们面临的挑战.同 ...
- NuGetTools:批量上传、删除和显示NuGet包
快照 前言 NuGet是.NET开发必不可少的包管理工具,在日常更新版本过程中,可能需要批量发布 NuGet 包,也不可避免需要发布一些测试的包,后期想将这些测试或者过期的包删除掉.nuget.org ...
- 第2章 开始学习C++
说明 看<C++ Primer Plus>时整理的学习笔记,部分内容完全摘抄自<C++ Primer Plus>(第6版)中文版,Stephen Prata 著,张海龙 袁国忠 ...
- 如何在Rust中打印变量的类型?
#![feature(core_intrinsics)] fn print_type_of<T>(_: T) { println!("{}", unsafe { std ...
- Scanner练习
练习1 键盘输入两个数字求和 public static void main(String[] args) { Scanner in = new Scanner(System.in); System. ...