前言
首先,感謝大家對上一篇文章[業務視覺化-讓你的流程圖"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/ladybugflow
implementation '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.jar
ladybugflow-0.0.2.jar.asc
ladybugflow-0.0.2.pom
ladybugflow-0.0.2.pom.asc
ladybugflow-0.0.2-javadoc.jar
ladybugflow-0.0.2-javadoc.jar.asc
ladybugflow-0.0.2-sources.jar
ladybugflow-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執行,本地執行,分散式叢集執行等等,不用考慮流程圖怎麼更新的問題。實現了節點執行自由。
感謝您看文章讀到這裡。