mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-08-02 13:48:15 +02:00
further cleanups
This commit is contained in:
parent
82900b9db1
commit
fe4a452a54
@ -26,17 +26,47 @@ public class CleanupAsyncConfig {
|
|||||||
|
|
||||||
// Set custom rejection handler to log when queue is full
|
// Set custom rejection handler to log when queue is full
|
||||||
exec.setRejectedExecutionHandler(new RejectedExecutionHandler() {
|
exec.setRejectedExecutionHandler(new RejectedExecutionHandler() {
|
||||||
|
private volatile long lastRejectionTime = 0;
|
||||||
|
private volatile int rejectionCount = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
|
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
|
||||||
log.warn("Cleanup task rejected - queue full! Active: {}, Queue size: {}, Pool size: {}",
|
long currentTime = System.currentTimeMillis();
|
||||||
executor.getActiveCount(),
|
rejectionCount++;
|
||||||
executor.getQueue().size(),
|
|
||||||
executor.getPoolSize());
|
|
||||||
|
|
||||||
// Use caller-runs policy as fallback - this will block the scheduler thread
|
// Rate-limit logging to avoid spam
|
||||||
// but ensures the cleanup still happens
|
if (currentTime - lastRejectionTime > 60000) { // Log at most once per minute
|
||||||
log.warn("Executing cleanup task on scheduler thread as fallback");
|
log.warn("Cleanup task rejected #{} - queue full! Active: {}, Queue size: {}, Pool size: {}",
|
||||||
r.run();
|
rejectionCount,
|
||||||
|
executor.getActiveCount(),
|
||||||
|
executor.getQueue().size(),
|
||||||
|
executor.getPoolSize());
|
||||||
|
lastRejectionTime = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to discard oldest task and add this one
|
||||||
|
if (executor.getQueue().poll() != null) {
|
||||||
|
log.debug("Discarded oldest queued cleanup task to make room");
|
||||||
|
try {
|
||||||
|
executor.execute(r);
|
||||||
|
return;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// If still rejected, fall back to caller-runs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last resort: caller-runs with timeout protection
|
||||||
|
log.warn("Executing cleanup task #{} on scheduler thread as last resort", rejectionCount);
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
r.run();
|
||||||
|
long duration = System.currentTimeMillis() - startTime;
|
||||||
|
if (duration > 30000) { // Warn if cleanup blocks scheduler for >30s
|
||||||
|
log.warn("Cleanup task on scheduler thread took {}ms - consider tuning", duration);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Cleanup task failed on scheduler thread", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -328,8 +328,8 @@ public class ApplicationProperties {
|
|||||||
private long cleanupIntervalMinutes = 30;
|
private long cleanupIntervalMinutes = 30;
|
||||||
private boolean startupCleanup = true;
|
private boolean startupCleanup = true;
|
||||||
private boolean cleanupSystemTemp = false;
|
private boolean cleanupSystemTemp = false;
|
||||||
private int batchSize = 0;
|
private int batchSize = 1000;
|
||||||
private long pauseBetweenBatchesMs = 0;
|
private long pauseBetweenBatchesMs = 50;
|
||||||
|
|
||||||
public String getBaseTmpDir() {
|
public String getBaseTmpDir() {
|
||||||
return baseTmpDir != null && !baseTmpDir.isEmpty()
|
return baseTmpDir != null && !baseTmpDir.isEmpty()
|
||||||
|
@ -50,6 +50,9 @@ public class TempFileCleanupService {
|
|||||||
// Maximum recursion depth for directory traversal
|
// Maximum recursion depth for directory traversal
|
||||||
private static final int MAX_RECURSION_DEPTH = 5;
|
private static final int MAX_RECURSION_DEPTH = 5;
|
||||||
|
|
||||||
|
// Maximum consecutive failures before aborting batch cleanup
|
||||||
|
private static final int MAX_CONSECUTIVE_FAILURES = 10;
|
||||||
|
|
||||||
// Cleanup state management
|
// Cleanup state management
|
||||||
private final AtomicBoolean cleanupRunning = new AtomicBoolean(false);
|
private final AtomicBoolean cleanupRunning = new AtomicBoolean(false);
|
||||||
private final AtomicLong lastCleanupDuration = new AtomicLong(0);
|
private final AtomicLong lastCleanupDuration = new AtomicLong(0);
|
||||||
@ -371,6 +374,7 @@ public class TempFileCleanupService {
|
|||||||
.getTempFileManagement()
|
.getTempFileManagement()
|
||||||
.getPauseBetweenBatchesMs();
|
.getPauseBetweenBatchesMs();
|
||||||
int processed = 0;
|
int processed = 0;
|
||||||
|
int consecutiveFailures = 0;
|
||||||
|
|
||||||
try (java.nio.file.DirectoryStream<Path> stream = Files.newDirectoryStream(directory)) {
|
try (java.nio.file.DirectoryStream<Path> stream = Files.newDirectoryStream(directory)) {
|
||||||
for (Path path : stream) {
|
for (Path path : stream) {
|
||||||
@ -394,17 +398,32 @@ public class TempFileCleanupService {
|
|||||||
try {
|
try {
|
||||||
Files.deleteIfExists(path);
|
Files.deleteIfExists(path);
|
||||||
onDeleteCallback.accept(path);
|
onDeleteCallback.accept(path);
|
||||||
|
consecutiveFailures = 0; // Reset failure count on success
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
consecutiveFailures++;
|
||||||
if (e.getMessage() != null
|
if (e.getMessage() != null
|
||||||
&& e.getMessage().contains("being used by another process")) {
|
&& e.getMessage().contains("being used by another process")) {
|
||||||
log.debug("File locked, skipping delete: {}", path);
|
log.debug("File locked, skipping delete: {}", path);
|
||||||
} else {
|
} else {
|
||||||
log.warn("Failed to delete temp file: {}", path, e);
|
log.warn("Failed to delete temp file: {}", path, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
||||||
|
log.error("Aborting directory cleanup after {} consecutive failures in: {}",
|
||||||
|
consecutiveFailures, directory);
|
||||||
|
return; // Early exit from cleanup
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
consecutiveFailures++;
|
||||||
log.warn("Error processing path: {}", path, e);
|
log.warn("Error processing path: {}", path, e);
|
||||||
|
|
||||||
|
if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
||||||
|
log.error("Aborting directory cleanup after {} consecutive failures in: {}",
|
||||||
|
consecutiveFailures, directory);
|
||||||
|
return; // Early exit from cleanup
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processed++;
|
processed++;
|
||||||
|
@ -134,8 +134,8 @@ system:
|
|||||||
cleanupIntervalMinutes: 30 # How often to run cleanup (in minutes)
|
cleanupIntervalMinutes: 30 # How often to run cleanup (in minutes)
|
||||||
startupCleanup: true # Clean up old temp files on startup
|
startupCleanup: true # Clean up old temp files on startup
|
||||||
cleanupSystemTemp: false # Whether to clean broader system temp directory
|
cleanupSystemTemp: false # Whether to clean broader system temp directory
|
||||||
batchSize: 0 # Number of entries processed before optional pause (0 = unlimited)
|
batchSize: 1000 # Number of entries processed before optional pause (0 = unlimited)
|
||||||
pauseBetweenBatchesMs: 0 # Pause duration in milliseconds between batches
|
pauseBetweenBatchesMs: 50 # Pause duration in milliseconds between batches
|
||||||
|
|
||||||
ui:
|
ui:
|
||||||
appName: '' # application's visible name
|
appName: '' # application's visible name
|
||||||
|
Loading…
Reference in New Issue
Block a user