From 7eea7fb3cbc8d1f599558a77e2c1991d39d5b97b Mon Sep 17 00:00:00 2001 From: Rafael Encinas Date: Wed, 6 Nov 2024 17:43:57 -0700 Subject: [PATCH] [Feature] Set Executor Instances limits dynamically from properties (#2193) * Update 'ProcessExecutor.java' to use dynamic process limits from properties * Move limits location out of 'application.properties' * Rename 'SemaphoreLimit' to 'SessionLimit' and bundle with 'Timeout...' into one parent class --- .../SPDF/model/ApplicationProperties.java | 95 +++++++++++++++++ .../software/SPDF/utils/ProcessExecutor.java | 100 +++++++++++++++--- src/main/resources/application.properties | 2 +- src/main/resources/settings.yml.template | 19 ++++ 4 files changed, 199 insertions(+), 17 deletions(-) diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index 16397965..83df30ae 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -47,6 +47,7 @@ public class ApplicationProperties { private AutomaticallyGenerated automaticallyGenerated = new AutomaticallyGenerated(); private EnterpriseEdition enterpriseEdition = new EnterpriseEdition(); private AutoPipeline autoPipeline = new AutoPipeline(); + private ProcessExecutor processExecutor = new ProcessExecutor(); @Data public static class AutoPipeline { @@ -309,4 +310,98 @@ public class ApplicationProperties { } } } + + @Data + public static class ProcessExecutor { + private SessionLimit sessionLimit = new SessionLimit(); + private TimeoutMinutes timeoutMinutes = new TimeoutMinutes(); + + @Data + public static class SessionLimit { + private int libreOfficeSessionLimit; + private int pdfToHtmlSessionLimit; + private int ocrMyPdfSessionLimit; + private int pythonOpenCvSessionLimit; + private int ghostScriptSessionLimit; + private int weasyPrintSessionLimit; + private int installAppSessionLimit; + private int calibreSessionLimit; + + public int getLibreOfficeSessionLimit() { + return libreOfficeSessionLimit > 0 ? libreOfficeSessionLimit : 1; + } + + public int getPdfToHtmlSessionLimit() { + return pdfToHtmlSessionLimit > 0 ? pdfToHtmlSessionLimit : 1; + } + + public int getOcrMyPdfSessionLimit() { + return ocrMyPdfSessionLimit > 0 ? ocrMyPdfSessionLimit : 2; + } + + public int getPythonOpenCvSessionLimit() { + return pythonOpenCvSessionLimit > 0 ? pythonOpenCvSessionLimit : 8; + } + + public int getGhostScriptSessionLimit() { + return ghostScriptSessionLimit > 0 ? ghostScriptSessionLimit : 16; + } + + public int getWeasyPrintSessionLimit() { + return weasyPrintSessionLimit > 0 ? weasyPrintSessionLimit : 16; + } + + public int getInstallAppSessionLimit() { + return installAppSessionLimit > 0 ? installAppSessionLimit : 1; + } + + public int getCalibreSessionLimit() { + return calibreSessionLimit > 0 ? calibreSessionLimit : 1; + } + } + + @Data + public static class TimeoutMinutes { + private long libreOfficeTimeoutMinutes; + private long pdfToHtmlTimeoutMinutes; + private long ocrMyPdfTimeoutMinutes; + private long pythonOpenCvTimeoutMinutes; + private long ghostScriptTimeoutMinutes; + private long weasyPrintTimeoutMinutes; + private long installAppTimeoutMinutes; + private long calibreTimeoutMinutes; + + public long getLibreOfficeTimeoutMinutes() { + return libreOfficeTimeoutMinutes > 0 ? libreOfficeTimeoutMinutes : 30; + } + + public long getPdfToHtmlTimeoutMinutes() { + return pdfToHtmlTimeoutMinutes > 0 ? pdfToHtmlTimeoutMinutes : 20; + } + + public long getOcrMyPdfTimeoutMinutes() { + return ocrMyPdfTimeoutMinutes > 0 ? ocrMyPdfTimeoutMinutes : 30; + } + + public long getPythonOpenCvTimeoutMinutes() { + return pythonOpenCvTimeoutMinutes > 0 ? pythonOpenCvTimeoutMinutes : 30; + } + + public long getGhostScriptTimeoutMinutes() { + return ghostScriptTimeoutMinutes > 0 ? ghostScriptTimeoutMinutes : 30; + } + + public long getWeasyPrintTimeoutMinutes() { + return weasyPrintTimeoutMinutes > 0 ? weasyPrintTimeoutMinutes : 30; + } + + public long getInstallAppTimeoutMinutes() { + return installAppTimeoutMinutes > 0 ? installAppTimeoutMinutes : 60; + } + + public long getCalibreTimeoutMinutes() { + return calibreTimeoutMinutes > 0 ? calibreTimeoutMinutes : 30; + } + } + } } diff --git a/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java b/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java index 5055c14c..0947714f 100644 --- a/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java +++ b/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java @@ -18,10 +18,14 @@ import org.slf4j.LoggerFactory; import io.github.pixee.security.BoundedLineReader; +import stirling.software.SPDF.model.ApplicationProperties; + public class ProcessExecutor { private static final Logger logger = LoggerFactory.getLogger(ProcessExecutor.class); + private static ApplicationProperties applicationProperties = new ApplicationProperties(); + public enum Processes { LIBRE_OFFICE, PDFTOHTML, @@ -45,26 +49,90 @@ public class ProcessExecutor { key -> { int semaphoreLimit = switch (key) { - case LIBRE_OFFICE -> 1; - case PDFTOHTML -> 1; - case OCR_MY_PDF -> 2; - case PYTHON_OPENCV -> 8; - case GHOSTSCRIPT -> 16; - case WEASYPRINT -> 16; - case INSTALL_APP -> 1; - case CALIBRE -> 1; + case LIBRE_OFFICE -> + applicationProperties + .getProcessExecutor() + .getSessionLimit() + .getLibreOfficeSessionLimit(); + case PDFTOHTML -> + applicationProperties + .getProcessExecutor() + .getSessionLimit() + .getPdfToHtmlSessionLimit(); + case OCR_MY_PDF -> + applicationProperties + .getProcessExecutor() + .getSessionLimit() + .getOcrMyPdfSessionLimit(); + case PYTHON_OPENCV -> + applicationProperties + .getProcessExecutor() + .getSessionLimit() + .getPythonOpenCvSessionLimit(); + case GHOSTSCRIPT -> + applicationProperties + .getProcessExecutor() + .getSessionLimit() + .getGhostScriptSessionLimit(); + case WEASYPRINT -> + applicationProperties + .getProcessExecutor() + .getSessionLimit() + .getWeasyPrintSessionLimit(); + case INSTALL_APP -> + applicationProperties + .getProcessExecutor() + .getSessionLimit() + .getInstallAppSessionLimit(); + case CALIBRE -> + applicationProperties + .getProcessExecutor() + .getSessionLimit() + .getCalibreSessionLimit(); }; long timeoutMinutes = switch (key) { - case LIBRE_OFFICE -> 30; - case PDFTOHTML -> 20; - case OCR_MY_PDF -> 30; - case PYTHON_OPENCV -> 30; - case GHOSTSCRIPT -> 30; - case WEASYPRINT -> 30; - case INSTALL_APP -> 60; - case CALIBRE -> 30; + case LIBRE_OFFICE -> + applicationProperties + .getProcessExecutor() + .getTimeoutMinutes() + .getLibreOfficeTimeoutMinutes(); + case PDFTOHTML -> + applicationProperties + .getProcessExecutor() + .getTimeoutMinutes() + .getPdfToHtmlTimeoutMinutes(); + case OCR_MY_PDF -> + applicationProperties + .getProcessExecutor() + .getTimeoutMinutes() + .getOcrMyPdfTimeoutMinutes(); + case PYTHON_OPENCV -> + applicationProperties + .getProcessExecutor() + .getTimeoutMinutes() + .getPythonOpenCvTimeoutMinutes(); + case GHOSTSCRIPT -> + applicationProperties + .getProcessExecutor() + .getTimeoutMinutes() + .getGhostScriptTimeoutMinutes(); + case WEASYPRINT -> + applicationProperties + .getProcessExecutor() + .getTimeoutMinutes() + .getWeasyPrintTimeoutMinutes(); + case INSTALL_APP -> + applicationProperties + .getProcessExecutor() + .getTimeoutMinutes() + .getInstallAppTimeoutMinutes(); + case CALIBRE -> + applicationProperties + .getProcessExecutor() + .getTimeoutMinutes() + .getCalibreTimeoutMinutes(); }; return new ProcessExecutor(semaphoreLimit, liveUpdates, timeoutMinutes); }); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 0f957c0a..fdfb603c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -50,4 +50,4 @@ springdoc.swagger-ui.url=/v1/api-docs posthog.api.key=phc_fiR65u5j6qmXTYL56MNrLZSWqLaDW74OrZH0Insd2xq -posthog.host=https://eu.i.posthog.com \ No newline at end of file +posthog.host=https://eu.i.posthog.com diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index 84f628ba..d9971d0c 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -102,3 +102,22 @@ metrics: AutomaticallyGenerated: key: example UUID: example + +processExecutor: + sessionLimit: # Process executor instances limits + libreOfficeSessionLimit: 1 + pdfToHtmlSessionLimit: 1 + ocrMyPdfSessionLimit: 2 + pythonOpenCvSessionLimit: 8 + ghostScriptSessionLimit: 16 + weasyPrintSessionLimit: 16 + installAppSessionLimit: 1 + calibreSessionLimit: 1 + timeoutMinutes: # Process executor timeout in minutes + libreOfficetimeoutMinutes: 30 + pdfToHtmltimeoutMinutes: 20 + pythonOpenCvtimeoutMinutes: 30 + ghostScripttimeoutMinutes: 30 + weasyPrinttimeoutMinutes: 30 + installApptimeoutMinutes: 60 + calibretimeoutMinutes: 30