|
|
@ -8,6 +8,8 @@ import com.iflytop.gd.app.core.CraftsContext; |
|
|
|
import com.iflytop.gd.app.mapper.CraftsMapper; |
|
|
|
import com.iflytop.gd.app.model.entity.Crafts; |
|
|
|
import com.iflytop.gd.app.model.vo.CraftStatusVO; |
|
|
|
import com.iflytop.gd.common.exception.AppException; |
|
|
|
import com.iflytop.gd.common.result.ResultCode; |
|
|
|
import jakarta.annotation.PostConstruct; |
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
import org.springframework.statemachine.config.StateMachineFactory; |
|
|
@ -15,11 +17,14 @@ import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.List; |
|
|
|
import java.util.concurrent.*; |
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
import java.util.concurrent.ExecutorService; |
|
|
|
import java.util.concurrent.Executors; |
|
|
|
import java.util.concurrent.Future; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
/** |
|
|
|
* 工艺执行管理服务,每个 heatId 对应一个独立线程执行任务 |
|
|
|
* 工艺执行管理服务 |
|
|
|
*/ |
|
|
|
@Service |
|
|
|
@RequiredArgsConstructor |
|
|
@ -38,28 +43,42 @@ public class CraftsService extends ServiceImpl<CraftsMapper, Crafts> { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 开始执行工艺 |
|
|
|
* 配置工艺 |
|
|
|
*/ |
|
|
|
public synchronized boolean startCrafts(Long craftId, String heatId) { |
|
|
|
if (futureMap.containsKey(heatId)) { |
|
|
|
return false; |
|
|
|
public synchronized void setCraft(Long craftId, String heatId) { |
|
|
|
// 校验已有上下文状态,仅允许在 READY、STOPPED 或 FINISHED 状态下重置 |
|
|
|
CraftsContext existing = contextMap.get(heatId); |
|
|
|
if (existing != null) { |
|
|
|
CraftStates state = existing.getSm().getState().getId(); |
|
|
|
if (state == CraftStates.RUNNING || state == CraftStates.PAUSED) { |
|
|
|
throw new AppException(ResultCode.CRAFT_RUNNING); |
|
|
|
} |
|
|
|
clearCraftContext(heatId); |
|
|
|
} |
|
|
|
Crafts craft = this.getById(craftId); |
|
|
|
if (craft == null) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
CraftsContext ctx = new CraftsContext(heatId, craft, stateMachineFactory, webSocketService, craftsStepService); |
|
|
|
CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> { |
|
|
|
try { |
|
|
|
ctx.run(); |
|
|
|
} finally { |
|
|
|
contextMap.remove(heatId); |
|
|
|
futureMap.remove(heatId); |
|
|
|
} |
|
|
|
}, executor); |
|
|
|
CraftsContext ctx = new CraftsContext( |
|
|
|
heatId, |
|
|
|
craft, |
|
|
|
stateMachineFactory, |
|
|
|
webSocketService, |
|
|
|
craftsStepService |
|
|
|
); |
|
|
|
contextMap.put(heatId, ctx); |
|
|
|
futureMap.put(heatId, cf); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 启动执行工艺(需先调用 setCraft) |
|
|
|
*/ |
|
|
|
public synchronized void startCrafts(String heatId) { |
|
|
|
CraftsContext ctx = contextMap.get(heatId); |
|
|
|
if (ctx == null) { |
|
|
|
throw new AppException(ResultCode.CRAFT_CONTEXT_NULL); |
|
|
|
} |
|
|
|
if (futureMap.containsKey(heatId)) { |
|
|
|
throw new AppException(ResultCode.CRAFT_RUNNING); |
|
|
|
} |
|
|
|
Future<?> future = executor.submit(ctx); |
|
|
|
futureMap.put(heatId, future); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -67,9 +86,10 @@ public class CraftsService extends ServiceImpl<CraftsMapper, Crafts> { |
|
|
|
*/ |
|
|
|
public synchronized void pauseCrafts(String heatId) { |
|
|
|
CraftsContext ctx = contextMap.get(heatId); |
|
|
|
if (ctx != null) { |
|
|
|
ctx.pause(); |
|
|
|
if (ctx == null) { |
|
|
|
throw new AppException(ResultCode.CRAFT_CONTEXT_NULL); |
|
|
|
} |
|
|
|
ctx.pause(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -77,37 +97,45 @@ public class CraftsService extends ServiceImpl<CraftsMapper, Crafts> { |
|
|
|
*/ |
|
|
|
public synchronized void resumeCrafts(String heatId) { |
|
|
|
CraftsContext ctx = contextMap.get(heatId); |
|
|
|
if (ctx != null) { |
|
|
|
ctx.resume(); |
|
|
|
if (ctx == null) { |
|
|
|
throw new AppException(ResultCode.CRAFT_CONTEXT_NULL); |
|
|
|
} |
|
|
|
ctx.resume(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 停止执行工艺 |
|
|
|
* 停止执行工艺,不清除上下文 |
|
|
|
*/ |
|
|
|
public synchronized boolean stopCrafts(String heatId) { |
|
|
|
public synchronized void stopCrafts(String heatId) { |
|
|
|
CraftsContext ctx = contextMap.get(heatId); |
|
|
|
Future<?> future = futureMap.get(heatId); |
|
|
|
if (ctx != null && future != null) { |
|
|
|
ctx.stop(); |
|
|
|
future.cancel(true); |
|
|
|
contextMap.remove(heatId); |
|
|
|
futureMap.remove(heatId); |
|
|
|
return true; |
|
|
|
Future<?> future = futureMap.remove(heatId); |
|
|
|
if (ctx == null || future == null) { |
|
|
|
throw new AppException(ResultCode.CRAFT_CONTEXT_NULL); |
|
|
|
} |
|
|
|
return false; |
|
|
|
ctx.stop(); |
|
|
|
future.cancel(true); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 清理指定 heatId 的执行上下文和 Future |
|
|
|
*/ |
|
|
|
public synchronized void clearCraftContext(String heatId) { |
|
|
|
contextMap.remove(heatId); |
|
|
|
Future<?> future = futureMap.remove(heatId); |
|
|
|
if (future != null) future.cancel(true); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 查询指定 heatId 的执行状态 |
|
|
|
*/ |
|
|
|
public synchronized CraftStatusVO getStatus(String heatId) { |
|
|
|
public CraftStatusVO getStatus(String heatId) { |
|
|
|
CraftsContext ctx = contextMap.get(heatId); |
|
|
|
if (ctx == null) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
CraftStatusVO vo = new CraftStatusVO(); |
|
|
|
vo.setHeatId(heatId); |
|
|
|
vo.setCraftsId(ctx.getCraft().getId()); |
|
|
|
vo.setState(ctx.getSm().getState().getId()); |
|
|
|
vo.setCurrentIndex(ctx.getCurrentIndex()); |
|
|
|
vo.setSteps(ctx.getCraftsStepList()); |
|
|
@ -117,12 +145,13 @@ public class CraftsService extends ServiceImpl<CraftsMapper, Crafts> { |
|
|
|
/** |
|
|
|
* 查询所有正在执行的工艺状态 |
|
|
|
*/ |
|
|
|
public synchronized List<CraftStatusVO> getAllStatuses() { |
|
|
|
public List<CraftStatusVO> getAllStatuses() { |
|
|
|
return contextMap.entrySet().stream().map(entry -> { |
|
|
|
String heatId = entry.getKey(); |
|
|
|
String heatIdKey = entry.getKey(); |
|
|
|
CraftsContext ctx = entry.getValue(); |
|
|
|
CraftStatusVO vo = new CraftStatusVO(); |
|
|
|
vo.setHeatId(heatId); |
|
|
|
vo.setHeatId(heatIdKey); |
|
|
|
vo.setCraftsId(ctx.getCraft().getId()); |
|
|
|
vo.setState(ctx.getSm().getState().getId()); |
|
|
|
vo.setCurrentIndex(ctx.getCurrentIndex()); |
|
|
|
vo.setSteps(ctx.getCraftsStepList()); |
|
|
@ -147,9 +176,7 @@ public class CraftsService extends ServiceImpl<CraftsMapper, Crafts> { |
|
|
|
} |
|
|
|
|
|
|
|
public boolean deleteCrafts(String idsStr) { |
|
|
|
List<Long> ids = Arrays.stream(idsStr.split(",")) |
|
|
|
.map(Long::parseLong) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
List<Long> ids = Arrays.stream(idsStr.split(",")).map(Long::parseLong).collect(Collectors.toList()); |
|
|
|
return this.removeByIds(ids); |
|
|
|
} |
|
|
|
} |
|
|
|
} |