package jnpf.dmsService.expiry;
|
|
import jnpf.dmsEntity.storage.expiry.DmsFileExpiryItem;
|
import jnpf.dmsMapper.DmsFileExpiryMapper;
|
import jnpf.dmsService.search.DmsSearchProperties;
|
import lombok.Getter;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Service;
|
import java.util.List;
|
|
@Slf4j
|
@Service
|
@EnableScheduling
|
@RequiredArgsConstructor
|
public class DmsFileExpiryJob {
|
private final DmsFileExpiryProperties properties;
|
private final DmsFileExpiryMapper mapper;
|
private final DmsFileExpiryExecutor executor;
|
private final DmsFileExpirySearchCleanup cleanup;
|
private final DmsSearchProperties search;
|
@Scheduled(cron = "${dms.expiry.cron:0 * * * * ?}")
|
@jnpf.audit.sdk.annotation.AuditLog(action = "DMS_FILE_EXPIRY_SCAN", bizCodeExpr = "''", recordSuccess = false)
|
public Result run() {
|
int limit = Math.max(1, Math.min(1000, properties.getBatchSize()));
|
int scanned = 0, applied = 0, skipped = 0, failed = 0;
|
long oldestLagSeconds = 0;
|
DmsFileExpiryItem after = null;
|
for (int page = 0; page < Math.max(1, properties.getMaxPages()); page++) {
|
List<DmsFileExpiryItem> items = mapper.candidates(after, limit);
|
for (DmsFileExpiryItem item : items) {
|
scanned++;
|
oldestLagSeconds = Math.max(oldestLagSeconds,
|
Math.max(0, (System.currentTimeMillis() - item.getEffectiveTo().getTime()) / 1000));
|
try {
|
if (executor.process(item)) applied++; else skipped++;
|
} catch (RuntimeException error) {
|
failed++;
|
log.error("DMS expiry failed; retry next scan tenant={} version={}", item.getTenantId(), item.getFileVersionId(), error);
|
}
|
}
|
if (items.size() < limit) break;
|
after = items.get(items.size() - 1); // Advance over failures; a poison row cannot starve this scan.
|
}
|
log.info("DMS expiry scanned={} applied={} skipped={} failed={} oldestLagSeconds={}",
|
scanned, applied, skipped, failed, oldestLagSeconds);
|
if (search.isEnabled()) {
|
for (DmsFileExpiryItem item : mapper.cleanupCandidates(limit)) {
|
try { cleanup.process(item); }
|
catch (RuntimeException error) {
|
log.error("DMS expiry cleanup retry tenant={} version={}", item.getTenantId(), item.getFileVersionId(), error);
|
}
|
}
|
}
|
return new Result(scanned, applied, skipped, failed, oldestLagSeconds);
|
}
|
|
@Getter
|
public static final class Result {
|
private final int scanned;
|
private final int applied;
|
private final int skipped;
|
private final int failed;
|
private final long oldestLagSeconds;
|
|
public Result(int scanned, int applied, int skipped, int failed,
|
long oldestLagSeconds) {
|
this.scanned = scanned;
|
this.applied = applied;
|
this.skipped = skipped;
|
this.failed = failed;
|
this.oldestLagSeconds = oldestLagSeconds;
|
}
|
}
|
}
|