package com.zy.core.move;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
import com.zy.common.utils.RedisUtil;
|
import com.zy.core.enums.RedisKeyType;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Component;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Objects;
|
|
@Component
|
public class StationMoveSessionRegistry {
|
|
private static final int SESSION_EXPIRE_SECONDS = 60 * 60 * 24;
|
|
@Autowired
|
private RedisUtil redisUtil;
|
|
public synchronized StationMoveSession load(Integer taskNo) {
|
if (taskNo == null || taskNo <= 0 || redisUtil == null) {
|
return null;
|
}
|
Object sessionObj = redisUtil.get(buildKey(taskNo));
|
if (sessionObj == null) {
|
return null;
|
}
|
try {
|
return JSON.parseObject(String.valueOf(sessionObj), StationMoveSession.class);
|
} catch (Exception ignore) {
|
return null;
|
}
|
}
|
|
public synchronized void save(StationMoveSession session) {
|
if (session == null || session.getTaskNo() == null || session.getTaskNo() <= 0 || redisUtil == null) {
|
return;
|
}
|
long now = System.currentTimeMillis();
|
if (session.getCreatedAt() == null || session.getCreatedAt() <= 0L) {
|
session.setCreatedAt(now);
|
}
|
session.setUpdatedAt(now);
|
redisUtil.set(buildKey(session.getTaskNo()),
|
JSON.toJSONString(session, SerializerFeature.DisableCircularReferenceDetect),
|
SESSION_EXPIRE_SECONDS);
|
}
|
|
public synchronized void delete(Integer taskNo) {
|
if (taskNo == null || taskNo <= 0 || redisUtil == null) {
|
return;
|
}
|
redisUtil.del(buildKey(taskNo));
|
}
|
|
public synchronized boolean isActiveRoute(Integer taskNo, Integer routeVersion) {
|
StationMoveSession session = load(taskNo);
|
return session != null
|
&& session.isActive()
|
&& routeVersion != null
|
&& Objects.equals(routeVersion, session.getRouteVersion());
|
}
|
|
public synchronized boolean shouldSkipOutOrderDecision(Integer taskNo, Integer currentStationId) {
|
StationMoveSession session = load(taskNo);
|
if (session == null || !session.isActive() || currentStationId == null) {
|
return false;
|
}
|
List<Integer> fullPathStationIds = session.getFullPathStationIds();
|
if (fullPathStationIds == null || !fullPathStationIds.contains(currentStationId)) {
|
return false;
|
}
|
if (StationMoveDispatchMode.CIRCLE == session.getDispatchMode()) {
|
return true;
|
}
|
return !Objects.equals(currentStationId, session.getCurrentRouteTargetStationId());
|
}
|
|
public synchronized boolean isCircleDecisionStation(Integer taskNo, Integer currentStationId) {
|
StationMoveSession session = load(taskNo);
|
return session != null
|
&& session.isActive()
|
&& StationMoveDispatchMode.CIRCLE == session.getDispatchMode()
|
&& currentStationId != null
|
&& Objects.equals(currentStationId, session.getNextDecisionStationId());
|
}
|
|
public synchronized boolean isCircleTransitStation(Integer taskNo, Integer currentStationId) {
|
StationMoveSession session = load(taskNo);
|
if (session == null
|
|| !session.isActive()
|
|| StationMoveDispatchMode.CIRCLE != session.getDispatchMode()
|
|| currentStationId == null
|
|| Objects.equals(currentStationId, session.getNextDecisionStationId())) {
|
return false;
|
}
|
List<Integer> fullPathStationIds = session.getFullPathStationIds();
|
return fullPathStationIds != null && fullPathStationIds.contains(currentStationId);
|
}
|
|
public synchronized StationMoveSession registerPlan(Integer taskNo,
|
String threadImpl,
|
Integer currentStationId,
|
Integer businessTargetStationId,
|
StationMoveTriggerType triggerType,
|
StationMoveDispatchMode dispatchMode,
|
Integer currentRouteTargetStationId,
|
Integer nextDecisionStationId,
|
List<Integer> fullPathStationIds,
|
boolean cancelActive,
|
String cancelReason) {
|
if (taskNo == null || taskNo <= 0) {
|
return null;
|
}
|
StationMoveSession current = load(taskNo);
|
StationMoveSession next = new StationMoveSession();
|
next.setTaskNo(taskNo);
|
next.setThreadImpl(threadImpl);
|
next.setRouteVersion(current == null || current.getRouteVersion() == null ? 1 : current.getRouteVersion() + 1);
|
next.setCurrentStationId(currentStationId);
|
next.setBusinessTargetStationId(businessTargetStationId);
|
next.setTriggerType(triggerType);
|
next.setDispatchMode(dispatchMode);
|
next.setCurrentRouteTargetStationId(currentRouteTargetStationId);
|
next.setNextDecisionStationId(nextDecisionStationId);
|
next.setStatus(StationMoveSession.STATUS_WAITING);
|
next.setCancelReason(cancelReason);
|
next.setFullPathStationIds(copyIntegerList(fullPathStationIds));
|
next.setPathSignature(buildPathSignature(fullPathStationIds));
|
save(next);
|
return next;
|
}
|
|
public synchronized boolean isSameActivePath(Integer taskNo, List<Integer> fullPathStationIds) {
|
StationMoveSession session = load(taskNo);
|
if (session == null || !session.isActive()) {
|
return false;
|
}
|
return Objects.equals(session.getPathSignature(), buildPathSignature(fullPathStationIds));
|
}
|
|
public synchronized void markSegmentIssued(Integer taskNo, Integer routeVersion) {
|
StationMoveSession session = load(taskNo);
|
if (session == null || !Objects.equals(session.getRouteVersion(), routeVersion)) {
|
return;
|
}
|
session.setStatus(StationMoveSession.STATUS_RUNNING);
|
session.setLastIssuedAt(System.currentTimeMillis());
|
save(session);
|
}
|
|
public synchronized void updateCurrentStation(Integer taskNo, Integer routeVersion, Integer currentStationId) {
|
StationMoveSession session = load(taskNo);
|
if (session == null || !Objects.equals(session.getRouteVersion(), routeVersion)) {
|
return;
|
}
|
session.setCurrentStationId(currentStationId);
|
if (!StationMoveSession.STATUS_CANCEL_PENDING.equals(session.getStatus())) {
|
session.setStatus(StationMoveSession.STATUS_RUNNING);
|
}
|
save(session);
|
}
|
|
public synchronized void markCancelPending(Integer taskNo, String cancelReason) {
|
StationMoveSession session = load(taskNo);
|
if (session == null || !session.isActive()) {
|
return;
|
}
|
session.setStatus(StationMoveSession.STATUS_CANCEL_PENDING);
|
session.setCancelReason(cancelReason);
|
save(session);
|
}
|
|
public synchronized void markCancelled(Integer taskNo, Integer routeVersion, Integer currentStationId, String cancelReason) {
|
updateTerminal(taskNo, routeVersion, currentStationId, StationMoveSession.STATUS_CANCELLED, cancelReason);
|
}
|
|
public synchronized void markBlocked(Integer taskNo, Integer routeVersion, Integer currentStationId) {
|
updateTerminal(taskNo, routeVersion, currentStationId, StationMoveSession.STATUS_BLOCKED, null);
|
}
|
|
public synchronized void markTimeout(Integer taskNo, Integer routeVersion, Integer currentStationId) {
|
updateTerminal(taskNo, routeVersion, currentStationId, StationMoveSession.STATUS_TIMEOUT, null);
|
}
|
|
public synchronized void markFinished(Integer taskNo, Integer routeVersion, Integer currentStationId) {
|
updateTerminal(taskNo, routeVersion, currentStationId, StationMoveSession.STATUS_FINISHED, null);
|
}
|
|
public synchronized StationMoveSession buildCircleSessionCommandSource(Integer taskNo) {
|
StationMoveSession session = load(taskNo);
|
if (session == null || !session.isActive() || StationMoveDispatchMode.CIRCLE != session.getDispatchMode()) {
|
return null;
|
}
|
return session;
|
}
|
|
private void updateTerminal(Integer taskNo,
|
Integer routeVersion,
|
Integer currentStationId,
|
String status,
|
String cancelReason) {
|
StationMoveSession session = load(taskNo);
|
if (session == null || !Objects.equals(session.getRouteVersion(), routeVersion)) {
|
return;
|
}
|
session.setCurrentStationId(currentStationId);
|
session.setStatus(status);
|
session.setCancelReason(cancelReason);
|
save(session);
|
}
|
|
private String buildKey(Integer taskNo) {
|
return RedisKeyType.STATION_MOVE_SESSION_.key + taskNo;
|
}
|
|
private String buildPathSignature(List<Integer> fullPathStationIds) {
|
if (fullPathStationIds == null || fullPathStationIds.isEmpty()) {
|
return "";
|
}
|
StringBuilder builder = new StringBuilder();
|
for (Integer stationId : fullPathStationIds) {
|
if (stationId == null) {
|
continue;
|
}
|
if (builder.length() > 0) {
|
builder.append("->");
|
}
|
builder.append(stationId);
|
}
|
return builder.toString();
|
}
|
|
private List<Integer> copyIntegerList(List<Integer> source) {
|
List<Integer> result = new ArrayList<>();
|
if (source != null) {
|
result.addAll(source);
|
}
|
return result;
|
}
|
}
|