刘光辉
5 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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;
        }
    }
}