Browse Source

fix:修复工艺状态机执行顺序问题

tags/freeze
白凤吉 3 months ago
parent
commit
2ae8259ce3
  1. 19
      src/main/java/com/iflytop/gd/app/common/enums/CraftEvents.java
  2. 16
      src/main/java/com/iflytop/gd/app/common/enums/CraftStates.java
  3. 47
      src/main/java/com/iflytop/gd/app/config/CraftsStateMachineConfig.java
  4. 38
      src/main/java/com/iflytop/gd/app/core/CraftsContext.java

19
src/main/java/com/iflytop/gd/app/common/enums/CraftEvents.java

@ -1,5 +1,22 @@
package com.iflytop.gd.app.common.enums;
/**
* 工艺状态机事件枚举
*/
public enum CraftEvents {
START, STEP_COMPLETE, PAUSE, RESUME, STOP, ERROR_OCCUR
/** 启动工艺 */
START,
/** 单步完成 */
STEP_COMPLETE,
/** 暂停执行 */
PAUSE,
/** 恢复执行 */
RESUME,
/** 用户手动停止 */
STOP,
/** 执行过程中发生错误 */
ERROR_OCCUR,
/** 工艺正常完成 */
FINISH
}

16
src/main/java/com/iflytop/gd/app/common/enums/CraftStates.java

@ -1,5 +1,19 @@
package com.iflytop.gd.app.common.enums;
/**
* 工艺状态机状态枚举
*/
public enum CraftStates {
READY, RUNNING, PAUSED, STOPPED, ERROR, FINISHED
/** 初始状态,尚未启动工艺 */
READY,
/** 工艺正在执行中 */
RUNNING,
/** 工艺已暂停,等待恢复 */
PAUSED,
/** 工艺已被手动停止 */
STOPPED,
/** 工艺执行过程中发生错误 */
ERROR,
/** 工艺已正常执行完毕 */
FINISHED
}

47
src/main/java/com/iflytop/gd/app/config/CraftsStateMachineConfig.java

@ -26,20 +26,51 @@ public class CraftsStateMachineConfig
@Override
public void configure(StateMachineTransitionConfigurer<CraftStates, CraftEvents> trans) throws Exception {
trans
.withExternal().source(CraftStates.READY).target(CraftStates.RUNNING).event(CraftEvents.START)
// 启动
.withExternal()
.source(CraftStates.READY)
.target(CraftStates.RUNNING)
.event(CraftEvents.START)
.and()
.withInternal().source(CraftStates.RUNNING).event(CraftEvents.STEP_COMPLETE)
// 单步完成保持 RUNNING
.withInternal()
.source(CraftStates.RUNNING)
.event(CraftEvents.STEP_COMPLETE)
.and()
.withExternal().source(CraftStates.RUNNING).target(CraftStates.PAUSED).event(CraftEvents.PAUSE)
// 暂停
.withExternal()
.source(CraftStates.RUNNING)
.target(CraftStates.PAUSED)
.event(CraftEvents.PAUSE)
.and()
.withExternal().source(CraftStates.PAUSED).target(CraftStates.RUNNING).event(CraftEvents.RESUME)
// 恢复
.withExternal()
.source(CraftStates.PAUSED)
.target(CraftStates.RUNNING)
.event(CraftEvents.RESUME)
.and()
.withExternal().source(CraftStates.RUNNING).target(CraftStates.STOPPED).event(CraftEvents.STOP)
// 用户手动停止RUNNING STOPPED
.withExternal()
.source(CraftStates.RUNNING)
.target(CraftStates.STOPPED)
.event(CraftEvents.STOP)
.and()
.withExternal().source(CraftStates.PAUSED).target(CraftStates.STOPPED).event(CraftEvents.STOP)
// 用户手动停止PAUSED STOPPED
.withExternal()
.source(CraftStates.PAUSED)
.target(CraftStates.STOPPED)
.event(CraftEvents.STOP)
.and()
.withExternal().source(CraftStates.RUNNING).target(CraftStates.ERROR).event(CraftEvents.ERROR_OCCUR)
// 出错
.withExternal()
.source(CraftStates.RUNNING)
.target(CraftStates.ERROR)
.event(CraftEvents.ERROR_OCCUR)
.and()
.withExternal().source(CraftStates.RUNNING).target(CraftStates.FINISHED).event(CraftEvents.STOP);
// 正常完成
.withExternal()
.source(CraftStates.RUNNING)
.target(CraftStates.FINISHED)
.event(CraftEvents.FINISH);
}
}

38
src/main/java/com/iflytop/gd/app/core/CraftsContext.java

@ -34,7 +34,7 @@ public class CraftsContext implements Runnable {
this.ws = ws;
this.sm = factory.getStateMachine(heatId);
Mono.from(sm.startReactively()).block(); // READY -> RUNNING
Mono.from(sm.startReactively()).block();
Message<CraftEvents> startMsg = MessageBuilder.withPayload(CraftEvents.START).build();
Mono.from(sm.sendEvent(Mono.just(startMsg))).block();
sm.addStateListener(new StateMachineListenerAdapter<>() {
@ -43,6 +43,7 @@ public class CraftsContext implements Runnable {
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("heatId", heatId);
dataMap.put("event", to.getId());
dataMap.put("index", currentIndex);
ws.push(WebSocketMessageType.CRAFTS_STATE, dataMap);
}
});
@ -52,16 +53,18 @@ public class CraftsContext implements Runnable {
public void run() {
try {
for (; currentIndex < craftsStepList.size(); currentIndex++) {
if (sm.getState().getId() == CraftStates.STOPPED) break; // 如果收到 STOP 事件直接退出
if (sm.getState().getId() == CraftStates.STOPPED) break;
CraftsStep step = craftsStepList.get(currentIndex);
boolean ok = executeStep(step);
if (!ok) {
Message<CraftEvents> errorMsg = MessageBuilder.withPayload(CraftEvents.ERROR_OCCUR).build();
Mono.from(sm.sendEvent(Mono.just(errorMsg))).block();
Message<CraftEvents> errMsg = MessageBuilder.withPayload(CraftEvents.ERROR_OCCUR).build();
Mono.from(sm.sendEvent(Mono.just(errMsg))).block();
break;
}
Message<CraftEvents> completeMsg = MessageBuilder.withPayload(CraftEvents.STEP_COMPLETE).build();
Mono.from(sm.sendEvent(Mono.just(completeMsg))).block();
Message<CraftEvents> compMsg = MessageBuilder.withPayload(CraftEvents.STEP_COMPLETE).build();
Mono.from(sm.sendEvent(Mono.just(compMsg))).block();
// 如果被 PAUSE阻塞等待
synchronized (this) {
while (sm.getState().getId() == CraftStates.PAUSED) {
this.wait();
@ -69,8 +72,9 @@ public class CraftsContext implements Runnable {
}
}
if (sm.getState().getId() == CraftStates.RUNNING) {
Message<CraftEvents> stopMsg = MessageBuilder.withPayload(CraftEvents.STOP).build();
Mono.from(sm.sendEvent(Mono.just(stopMsg))).block();
Message<CraftEvents> finishMsg = MessageBuilder
.withPayload(CraftEvents.FINISH).build();
Mono.from(sm.sendEvent(Mono.just(finishMsg))).block();
}
} catch (InterruptedException e) {
Message<CraftEvents> stopMsg = MessageBuilder.withPayload(CraftEvents.STOP).build();
@ -79,31 +83,35 @@ public class CraftsContext implements Runnable {
}
private boolean executeStep(CraftsStep step) throws InterruptedException {
// TODO: 推送单步信息并实际调用设备服务
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("heatId", heatId);
dataMap.put("currentStep", step.getMethod());
ws.push(WebSocketMessageType.CRAFTS_STEP, dataMap);
Thread.sleep(3000);
// TODO: 调用 craftsStepService device 服务执行具体命令
return true;
}
// 暂停
public void pause() {
Message<CraftEvents> pauseMsg = MessageBuilder.withPayload(CraftEvents.PAUSE).build();
Mono.from(sm.sendEvent(Mono.just(pauseMsg))).block();
Message<CraftEvents> msg = MessageBuilder.withPayload(CraftEvents.PAUSE).build();
Mono.from(sm.sendEvent(Mono.just(msg))).block();
}
// 恢复
public void resume() {
Message<CraftEvents> resumeMsg = MessageBuilder.withPayload(CraftEvents.RESUME).build();
Mono.from(sm.sendEvent(Mono.just(resumeMsg))).block();
Message<CraftEvents> msg = MessageBuilder.withPayload(CraftEvents.RESUME).build();
Mono.from(sm.sendEvent(Mono.just(msg))).block();
synchronized (this) {
this.notify();
}
}
// 用户手动停止
public void stop() {
Message<CraftEvents> stopMsg = MessageBuilder.withPayload(CraftEvents.STOP).build();
Mono.from(sm.sendEvent(Mono.just(stopMsg))).block();
Message<CraftEvents> msg = MessageBuilder.withPayload(CraftEvents.STOP).build();
Mono.from(sm.sendEvent(Mono.just(msg))).block();
synchronized (this) {
this.notify();
}

Loading…
Cancel
Save