package de.is24.infrastructure.gridfs.http.gridfs.scheduling;
import com.google.common.annotations.VisibleForTesting;
import de.is24.infrastructure.gridfs.http.mongo.MongoPrimaryDetector;
import de.is24.infrastructure.gridfs.http.storage.FileStorageService;
import de.is24.infrastructure.gridfs.http.utils.MDCHelper;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;
import static org.apache.commons.lang.time.DateUtils.addMinutes;
@ManagedResource
@Service
public class DeleteFilesJob {
private final FileStorageService fileStorageService;
private final MongoPrimaryDetector primaryDetector;
private final int minuetsToWaitForActualDelete;
private AtomicLong executionsSinceStartUp = new AtomicLong();
private AtomicLong failureSinceStartUp = new AtomicLong();
private String lastStackTrace;
@Autowired
public DeleteFilesJob(final FileStorageService fileStorageService,
final MongoPrimaryDetector primaryDetector,
@Value("${scheduler.delete.files.delay.minuets:10}") final int minuetsToWaitForActualDelete) {
this.fileStorageService = fileStorageService;
this.primaryDetector = primaryDetector;
this.minuetsToWaitForActualDelete = minuetsToWaitForActualDelete;
}
@Scheduled(cron = "${scheduler.delete.files.cron:0 3-59/15 * * * *}")
public void deleteFilesMarkedAsDeleted() {
deleteFilesMarkedAsDeleted(new Date());
}
@ManagedOperation
public void deleteFilesMarkedAsDeletedNow() {
doRemoveFilesMarkedAsDeleted(new Date());
}
@ManagedAttribute
public long getExecutionsSinceStartup() {
return executionsSinceStartUp.get();
}
@ManagedAttribute
public long getFailureSinceStartUp() {
return failureSinceStartUp.get();
}
@ManagedAttribute
public String getLastStackTrace() {
return lastStackTrace;
}
@VisibleForTesting
void deleteFilesMarkedAsDeleted(final Date now) {
if (primaryDetector.isPrimary()) {
doRemoveFilesMarkedAsDeleted(now);
}
}
private void doRemoveFilesMarkedAsDeleted(Date now) {
executionsSinceStartUp.incrementAndGet();
new MDCHelper(this.getClass()).run(() -> {
try {
fileStorageService.removeFilesMarkedAsDeletedBefore(addMinutes(now, -minuetsToWaitForActualDelete));
} catch (Exception ex) {
failureSinceStartUp.incrementAndGet();
lastStackTrace = ExceptionUtils.getFullStackTrace(ex);
throw ex;
}
});
}
}