Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
35547 amit 1
package com.smartdukaan.cron.scheduled;
2
 
3
import com.spice.profitmandi.dao.entity.solr.SolrUpdateFailure;
4
import com.spice.profitmandi.dao.repository.solr.SolrUpdateFailureRepository;
5
import com.spice.profitmandi.dao.service.solr.FofoSolr;
6
import org.apache.logging.log4j.LogManager;
7
import org.apache.logging.log4j.Logger;
8
import org.springframework.beans.factory.annotation.Autowired;
9
import org.springframework.beans.factory.annotation.Value;
10
import org.springframework.scheduling.annotation.Scheduled;
11
import org.springframework.stereotype.Component;
12
import org.springframework.transaction.annotation.Transactional;
13
 
14
import java.time.LocalDateTime;
15
import java.util.List;
16
 
17
/**
18
 * Scheduled job to retry failed Solr updates.
19
 * Runs every 5 minutes to retry pending failures.
20
 * Max 3 auto-retries before marking as FAILED for manual intervention.
21
 * Only active in production environment.
22
 */
23
@Component
24
public class SolrRetryJob {
25
 
26
    private static final Logger log = LogManager.getLogger(SolrRetryJob.class);
27
    private static final int MAX_AUTO_RETRIES = 3;
28
 
29
    @Value("${prod:false}")
30
    private boolean isProd;
31
 
32
    @Autowired
33
    private SolrUpdateFailureRepository failureRepository;
34
 
35
    @Autowired
36
    private FofoSolr fofoSolr;
37
 
38
    /**
39
     * Retry pending Solr updates every 5 minutes.
40
     * Only retries records with retry count < MAX_AUTO_RETRIES.
41
     * Only runs in production environment.
42
     */
43
    @Scheduled(cron = "0 */5 * * * *")
44
    @Transactional(rollbackFor = Throwable.class)
45
    public void retryPendingUpdates() {
46
        if (!isProd) {
47
            return;
48
        }
49
 
50
        log.debug("Starting Solr retry job");
51
 
52
        List<SolrUpdateFailure> failures = failureRepository.selectAllPending();
53
 
54
        if (failures.isEmpty()) {
55
            log.debug("No pending Solr updates to retry");
56
            return;
57
        }
58
 
59
        log.info("Found {} pending Solr update failures to retry", failures.size());
60
 
61
        int success = 0;
62
        int failed = 0;
63
        int skipped = 0;
64
 
65
        for (SolrUpdateFailure failure : failures) {
66
            // Skip if max retries exceeded
67
            if (failure.getRetryCount() >= MAX_AUTO_RETRIES) {
68
                failure.setStatus("FAILED");
69
                failureRepository.update(failure);
70
                skipped++;
71
                log.warn("Max retries exceeded for catalogId={}, marking as FAILED", failure.getCatalogId());
72
                continue;
73
            }
74
 
75
            try {
76
                fofoSolr.updateSingleCatalog(failure.getCatalogId());
77
                failureRepository.deleteById(failure.getId());
78
                success++;
79
                log.info("Retry successful for catalogId={}", failure.getCatalogId());
80
            } catch (Exception e) {
81
                failure.setRetryCount(failure.getRetryCount() + 1);
82
                failure.setLastRetryAt(LocalDateTime.now());
83
                failure.setErrorMessage(truncateErrorMessage(e.getMessage()));
84
 
85
                if (failure.getRetryCount() >= MAX_AUTO_RETRIES) {
86
                    failure.setStatus("FAILED");
87
                    log.warn("Retry #{} failed for catalogId={}, marking as FAILED for manual intervention",
88
                            failure.getRetryCount(), failure.getCatalogId());
89
                } else {
90
                    log.warn("Retry #{} failed for catalogId={}, will retry again",
91
                            failure.getRetryCount(), failure.getCatalogId());
92
                }
93
 
94
                failureRepository.update(failure);
95
                failed++;
96
            }
97
        }
98
 
99
        log.info("Solr retry job completed: success={}, failed={}, skipped={}", success, failed, skipped);
100
    }
101
 
102
    private String truncateErrorMessage(String message) {
103
        if (message == null) {
104
            return "Unknown error";
105
        }
106
        return message.length() > 2000 ? message.substring(0, 2000) : message;
107
    }
108
}