feat: 增强设备分配服务,自动处理超时链接任务状态并记录历史
This commit is contained in:
@@ -3,10 +3,15 @@ package com.gameplatform.server.service.link;
|
||||
import com.gameplatform.server.mapper.agent.LinkTaskMapper;
|
||||
import com.gameplatform.server.model.entity.agent.LinkTask;
|
||||
import com.gameplatform.server.service.cooldown.MemoryMachineCooldownService;
|
||||
import com.gameplatform.server.mapper.history.LinkTaskStatusHistoryMapper;
|
||||
import com.gameplatform.server.model.entity.history.LinkTaskStatusHistory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -22,11 +27,14 @@ public class DeviceAllocationService {
|
||||
|
||||
private final MemoryMachineCooldownService machineCooldownService;
|
||||
private final LinkTaskMapper linkTaskMapper;
|
||||
private final LinkTaskStatusHistoryMapper statusHistoryMapper;
|
||||
|
||||
public DeviceAllocationService(MemoryMachineCooldownService machineCooldownService,
|
||||
LinkTaskMapper linkTaskMapper) {
|
||||
LinkTaskMapper linkTaskMapper,
|
||||
LinkTaskStatusHistoryMapper statusHistoryMapper) {
|
||||
this.machineCooldownService = machineCooldownService;
|
||||
this.linkTaskMapper = linkTaskMapper;
|
||||
this.statusHistoryMapper = statusHistoryMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,6 +44,7 @@ public class DeviceAllocationService {
|
||||
* @param reason 分配原因
|
||||
* @return 分配成功的设备ID,如果所有设备都被占用则返回null
|
||||
*/
|
||||
@Transactional
|
||||
public String allocateDevice(List<String> availableDevices, Long linkTaskId, String reason) {
|
||||
if (availableDevices == null || availableDevices.isEmpty()) {
|
||||
log.warn("设备分配失败:没有可用设备");
|
||||
@@ -84,15 +93,88 @@ public class DeviceAllocationService {
|
||||
List<String> availableDevices = new ArrayList<>();
|
||||
|
||||
for (String deviceId : devices) {
|
||||
// 检查设备是否被其他链接任务占用(USING、LOGGED_IN状态)
|
||||
List<LinkTask> occupiedTasks = linkTaskMapper.findByMachineIdAndStatus(deviceId, "USING");
|
||||
occupiedTasks.addAll(linkTaskMapper.findByMachineIdAndStatus(deviceId, "LOGGED_IN"));
|
||||
|
||||
if (occupiedTasks.isEmpty()) {
|
||||
// 检查设备是否被其他链接任务占用(USING、LOGGED_IN状态),并自动清理超时占用
|
||||
List<LinkTask> usingTasks = linkTaskMapper.findByMachineIdAndStatus(deviceId, "USING");
|
||||
List<LinkTask> loggedInTasks = linkTaskMapper.findByMachineIdAndStatus(deviceId, "LOGGED_IN");
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
List<LinkTask> stillOccupied = new ArrayList<>();
|
||||
|
||||
// USING 超过10分钟未选择区 -> EXPIRED,并写入历史
|
||||
for (LinkTask task : usingTasks) {
|
||||
try {
|
||||
LocalDateTime firstSelectAt = task.getFirstRegionSelectAt();
|
||||
boolean shouldExpire = firstSelectAt != null && firstSelectAt.isBefore(now.minusMinutes(10));
|
||||
if (shouldExpire) {
|
||||
String prev = task.getStatus();
|
||||
task.setStatus("EXPIRED");
|
||||
task.setUpdatedAt(now);
|
||||
int updated = linkTaskMapper.update(task);
|
||||
if (updated > 0) {
|
||||
try {
|
||||
Integer sinceLoginSeconds = null;
|
||||
if (task.getLoginAt() != null) {
|
||||
sinceLoginSeconds = (int) Duration.between(task.getLoginAt(), now).getSeconds();
|
||||
}
|
||||
statusHistoryMapper.insert(new LinkTaskStatusHistory(
|
||||
task.getId(), task.getCodeNo(), deviceId,
|
||||
prev, "EXPIRED", "DEVICE_ALLOCATION", "usingTimeoutExpire10m",
|
||||
sinceLoginSeconds, null
|
||||
));
|
||||
} catch (Exception ignore) {}
|
||||
log.info("自动过期USING链接:codeNo={}, device={}, firstRegionSelectAt={}, 超过10分钟", task.getCodeNo(), deviceId, firstSelectAt);
|
||||
} else {
|
||||
stillOccupied.add(task);
|
||||
}
|
||||
} else {
|
||||
stillOccupied.add(task);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("检查/更新USING任务超时失败,保持占用:codeNo={}, device={}, err={}", task.getCodeNo(), deviceId, e.getMessage());
|
||||
stillOccupied.add(task);
|
||||
}
|
||||
}
|
||||
|
||||
// LOGGED_IN 距离上次更新超过30分钟 -> COMPLETED,并写入历史
|
||||
for (LinkTask task : loggedInTasks) {
|
||||
try {
|
||||
LocalDateTime updatedAt = task.getUpdatedAt();
|
||||
boolean shouldComplete = updatedAt != null && updatedAt.isBefore(now.minusMinutes(30));
|
||||
if (shouldComplete) {
|
||||
String prev = task.getStatus();
|
||||
task.setStatus("COMPLETED");
|
||||
task.setUpdatedAt(now);
|
||||
int updated = linkTaskMapper.update(task);
|
||||
if (updated > 0) {
|
||||
try {
|
||||
Integer sinceLoginSeconds = null;
|
||||
if (task.getLoginAt() != null) {
|
||||
sinceLoginSeconds = (int) Duration.between(task.getLoginAt(), now).getSeconds();
|
||||
}
|
||||
statusHistoryMapper.insert(new LinkTaskStatusHistory(
|
||||
task.getId(), task.getCodeNo(), deviceId,
|
||||
prev, "COMPLETED", "DEVICE_ALLOCATION", "autoCompleteAfter30m",
|
||||
sinceLoginSeconds, null
|
||||
));
|
||||
} catch (Exception ignore) {}
|
||||
log.info("自动完成LOGGED_IN链接:codeNo={}, device={}, updatedAt={}, 超过30分钟", task.getCodeNo(), deviceId, updatedAt);
|
||||
} else {
|
||||
stillOccupied.add(task);
|
||||
}
|
||||
} else {
|
||||
stillOccupied.add(task);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("检查/更新LOGGED_IN任务超时失败,保持占用:codeNo={}, device={}, err={}", task.getCodeNo(), deviceId, e.getMessage());
|
||||
stillOccupied.add(task);
|
||||
}
|
||||
}
|
||||
|
||||
if (stillOccupied.isEmpty()) {
|
||||
availableDevices.add(deviceId);
|
||||
} else {
|
||||
log.debug("设备{}被其他链接任务占用,占用任务数={}", deviceId, occupiedTasks.size());
|
||||
for (LinkTask occupiedTask : occupiedTasks) {
|
||||
log.debug("设备{}被其他链接任务占用,占用任务数={}", deviceId, stillOccupied.size());
|
||||
for (LinkTask occupiedTask : stillOccupied) {
|
||||
log.debug("占用设备{}的链接:codeNo={}, status={}, 任务ID={}",
|
||||
deviceId, occupiedTask.getCodeNo(), occupiedTask.getStatus(), occupiedTask.getId());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user