| | |
| | | package com.zy.core.trace; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.asrs.domain.vo.StationTaskTraceEventVo; |
| | | import com.zy.asrs.domain.vo.StationTaskTraceSegmentVo; |
| | | import com.zy.asrs.domain.vo.StationTaskTraceVo; |
| | | import com.zy.asrs.entity.WrkMast; |
| | | import com.zy.asrs.service.WrkMastService; |
| | | import com.zy.common.utils.RedisUtil; |
| | | import com.zy.core.enums.WrkStsType; |
| | | import com.zy.core.model.command.StationCommand; |
| | | import com.zy.core.enums.RedisKeyType; |
| | | import lombok.Data; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.ArrayList; |
| | |
| | | |
| | | private static final int MAX_EVENT_COUNT = 200; |
| | | private static final long TERMINAL_KEEP_MS = 30L * 60L * 1000L; |
| | | private static final String TRACE_CACHE_KEY = RedisKeyType.STATION_TASK_TRACE_REGISTRY.key; |
| | | |
| | | public static final String STATUS_WAITING = "WAITING"; |
| | | public static final String STATUS_RUNNING = "RUNNING"; |
| | |
| | | public static final String STATUS_FINISHED = "FINISHED"; |
| | | public static final String STATUS_REROUTED = "REROUTED"; |
| | | |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | @Autowired |
| | | private WrkMastService wrkMastService; |
| | | |
| | | private final Map<Integer, TraceTaskState> taskStateMap = new ConcurrentHashMap<>(); |
| | | private volatile boolean loadedFromRedis = false; |
| | | |
| | | public TraceRegistration registerPlan(Integer taskNo, |
| | | String threadImpl, |
| | |
| | | return new TraceRegistration(); |
| | | } |
| | | |
| | | ensureCacheLoaded(); |
| | | cleanupExpired(); |
| | | TraceTaskState taskState = taskStateMap.computeIfAbsent(taskNo, TraceTaskState::new); |
| | | return taskState.registerPlan(threadImpl, startStationId, currentStationId, finalTargetStationId, |
| | | TraceRegistration registration = taskState.registerPlan(threadImpl, startStationId, currentStationId, finalTargetStationId, |
| | | copyIntegerList(localPathStationIds), copySegmentList(localSegmentList)); |
| | | persistState(taskState); |
| | | return registration; |
| | | } |
| | | |
| | | public void markSegmentIssued(Integer taskNo, |
| | |
| | | String eventType, |
| | | String message, |
| | | Map<String, Object> details) { |
| | | ensureCacheLoaded(); |
| | | TraceTaskState state = taskStateMap.get(taskNo); |
| | | if (state == null) { |
| | | return; |
| | | } |
| | | state.markSegmentIssued(traceVersion, command, eventType, message, details); |
| | | persistState(state); |
| | | } |
| | | |
| | | public void updateProgress(Integer taskNo, |
| | |
| | | String eventType, |
| | | String message, |
| | | Map<String, Object> details) { |
| | | ensureCacheLoaded(); |
| | | TraceTaskState state = taskStateMap.get(taskNo); |
| | | if (state == null) { |
| | | return; |
| | | } |
| | | state.updateProgress(traceVersion, currentStationId, eventType, message, details); |
| | | persistState(state); |
| | | } |
| | | |
| | | public void markBlocked(Integer taskNo, |
| | | Integer traceVersion, |
| | | Integer currentStationId, |
| | | Map<String, Object> details) { |
| | | ensureCacheLoaded(); |
| | | TraceTaskState state = taskStateMap.get(taskNo); |
| | | if (state == null) { |
| | | return; |
| | | } |
| | | state.markTerminal(traceVersion, STATUS_BLOCKED, currentStationId, currentStationId, |
| | | "BLOCKED", "输送任务运行堵塞", details); |
| | | persistState(state); |
| | | } |
| | | |
| | | public void markCancelled(Integer taskNo, |
| | | Integer traceVersion, |
| | | Integer currentStationId, |
| | | Map<String, Object> details) { |
| | | ensureCacheLoaded(); |
| | | TraceTaskState state = taskStateMap.get(taskNo); |
| | | if (state == null) { |
| | | return; |
| | | } |
| | | state.markTerminal(traceVersion, STATUS_CANCELLED, currentStationId, null, |
| | | "CANCELLED", "输送任务收到取消信号", details); |
| | | persistState(state); |
| | | } |
| | | |
| | | public void markTimeout(Integer taskNo, |
| | | Integer traceVersion, |
| | | Integer currentStationId, |
| | | Map<String, Object> details) { |
| | | ensureCacheLoaded(); |
| | | TraceTaskState state = taskStateMap.get(taskNo); |
| | | if (state == null) { |
| | | return; |
| | | } |
| | | state.markTerminal(traceVersion, STATUS_TIMEOUT, currentStationId, null, |
| | | "TIMEOUT", "输送任务长时间无法定位当前位置", details); |
| | | persistState(state); |
| | | } |
| | | |
| | | public void markFinished(Integer taskNo, |
| | | Integer traceVersion, |
| | | Integer currentStationId, |
| | | Map<String, Object> details) { |
| | | ensureCacheLoaded(); |
| | | TraceTaskState state = taskStateMap.get(taskNo); |
| | | if (state == null) { |
| | | return; |
| | | } |
| | | state.markTerminal(traceVersion, STATUS_FINISHED, currentStationId, null, |
| | | "FINISHED", "输送任务轨迹完成", details); |
| | | persistState(state); |
| | | } |
| | | |
| | | public void updateLoopHint(Integer taskNo, |
| | | Boolean loopAlertActive, |
| | | String loopAlertType, |
| | | String loopAlertText, |
| | | Integer loopAlertCount, |
| | | Map<String, Object> details) { |
| | | ensureCacheLoaded(); |
| | | TraceTaskState state = taskStateMap.get(taskNo); |
| | | if (state == null) { |
| | | return; |
| | | } |
| | | state.updateLoopHint(loopAlertActive, loopAlertType, loopAlertText, loopAlertCount, details); |
| | | persistState(state); |
| | | } |
| | | |
| | | public List<StationTaskTraceVo> listLatestTraces() { |
| | | ensureCacheLoaded(); |
| | | cleanupExpired(); |
| | | reconcileInactiveBusinessTasks(); |
| | | List<StationTaskTraceVo> result = new ArrayList<>(); |
| | | for (TraceTaskState state : taskStateMap.values()) { |
| | | if (state != null) { |
| | |
| | | return result; |
| | | } |
| | | |
| | | public List<StationTaskTraceVo> listActiveTraces() { |
| | | List<StationTaskTraceVo> latestTraces = listLatestTraces(); |
| | | List<StationTaskTraceVo> result = new ArrayList<>(); |
| | | for (StationTaskTraceVo traceVo : latestTraces) { |
| | | if (traceVo == null) { |
| | | continue; |
| | | } |
| | | String status = traceVo.getStatus(); |
| | | if (STATUS_WAITING.equals(status) |
| | | || STATUS_RUNNING.equals(status) |
| | | || STATUS_REROUTED.equals(status)) { |
| | | result.add(traceVo); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private void cleanupExpired() { |
| | | long now = System.currentTimeMillis(); |
| | | for (Map.Entry<Integer, TraceTaskState> entry : taskStateMap.entrySet()) { |
| | | TraceTaskState state = entry.getValue(); |
| | | if (state != null && state.shouldRemove(now)) { |
| | | taskStateMap.remove(entry.getKey(), state); |
| | | removePersistedState(entry.getKey()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void reconcileInactiveBusinessTasks() { |
| | | if (wrkMastService == null) { |
| | | return; |
| | | } |
| | | for (TraceTaskState state : taskStateMap.values()) { |
| | | if (state == null || state.isTerminal()) { |
| | | continue; |
| | | } |
| | | WrkMast wrkMast; |
| | | try { |
| | | wrkMast = wrkMastService.selectByWorkNo(state.taskNo); |
| | | } catch (Exception ignore) { |
| | | continue; |
| | | } |
| | | if (wrkMast == null) { |
| | | Integer currentStationId = state.currentStationId != null ? state.currentStationId : state.finalTargetStationId; |
| | | Map<String, Object> details = new LinkedHashMap<>(); |
| | | details.put("reason", "wrk_missing"); |
| | | state.markTerminal(state.traceVersion, STATUS_FINISHED, currentStationId, null, |
| | | "AUTO_FINISHED", "输送任务档已不存在,轨迹自动结束", details); |
| | | persistState(state); |
| | | continue; |
| | | } |
| | | if (isStationTraceActiveWrkStatus(wrkMast.getWrkSts())) { |
| | | continue; |
| | | } |
| | | Integer currentStationId = state.currentStationId != null ? state.currentStationId : state.finalTargetStationId; |
| | | Map<String, Object> details = new LinkedHashMap<>(); |
| | | details.put("reason", "wrk_status_transition"); |
| | | details.put("wrkSts", wrkMast.getWrkSts()); |
| | | details.put("wrkStsDesc", wrkMast.getWrkSts$()); |
| | | if (isManualWrkStatus(wrkMast.getWrkSts())) { |
| | | state.markTerminal(state.traceVersion, STATUS_CANCELLED, currentStationId, null, |
| | | "AUTO_CANCELLED", "输送任务已退出运行,轨迹自动结束", details); |
| | | } else { |
| | | state.markTerminal(state.traceVersion, STATUS_FINISHED, currentStationId, null, |
| | | "AUTO_FINISHED", "输送任务已结束,轨迹自动结束", details); |
| | | } |
| | | persistState(state); |
| | | } |
| | | } |
| | | |
| | | private boolean isStationTraceActiveWrkStatus(Long wrkSts) { |
| | | return Objects.equals(wrkSts, WrkStsType.INBOUND_DEVICE_RUN.sts) |
| | | || Objects.equals(wrkSts, WrkStsType.STATION_RUN.sts); |
| | | } |
| | | |
| | | private boolean isManualWrkStatus(Long wrkSts) { |
| | | return Objects.equals(wrkSts, WrkStsType.INBOUND_MANUAL.sts) |
| | | || Objects.equals(wrkSts, WrkStsType.OUTBOUND_MANUAL.sts) |
| | | || Objects.equals(wrkSts, WrkStsType.LOC_MOVE_MANUAL.sts); |
| | | } |
| | | |
| | | private void ensureCacheLoaded() { |
| | | if (loadedFromRedis) { |
| | | return; |
| | | } |
| | | synchronized (this) { |
| | | if (loadedFromRedis) { |
| | | return; |
| | | } |
| | | Map<Object, Object> cacheMap = redisUtil == null ? null : redisUtil.hmget(TRACE_CACHE_KEY); |
| | | if (cacheMap != null && !cacheMap.isEmpty()) { |
| | | long now = System.currentTimeMillis(); |
| | | for (Map.Entry<Object, Object> entry : cacheMap.entrySet()) { |
| | | Integer taskNo = parseTaskNo(entry.getKey()); |
| | | TraceSnapshot snapshot = parseSnapshot(entry.getValue(), taskNo); |
| | | if (snapshot == null || snapshot.getTaskNo() == null) { |
| | | if (taskNo != null) { |
| | | removePersistedState(taskNo); |
| | | } |
| | | continue; |
| | | } |
| | | if (snapshot.isExpired(now)) { |
| | | removePersistedState(snapshot.getTaskNo()); |
| | | continue; |
| | | } |
| | | taskStateMap.put(snapshot.getTaskNo(), TraceTaskState.fromSnapshot(snapshot)); |
| | | } |
| | | } |
| | | loadedFromRedis = true; |
| | | } |
| | | } |
| | | |
| | | private void persistState(TraceTaskState state) { |
| | | if (state == null || state.taskNo == null || redisUtil == null) { |
| | | return; |
| | | } |
| | | redisUtil.hset(TRACE_CACHE_KEY, String.valueOf(state.taskNo), JSON.toJSONString(state.toSnapshot())); |
| | | } |
| | | |
| | | private void removePersistedState(Integer taskNo) { |
| | | if (taskNo == null || redisUtil == null) { |
| | | return; |
| | | } |
| | | redisUtil.hdel(TRACE_CACHE_KEY, String.valueOf(taskNo)); |
| | | } |
| | | |
| | | private Integer parseTaskNo(Object value) { |
| | | if (value == null) { |
| | | return null; |
| | | } |
| | | try { |
| | | return Integer.parseInt(String.valueOf(value)); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | private TraceSnapshot parseSnapshot(Object cacheValue, Integer fallbackTaskNo) { |
| | | if (cacheValue == null) { |
| | | return null; |
| | | } |
| | | try { |
| | | TraceSnapshot snapshot = JSON.parseObject(String.valueOf(cacheValue), TraceSnapshot.class); |
| | | if (snapshot != null && snapshot.getTaskNo() == null) { |
| | | snapshot.setTaskNo(fallbackTaskNo); |
| | | } |
| | | return snapshot; |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | |
| | | return result; |
| | | } |
| | | |
| | | private static List<StationTaskTraceEventVo> copyEventList(List<StationTaskTraceEventVo> source) { |
| | | List<StationTaskTraceEventVo> result = new ArrayList<>(); |
| | | if (source == null) { |
| | | return result; |
| | | } |
| | | for (StationTaskTraceEventVo item : source) { |
| | | if (item == null) { |
| | | continue; |
| | | } |
| | | StationTaskTraceEventVo copy = new StationTaskTraceEventVo(); |
| | | copy.setTimestamp(item.getTimestamp()); |
| | | copy.setEventType(item.getEventType()); |
| | | copy.setMessage(item.getMessage()); |
| | | copy.setStatus(item.getStatus()); |
| | | copy.setCurrentStationId(item.getCurrentStationId()); |
| | | copy.setTargetStationId(item.getTargetStationId()); |
| | | copy.setTraceVersion(item.getTraceVersion()); |
| | | copy.setDetails(copyDetails(item.getDetails())); |
| | | result.add(copy); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private static boolean isTerminalStatus(String status) { |
| | | return STATUS_BLOCKED.equals(status) |
| | | || STATUS_CANCELLED.equals(status) |
| | |
| | | private Integer pathOffset; |
| | | private List<Integer> fullPathStationIds = new ArrayList<>(); |
| | | private boolean rerouted; |
| | | } |
| | | |
| | | @Data |
| | | private static class TraceSnapshot { |
| | | private Integer taskNo; |
| | | private String threadImpl; |
| | | private String status; |
| | | private Integer traceVersion; |
| | | private Integer startStationId; |
| | | private Integer currentStationId; |
| | | private Integer finalTargetStationId; |
| | | private Integer blockedStationId; |
| | | private List<Integer> fullPathStationIds = new ArrayList<>(); |
| | | private List<Integer> issuedStationIds = new ArrayList<>(); |
| | | private List<Integer> passedStationIds = new ArrayList<>(); |
| | | private List<Integer> pendingStationIds = new ArrayList<>(); |
| | | private List<Integer> latestIssuedSegmentPath = new ArrayList<>(); |
| | | private List<StationTaskTraceSegmentVo> segmentList = new ArrayList<>(); |
| | | private Integer issuedSegmentCount; |
| | | private Integer totalSegmentCount; |
| | | private Boolean loopAlertActive; |
| | | private String loopAlertType; |
| | | private String loopAlertText; |
| | | private Integer loopAlertCount; |
| | | private Long updatedAt; |
| | | private Long terminalExpireAt; |
| | | private List<StationTaskTraceEventVo> events = new ArrayList<>(); |
| | | |
| | | private boolean isExpired(long now) { |
| | | return terminalExpireAt != null && terminalExpireAt <= now; |
| | | } |
| | | } |
| | | |
| | | private static class TraceTaskState { |
| | |
| | | private List<StationTaskTraceSegmentVo> segmentList = new ArrayList<>(); |
| | | private Integer issuedSegmentCount = 0; |
| | | private Integer totalSegmentCount = 0; |
| | | private Boolean loopAlertActive = Boolean.FALSE; |
| | | private String loopAlertType; |
| | | private String loopAlertText; |
| | | private Integer loopAlertCount; |
| | | private final List<StationTaskTraceEventVo> events = new ArrayList<>(); |
| | | private Long updatedAt = System.currentTimeMillis(); |
| | | private Long terminalExpireAt; |
| | |
| | | List<Integer> localPathStationIds, |
| | | List<StationTaskTraceSegmentVo> localSegmentList) { |
| | | TraceRegistration registration = new TraceRegistration(); |
| | | boolean firstPlan = this.traceVersion == null || this.traceVersion <= 0; |
| | | boolean rerouted = !isTerminalStatus(this.status) && this.traceVersion != null && this.traceVersion > 0; |
| | | int nextTraceVersion = rerouted ? this.traceVersion + 1 : 1; |
| | | int pathOffset = rerouted ? this.passedStationIds.size() : 0; |
| | |
| | | this.latestIssuedSegmentPath = new ArrayList<>(); |
| | | this.status = rerouted ? STATUS_REROUTED : STATUS_WAITING; |
| | | this.terminalExpireAt = null; |
| | | if (firstPlan) { |
| | | clearLoopHintState(); |
| | | } |
| | | rebuildProgress(planCurrentStationId); |
| | | this.updatedAt = System.currentTimeMillis(); |
| | | |
| | |
| | | details.put("segmentCount", this.totalSegmentCount); |
| | | details.put("pathOffset", pathOffset); |
| | | details.put("currentStationId", this.currentStationId); |
| | | appendLoopHintDetails(details); |
| | | appendEvent(rerouted ? "REROUTED" : "PLAN_READY", |
| | | rerouted ? "输送任务路径已重算并续接轨迹" : "输送任务分段计划已建立", |
| | | details); |
| | |
| | | appendEvent(eventType, message, nextDetails); |
| | | } |
| | | |
| | | private synchronized void updateLoopHint(Boolean loopAlertActive, |
| | | String loopAlertType, |
| | | String loopAlertText, |
| | | Integer loopAlertCount, |
| | | Map<String, Object> details) { |
| | | boolean active = Boolean.TRUE.equals(loopAlertActive) |
| | | && loopAlertCount != null |
| | | && loopAlertCount > 2 |
| | | && loopAlertText != null |
| | | && !loopAlertText.trim().isEmpty(); |
| | | String nextType = active ? loopAlertType : null; |
| | | String nextText = active ? loopAlertText.trim() : null; |
| | | Integer nextCount = loopAlertCount != null && loopAlertCount > 0 ? loopAlertCount : null; |
| | | boolean changed = !Objects.equals(this.loopAlertActive, active) |
| | | || !Objects.equals(this.loopAlertType, nextType) |
| | | || !Objects.equals(this.loopAlertText, nextText) |
| | | || !Objects.equals(this.loopAlertCount, nextCount); |
| | | if (!changed) { |
| | | return; |
| | | } |
| | | |
| | | this.loopAlertActive = active; |
| | | this.loopAlertType = nextType; |
| | | this.loopAlertText = nextText; |
| | | this.loopAlertCount = nextCount; |
| | | this.updatedAt = System.currentTimeMillis(); |
| | | if (!active) { |
| | | return; |
| | | } |
| | | |
| | | Map<String, Object> nextDetails = copyDetails(details); |
| | | nextDetails.put("loopAlertActive", Boolean.TRUE); |
| | | nextDetails.put("loopAlertType", this.loopAlertType); |
| | | nextDetails.put("loopAlertText", this.loopAlertText); |
| | | nextDetails.put("loopAlertCount", this.loopAlertCount); |
| | | appendEvent("LOOP_REPEAT_ALERT", this.loopAlertText, nextDetails); |
| | | } |
| | | |
| | | private synchronized boolean shouldRemove(long now) { |
| | | return terminalExpireAt != null && terminalExpireAt <= now; |
| | | } |
| | | |
| | | private synchronized boolean isTerminal() { |
| | | return isTerminalStatus(this.status); |
| | | } |
| | | |
| | | private synchronized StationTaskTraceVo toVo() { |
| | |
| | | vo.setSegmentList(copySegmentListWithIssued(segmentList, issuedSegmentCount)); |
| | | vo.setIssuedSegmentCount(issuedSegmentCount); |
| | | vo.setTotalSegmentCount(totalSegmentCount); |
| | | vo.setLoopAlertActive(loopAlertActive); |
| | | vo.setLoopAlertType(loopAlertType); |
| | | vo.setLoopAlertText(loopAlertText); |
| | | vo.setLoopAlertCount(loopAlertCount); |
| | | vo.setUpdatedAt(updatedAt); |
| | | vo.setEvents(new ArrayList<>(events)); |
| | | vo.setEvents(copyEventList(events)); |
| | | return vo; |
| | | } |
| | | |
| | | private synchronized TraceSnapshot toSnapshot() { |
| | | TraceSnapshot snapshot = new TraceSnapshot(); |
| | | snapshot.setTaskNo(taskNo); |
| | | snapshot.setThreadImpl(threadImpl); |
| | | snapshot.setStatus(status); |
| | | snapshot.setTraceVersion(traceVersion); |
| | | snapshot.setStartStationId(startStationId); |
| | | snapshot.setCurrentStationId(currentStationId); |
| | | snapshot.setFinalTargetStationId(finalTargetStationId); |
| | | snapshot.setBlockedStationId(blockedStationId); |
| | | snapshot.setFullPathStationIds(copyIntegerList(fullPathStationIds)); |
| | | snapshot.setIssuedStationIds(copyIntegerList(issuedStationIds)); |
| | | snapshot.setPassedStationIds(copyIntegerList(passedStationIds)); |
| | | snapshot.setPendingStationIds(copyIntegerList(pendingStationIds)); |
| | | snapshot.setLatestIssuedSegmentPath(copyIntegerList(latestIssuedSegmentPath)); |
| | | snapshot.setSegmentList(copySegmentList(segmentList)); |
| | | snapshot.setIssuedSegmentCount(issuedSegmentCount); |
| | | snapshot.setTotalSegmentCount(totalSegmentCount); |
| | | snapshot.setLoopAlertActive(loopAlertActive); |
| | | snapshot.setLoopAlertType(loopAlertType); |
| | | snapshot.setLoopAlertText(loopAlertText); |
| | | snapshot.setLoopAlertCount(loopAlertCount); |
| | | snapshot.setUpdatedAt(updatedAt); |
| | | snapshot.setTerminalExpireAt(terminalExpireAt); |
| | | snapshot.setEvents(copyEventList(events)); |
| | | return snapshot; |
| | | } |
| | | |
| | | private static TraceTaskState fromSnapshot(TraceSnapshot snapshot) { |
| | | TraceTaskState state = new TraceTaskState(snapshot.getTaskNo()); |
| | | state.threadImpl = snapshot.getThreadImpl(); |
| | | state.status = snapshot.getStatus() == null ? STATUS_WAITING : snapshot.getStatus(); |
| | | state.traceVersion = snapshot.getTraceVersion() == null ? 0 : snapshot.getTraceVersion(); |
| | | state.startStationId = snapshot.getStartStationId(); |
| | | state.currentStationId = snapshot.getCurrentStationId(); |
| | | state.finalTargetStationId = snapshot.getFinalTargetStationId(); |
| | | state.blockedStationId = snapshot.getBlockedStationId(); |
| | | state.fullPathStationIds = copyIntegerList(snapshot.getFullPathStationIds()); |
| | | state.issuedStationIds = copyIntegerList(snapshot.getIssuedStationIds()); |
| | | state.passedStationIds = copyIntegerList(snapshot.getPassedStationIds()); |
| | | state.pendingStationIds = copyIntegerList(snapshot.getPendingStationIds()); |
| | | state.latestIssuedSegmentPath = copyIntegerList(snapshot.getLatestIssuedSegmentPath()); |
| | | state.segmentList = copySegmentList(snapshot.getSegmentList()); |
| | | state.issuedSegmentCount = snapshot.getIssuedSegmentCount() == null ? 0 : snapshot.getIssuedSegmentCount(); |
| | | state.totalSegmentCount = snapshot.getTotalSegmentCount() == null ? state.segmentList.size() : snapshot.getTotalSegmentCount(); |
| | | state.loopAlertActive = Boolean.TRUE.equals(snapshot.getLoopAlertActive()); |
| | | state.loopAlertType = snapshot.getLoopAlertType(); |
| | | state.loopAlertText = snapshot.getLoopAlertText(); |
| | | state.loopAlertCount = snapshot.getLoopAlertCount(); |
| | | state.updatedAt = snapshot.getUpdatedAt() == null ? System.currentTimeMillis() : snapshot.getUpdatedAt(); |
| | | state.terminalExpireAt = snapshot.getTerminalExpireAt(); |
| | | state.events.clear(); |
| | | state.events.addAll(copyEventList(snapshot.getEvents())); |
| | | return state; |
| | | } |
| | | |
| | | private List<Integer> buildFullPathForRegistration(boolean rerouted, |
| | |
| | | this.pendingStationIds = copyIntegerList(fullPath.subList(currentIndex + 1, fullPath.size())); |
| | | } |
| | | |
| | | private void clearLoopHintState() { |
| | | this.loopAlertActive = Boolean.FALSE; |
| | | this.loopAlertType = null; |
| | | this.loopAlertText = null; |
| | | this.loopAlertCount = null; |
| | | } |
| | | |
| | | private void appendLoopHintDetails(Map<String, Object> details) { |
| | | if (details == null || this.loopAlertCount == null || this.loopAlertCount <= 0) { |
| | | return; |
| | | } |
| | | details.put("loopAlertCount", this.loopAlertCount); |
| | | if (Boolean.TRUE.equals(this.loopAlertActive)) { |
| | | details.put("loopAlertActive", Boolean.TRUE); |
| | | details.put("loopAlertType", this.loopAlertType); |
| | | details.put("loopAlertText", this.loopAlertText); |
| | | } |
| | | } |
| | | |
| | | private boolean acceptTraceVersion(Integer incomingTraceVersion) { |
| | | return incomingTraceVersion != null |
| | | && this.traceVersion != null |