diff --git a/core/src/main/java/org/mapfish/print/metrics/ApplicationStatus.java b/core/src/main/java/org/mapfish/print/metrics/ApplicationStatus.java index cf262c976e..bf38bbff92 100644 --- a/core/src/main/java/org/mapfish/print/metrics/ApplicationStatus.java +++ b/core/src/main/java/org/mapfish/print/metrics/ApplicationStatus.java @@ -1,22 +1,59 @@ package org.mapfish.print.metrics; import com.codahale.metrics.health.HealthCheck; +import java.time.Instant; +import java.time.temporal.TemporalAmount; +import java.util.Date; import org.mapfish.print.servlet.job.JobQueue; +import org.mapfish.print.servlet.job.impl.ThreadPoolJobManager; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; class ApplicationStatus extends HealthCheck { - public static final int MAX_WAITING_JOBS_TILL_UNHEALTHY = 5; + @Value("${expectedMaxTime.sinceLastPrint.InSeconds}") + private int SECONDS_IN_FLOATING_WINDOW; + + private final TemporalAmount TIME_WINDOW_SIZE = + java.time.Duration.ofSeconds(SECONDS_IN_FLOATING_WINDOW); @Autowired private JobQueue jobQueue; + @Autowired private ThreadPoolJobManager jobManager; + + private long previousNumberOfWaitingJobs = 0L; @Override protected Result check() throws Exception { long waitingJobsCount = jobQueue.getWaitingJobsCount(); - String health = "Number of jobs waiting is " + waitingJobsCount; + if (waitingJobsCount == 0) { + previousNumberOfWaitingJobs = waitingJobsCount; + return Result.healthy("No print job is waiting in the queue."); + } - if (waitingJobsCount >= MAX_WAITING_JOBS_TILL_UNHEALTHY) { - return Result.unhealthy(health + ". It is too high."); + String health = "Number of print jobs waiting is " + waitingJobsCount; + + if (jobManager.getLastExecutedJobTimestamp() == null) { + return Result.unhealthy("No print job was ever processed by this server. " + health); + } else if (jobManager + .getLastExecutedJobTimestamp() + .toInstant() + .isAfter(getBeginningOfTimeWindow())) { + if (waitingJobsCount > previousNumberOfWaitingJobs) { + previousNumberOfWaitingJobs = waitingJobsCount; + return Result.unhealthy( + "More print jobs are being queued. But this server is processing them. " + health); + } else { + previousNumberOfWaitingJobs = waitingJobsCount; + return Result.healthy( + "Print jobs are being dequeued. Number of print jobs waiting is " + waitingJobsCount); + } } else { - return Result.healthy(health); + previousNumberOfWaitingJobs = waitingJobsCount; + throw new RuntimeException( + "No print job was processed by this server, in the last (seconds): " + + SECONDS_IN_FLOATING_WINDOW); } } + + private Instant getBeginningOfTimeWindow() { + return new Date().toInstant().minus(TIME_WINDOW_SIZE); + } } diff --git a/core/src/main/java/org/mapfish/print/servlet/job/JobManager.java b/core/src/main/java/org/mapfish/print/servlet/job/JobManager.java index 7ea15b8d52..bbb9ba87bd 100644 --- a/core/src/main/java/org/mapfish/print/servlet/job/JobManager.java +++ b/core/src/main/java/org/mapfish/print/servlet/job/JobManager.java @@ -1,8 +1,9 @@ package org.mapfish.print.servlet.job; +import java.util.Date; + /** Manages and Executes Print Jobs. */ public interface JobManager { - /** * Submit a new job for execution. * @@ -14,7 +15,7 @@ public interface JobManager { * Cancel a job. * * @param referenceId The referenceId of the job to cancel. - * @throws NoSuchReferenceException + * @throws NoSuchReferenceException When trying to cancel an unknown referenceId */ void cancel(String referenceId) throws NoSuchReferenceException; @@ -22,7 +23,14 @@ public interface JobManager { * Get the status for a job. * * @param referenceId The referenceId of the job to check. - * @throws NoSuchReferenceException + * @throws NoSuchReferenceException When requesting status of an unknown referenceId */ PrintJobStatus getStatus(String referenceId) throws NoSuchReferenceException; + + /** + * Instant at which a job was executed by this manager + * + * @return the timestamp as a Date + */ + Date getLastExecutedJobTimestamp(); } diff --git a/core/src/main/java/org/mapfish/print/servlet/job/impl/ThreadPoolJobManager.java b/core/src/main/java/org/mapfish/print/servlet/job/impl/ThreadPoolJobManager.java index 8307e2dcb0..20dfe2b28d 100644 --- a/core/src/main/java/org/mapfish/print/servlet/job/impl/ThreadPoolJobManager.java +++ b/core/src/main/java/org/mapfish/print/servlet/job/impl/ThreadPoolJobManager.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.util.Collections; import java.util.Comparator; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -118,6 +119,7 @@ public class ThreadPoolJobManager implements JobManager { @Autowired private MetricRegistry metricRegistry; private boolean requestedToStop = false; + private Date lastExecutedJobTimestamp; public final void setMaxNumberOfRunningPrintJobs(final int maxNumberOfRunningPrintJobs) { this.maxNumberOfRunningPrintJobs = maxNumberOfRunningPrintJobs; @@ -290,7 +292,12 @@ public final void shutdown() { } } + public Date getLastExecutedJobTimestamp() { + return lastExecutedJobTimestamp; + } + private void executeJob(final PrintJob job) { + lastExecutedJobTimestamp = new Date(); LOGGER.debug( "executeJob {}, PoolSize {}, CorePoolSize {}, Active {}, Completed {}, Task {}, isShutdown" + " {}, isTerminated {}", diff --git a/core/src/main/resources/mapfish-spring.properties b/core/src/main/resources/mapfish-spring.properties index 7d59290bee..76f7af38c7 100644 --- a/core/src/main/resources/mapfish-spring.properties +++ b/core/src/main/resources/mapfish-spring.properties @@ -52,3 +52,6 @@ httpRequest.fetchRetry.maxNumber=3 # Number of milliseconds between 2 executions of the same request httpRequest.fetchRetry.intervalMillis=100 + +# Amount of time in the past where we check if a print job was executed by this server +expectedMaxTime.sinceLastPrint.InSeconds=300