263 lines
8.3 KiB
Java
263 lines
8.3 KiB
Java
package com.tuoheng.status.statemachine.manager;
|
||
|
||
import com.tuoheng.status.statemachine.events.Event;
|
||
import com.tuoheng.status.statemachine.status.Status;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.statemachine.StateMachine;
|
||
import org.springframework.statemachine.config.StateMachineFactory;
|
||
import org.springframework.statemachine.state.State;
|
||
import org.springframework.stereotype.Component;
|
||
|
||
import java.util.Map;
|
||
import java.util.concurrent.ConcurrentHashMap;
|
||
import java.util.logging.Logger;
|
||
|
||
/**
|
||
* 状态机管理器
|
||
* 用于管理多个状态机实例,通过ID获取和查询状态机
|
||
*/
|
||
@Component
|
||
public class StateMachineManager {
|
||
|
||
private static final Logger logger = Logger.getLogger(StateMachineManager.class.getName());
|
||
|
||
@Autowired
|
||
private StateMachineFactory<Status, Event> stateMachineFactory;
|
||
|
||
// 存储状态机实例的Map,key为状态机ID
|
||
private final Map<String, StateMachine<Status, Event>> stateMachineMap = new ConcurrentHashMap<>();
|
||
|
||
/**
|
||
* 创建或获取状态机实例
|
||
* 如果ID对应的状态机不存在,则创建新实例;如果存在,则返回现有实例
|
||
*
|
||
* @param machineId 状态机ID
|
||
* @return 状态机实例
|
||
*/
|
||
public StateMachine<Status, Event> getOrCreateStateMachine(String machineId) {
|
||
return stateMachineMap.computeIfAbsent(machineId, id -> {
|
||
logger.info("创建新状态机实例,ID: " + id);
|
||
StateMachine<Status, Event> stateMachine = stateMachineFactory.getStateMachine(id);
|
||
// 将machineId存储到扩展状态中
|
||
stateMachine.getExtendedState().getVariables().put("machineId", id);
|
||
// 启动状态机
|
||
stateMachine.start();
|
||
return stateMachine;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 获取状态机实例(如果不存在则返回null)
|
||
*
|
||
* @param machineId 状态机ID
|
||
* @return 状态机实例,如果不存在则返回null
|
||
*/
|
||
public StateMachine<Status, Event> getStateMachine(String machineId) {
|
||
return stateMachineMap.get(machineId);
|
||
}
|
||
|
||
/**
|
||
* 创建新的状态机实例(如果已存在则先停止并移除旧的)
|
||
*
|
||
* @param machineId 状态机ID
|
||
* @return 新创建的状态机实例
|
||
*/
|
||
public StateMachine<Status, Event> createStateMachine(String machineId) {
|
||
// 如果已存在,先停止并移除
|
||
StateMachine<Status, Event> existing = stateMachineMap.remove(machineId);
|
||
if (existing != null) {
|
||
logger.info("停止并移除已存在的状态机,ID: " + machineId);
|
||
try {
|
||
existing.stop();
|
||
} catch (Exception e) {
|
||
logger.warning("停止状态机时发生错误: " + e.getMessage());
|
||
}
|
||
}
|
||
|
||
// 创建新实例
|
||
logger.info("创建新状态机实例,ID: " + machineId);
|
||
StateMachine<Status, Event> stateMachine = stateMachineFactory.getStateMachine(machineId);
|
||
stateMachine.getExtendedState().getVariables().put("machineId", machineId);
|
||
stateMachine.start();
|
||
stateMachineMap.put(machineId, stateMachine);
|
||
return stateMachine;
|
||
}
|
||
|
||
/**
|
||
* 获取状态机的当前状态
|
||
*
|
||
* @param machineId 状态机ID
|
||
* @return 当前状态,如果状态机不存在则返回null
|
||
*/
|
||
public Status getCurrentStatus(String machineId) {
|
||
StateMachine<Status, Event> stateMachine = stateMachineMap.get(machineId);
|
||
if (stateMachine == null) {
|
||
logger.warning("状态机不存在,ID: " + machineId);
|
||
return null;
|
||
}
|
||
|
||
State<Status, Event> state = stateMachine.getState();
|
||
if (state == null) {
|
||
return null;
|
||
}
|
||
|
||
return state.getId();
|
||
}
|
||
|
||
/**
|
||
* 获取状态机的详细信息(包括当前状态和扩展状态)
|
||
*
|
||
* @param machineId 状态机ID
|
||
* @return 状态机信息,如果状态机不存在则返回null
|
||
*/
|
||
public StateMachineInfo getStateMachineInfo(String machineId) {
|
||
StateMachine<Status, Event> stateMachine = stateMachineMap.get(machineId);
|
||
if (stateMachine == null) {
|
||
return null;
|
||
}
|
||
|
||
StateMachineInfo info = new StateMachineInfo();
|
||
info.setMachineId(machineId);
|
||
|
||
State<Status, Event> state = stateMachine.getState();
|
||
if (state != null) {
|
||
info.setCurrentStatus(state.getId());
|
||
info.setIsSubState(state.isSubmachineState());
|
||
}
|
||
|
||
info.setExtendedState(stateMachine.getExtendedState().getVariables());
|
||
// 通过检查状态机是否有状态来判断是否在运行
|
||
// Spring StateMachine 3.2.0 没有 isRunning() 方法,使用状态判断
|
||
info.setIsRunning(state != null);
|
||
|
||
return info;
|
||
}
|
||
|
||
/**
|
||
* 移除状态机实例
|
||
*
|
||
* @param machineId 状态机ID
|
||
* @return 是否成功移除
|
||
*/
|
||
public boolean removeStateMachine(String machineId) {
|
||
StateMachine<Status, Event> stateMachine = stateMachineMap.remove(machineId);
|
||
if (stateMachine != null) {
|
||
logger.info("移除状态机实例,ID: " + machineId);
|
||
try {
|
||
stateMachine.stop();
|
||
return true;
|
||
} catch (Exception e) {
|
||
logger.warning("停止状态机时发生错误: " + e.getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 检查状态机是否存在
|
||
*
|
||
* @param machineId 状态机ID
|
||
* @return 是否存在
|
||
*/
|
||
public boolean exists(String machineId) {
|
||
return stateMachineMap.containsKey(machineId);
|
||
}
|
||
|
||
/**
|
||
* 获取所有状态机的ID列表
|
||
*
|
||
* @return 状态机ID集合
|
||
*/
|
||
public java.util.Set<String> getAllMachineIds() {
|
||
return stateMachineMap.keySet();
|
||
}
|
||
|
||
/**
|
||
* 获取当前管理的状态机数量
|
||
*
|
||
* @return 状态机数量
|
||
*/
|
||
public int getStateMachineCount() {
|
||
return stateMachineMap.size();
|
||
}
|
||
|
||
/**
|
||
* 清空所有状态机实例
|
||
*/
|
||
public void clearAll() {
|
||
logger.info("清空所有状态机实例,数量: " + stateMachineMap.size());
|
||
for (Map.Entry<String, StateMachine<Status, Event>> entry : stateMachineMap.entrySet()) {
|
||
try {
|
||
entry.getValue().stop();
|
||
} catch (Exception e) {
|
||
logger.warning("停止状态机时发生错误,ID: " + entry.getKey() + ", 错误: " + e.getMessage());
|
||
}
|
||
}
|
||
stateMachineMap.clear();
|
||
}
|
||
|
||
/**
|
||
* 状态机信息类
|
||
*/
|
||
public static class StateMachineInfo {
|
||
private String machineId;
|
||
private Status currentStatus;
|
||
private boolean isSubState;
|
||
private boolean isRunning;
|
||
private Map<Object, Object> extendedState;
|
||
|
||
// Getters and Setters
|
||
public String getMachineId() {
|
||
return machineId;
|
||
}
|
||
|
||
public void setMachineId(String machineId) {
|
||
this.machineId = machineId;
|
||
}
|
||
|
||
public Status getCurrentStatus() {
|
||
return currentStatus;
|
||
}
|
||
|
||
public void setCurrentStatus(Status currentStatus) {
|
||
this.currentStatus = currentStatus;
|
||
}
|
||
|
||
public boolean isSubState() {
|
||
return isSubState;
|
||
}
|
||
|
||
public void setIsSubState(boolean subState) {
|
||
isSubState = subState;
|
||
}
|
||
|
||
public boolean isRunning() {
|
||
return isRunning;
|
||
}
|
||
|
||
public void setIsRunning(boolean running) {
|
||
isRunning = running;
|
||
}
|
||
|
||
public Map<Object, Object> getExtendedState() {
|
||
return extendedState;
|
||
}
|
||
|
||
public void setExtendedState(Map<Object, Object> extendedState) {
|
||
this.extendedState = extendedState;
|
||
}
|
||
|
||
@Override
|
||
public String toString() {
|
||
return "StateMachineInfo{" +
|
||
"machineId='" + machineId + '\'' +
|
||
", currentStatus=" + currentStatus +
|
||
", isSubState=" + isSubState +
|
||
", isRunning=" + isRunning +
|
||
", extendedState=" + extendedState +
|
||
'}';
|
||
}
|
||
}
|
||
}
|