| | |
| | | import com.zy.asrs.service.DeviceConfigService; |
| | | import com.zy.asrs.service.StationCycleCapacityService; |
| | | import com.zy.common.model.NavigateNode; |
| | | import com.zy.common.utils.RedisUtil; |
| | | import com.zy.common.utils.NavigateSolution; |
| | | import com.zy.core.cache.SlaveConnection; |
| | | import com.zy.core.enums.RedisKeyType; |
| | | import com.zy.core.enums.SlaveType; |
| | | import com.zy.core.model.StationObjModel; |
| | | import com.zy.core.model.protocol.StationProtocol; |
| | |
| | | @Service("stationCycleCapacityService") |
| | | @Slf4j |
| | | public class StationCycleCapacityServiceImpl implements StationCycleCapacityService { |
| | | private static final long LOOP_LOAD_RESERVE_EXPIRE_MILLIS = 120_000L; |
| | | |
| | | @Autowired |
| | | private BasMapService basMapService; |
| | |
| | | private DeviceConfigService deviceConfigService; |
| | | @Autowired |
| | | private BasDevpService basDevpService; |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | private final AtomicReference<StationCycleCapacityVo> snapshotRef = new AtomicReference<>(new StationCycleCapacityVo()); |
| | | |
| | |
| | | int loopNo = 1; |
| | | int totalStationCount = 0; |
| | | int taskStationCount = 0; |
| | | Set<Integer> actualWorkNoSet = new HashSet<>(); |
| | | |
| | | for (Set<Integer> scc : sccList) { |
| | | if (!isCycleScc(scc, filteredGraph)) { |
| | |
| | | if (workNo != null && workNo > 0) { |
| | | workNoList.add(workNo); |
| | | currentLoopTaskCount++; |
| | | actualWorkNoSet.add(workNo); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | int reserveTaskCount = mergeReserveTaskCount(loopList, actualWorkNoSet); |
| | | taskStationCount += reserveTaskCount; |
| | | |
| | | StationCycleCapacityVo vo = new StationCycleCapacityVo(); |
| | | vo.setLoopList(loopList); |
| | | vo.setLoopCount(loopList.size()); |
| | |
| | | return vo; |
| | | } |
| | | |
| | | private int mergeReserveTaskCount(List<StationCycleLoopVo> loopList, Set<Integer> actualWorkNoSet) { |
| | | if (loopList == null || loopList.isEmpty()) { |
| | | return 0; |
| | | } |
| | | |
| | | Map<Object, Object> reserveMap = redisUtil.hmget(RedisKeyType.STATION_CYCLE_LOAD_RESERVE.key); |
| | | if (reserveMap == null || reserveMap.isEmpty()) { |
| | | return 0; |
| | | } |
| | | |
| | | Map<Integer, StationCycleLoopVo> loopMap = new HashMap<>(); |
| | | Map<Integer, StationCycleLoopVo> stationLoopMap = new HashMap<>(); |
| | | for (StationCycleLoopVo loopVo : loopList) { |
| | | if (loopVo != null && loopVo.getLoopNo() != null) { |
| | | loopMap.put(loopVo.getLoopNo(), loopVo); |
| | | } |
| | | if (loopVo == null || loopVo.getStationIdList() == null) { |
| | | continue; |
| | | } |
| | | for (Integer stationId : loopVo.getStationIdList()) { |
| | | if (stationId != null) { |
| | | stationLoopMap.put(stationId, loopVo); |
| | | } |
| | | } |
| | | } |
| | | |
| | | long now = System.currentTimeMillis(); |
| | | int mergedCount = 0; |
| | | List<Object> removeFieldList = new ArrayList<>(); |
| | | |
| | | for (Map.Entry<Object, Object> entry : reserveMap.entrySet()) { |
| | | ReserveRecord record = parseReserveRecord(entry.getKey(), entry.getValue()); |
| | | if (record == null) { |
| | | removeFieldList.add(entry.getKey()); |
| | | continue; |
| | | } |
| | | |
| | | if (actualWorkNoSet.contains(record.wrkNo)) { |
| | | removeFieldList.add(entry.getKey()); |
| | | continue; |
| | | } |
| | | |
| | | if (record.createTime <= 0 || now - record.createTime > LOOP_LOAD_RESERVE_EXPIRE_MILLIS) { |
| | | removeFieldList.add(entry.getKey()); |
| | | continue; |
| | | } |
| | | |
| | | StationCycleLoopVo loopVo = loopMap.get(record.loopNo); |
| | | if (loopVo == null && record.hitStationId != null) { |
| | | loopVo = stationLoopMap.get(record.hitStationId); |
| | | } |
| | | if (loopVo == null) { |
| | | removeFieldList.add(entry.getKey()); |
| | | continue; |
| | | } |
| | | |
| | | List<Integer> workNoList = loopVo.getWorkNoList(); |
| | | if (workNoList == null) { |
| | | workNoList = new ArrayList<>(); |
| | | loopVo.setWorkNoList(workNoList); |
| | | } |
| | | if (workNoList.contains(record.wrkNo)) { |
| | | continue; |
| | | } |
| | | |
| | | workNoList.add(record.wrkNo); |
| | | Collections.sort(workNoList); |
| | | |
| | | int mergedTaskCount = toNonNegative(loopVo.getTaskCount()) + 1; |
| | | loopVo.setTaskCount(mergedTaskCount); |
| | | loopVo.setCurrentLoad(calcCurrentLoad(mergedTaskCount, toNonNegative(loopVo.getStationCount()))); |
| | | mergedCount++; |
| | | } |
| | | |
| | | if (!removeFieldList.isEmpty()) { |
| | | redisUtil.hdel(RedisKeyType.STATION_CYCLE_LOAD_RESERVE.key, removeFieldList.toArray()); |
| | | } |
| | | return mergedCount; |
| | | } |
| | | |
| | | private ReserveRecord parseReserveRecord(Object fieldObj, Object valueObj) { |
| | | if (fieldObj == null || valueObj == null) { |
| | | return null; |
| | | } |
| | | |
| | | Integer fieldWrkNo = parseInteger(String.valueOf(fieldObj)); |
| | | if (fieldWrkNo == null || fieldWrkNo <= 0) { |
| | | return null; |
| | | } |
| | | |
| | | JSONObject jsonObject; |
| | | try { |
| | | jsonObject = JSON.parseObject(String.valueOf(valueObj)); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | if (jsonObject == null) { |
| | | return null; |
| | | } |
| | | |
| | | Integer wrkNo = jsonObject.getInteger("wrkNo"); |
| | | Integer loopNo = jsonObject.getInteger("loopNo"); |
| | | Integer hitStationId = jsonObject.getInteger("hitStationId"); |
| | | Long createTime = jsonObject.getLong("createTime"); |
| | | if (wrkNo == null || wrkNo <= 0) { |
| | | wrkNo = fieldWrkNo; |
| | | } |
| | | if ((loopNo == null || loopNo <= 0) && (hitStationId == null || hitStationId <= 0)) { |
| | | return null; |
| | | } |
| | | if (createTime == null || createTime <= 0) { |
| | | return null; |
| | | } |
| | | |
| | | ReserveRecord record = new ReserveRecord(); |
| | | record.wrkNo = wrkNo; |
| | | record.loopNo = loopNo; |
| | | record.hitStationId = hitStationId; |
| | | record.createTime = createTime; |
| | | return record; |
| | | } |
| | | |
| | | private Integer parseInteger(String value) { |
| | | if (value == null || value.trim().isEmpty()) { |
| | | return null; |
| | | } |
| | | try { |
| | | return Integer.parseInt(value.trim()); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | private int toNonNegative(Integer value) { |
| | | if (value == null || value < 0) { |
| | | return 0; |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | private static class ReserveRecord { |
| | | private Integer wrkNo; |
| | | private Integer loopNo; |
| | | private Integer hitStationId; |
| | | private Long createTime; |
| | | } |
| | | |
| | | private double calcCurrentLoad(int taskCount, int stationCount) { |
| | | if (stationCount <= 0 || taskCount <= 0) { |
| | | return 0.0; |