package com.datatool.service; import com.datatool.config.TransferProperties; import com.datatool.room.RoomService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.time.Instant; import java.util.stream.Stream; /** * 定时过期清理:扫描上传根目录下各房间目录,对“内存已无房间且目录年龄超过 room-expire-hours”的进行删除。 */ @Component public class ScheduledUploadCleanup { private static final Logger log = LoggerFactory.getLogger(ScheduledUploadCleanup.class); private static final String ROOM_CODE_PATTERN = "[0-9]{6}"; private final UploadCleanupService uploadCleanupService; private final RoomService roomService; private final TransferProperties transferProperties; public ScheduledUploadCleanup(UploadCleanupService uploadCleanupService, RoomService roomService, TransferProperties transferProperties) { this.uploadCleanupService = uploadCleanupService; this.roomService = roomService; this.transferProperties = transferProperties; } @Scheduled(fixedRateString = "${datatool.transfer.cleanup-interval-ms:3600000}") public void cleanupExpiredRoomFolders() { Path root = uploadCleanupService.resolveUploadRoot(); if (!Files.isDirectory(root)) { return; } int expireHours = transferProperties.getRoomExpireHours(); long expireSeconds = expireHours * 3600L; long nowSeconds = Instant.now().getEpochSecond(); try (Stream list = Files.list(root)) { list.filter(Files::isDirectory) .map(Path::getFileName) .map(Path::toString) .filter(roomCode -> roomCode.matches(ROOM_CODE_PATTERN)) .forEach(roomCode -> { if (roomService.hasRoom(roomCode)) { return; } Path roomDir = root.resolve(roomCode); try { long lastModified = Files.getLastModifiedTime(roomDir).toInstant().getEpochSecond(); if (nowSeconds - lastModified >= expireSeconds) { uploadCleanupService.deleteRoomFolder(roomCode); } } catch (IOException e) { log.warn("[ScheduledUploadCleanup] 无法读取目录时间 roomCode={} error={}", roomCode, e.getMessage()); } }); } catch (IOException e) { log.warn("[ScheduledUploadCleanup] 列出上传目录失败 error={}", e.getMessage()); } } }