From ea753a6229e2e2b7251ec4784b6ce6d5156799d9 Mon Sep 17 00:00:00 2001 From: Kamil Date: Tue, 25 Jun 2024 14:33:32 +0200 Subject: [PATCH] #2887 Parametrized pool Medium/High Priority: - use WorkItemPriority type; - added configuration BatchWriteBehind work item: MAX_ROWS, MAX_INSTANCES, SPAWN_THRESHOLD; --- .../serotonin/mango/MangoContextListener.java | 4 +- .../mango/rt/dataImage/DataPointRT.java | 6 +-- .../bacnet/BACnetIPDataSourceRT.java | 5 +- .../http/HttpImageDataSourceRT.java | 6 ++- .../persistent/PersistentDataSourceRT.java | 8 +-- .../mango/rt/maint/BackgroundProcessing.java | 10 ++-- .../work/AbstractBeforeAfterWorkItem.java | 6 +-- .../rt/maint/work/EmailAfterWorkItem.java | 4 +- .../rt/maint/work/GetWorkItemPriority.java | 5 ++ .../mango/rt/maint/work/ProcessWorkItem.java | 44 +++------------- .../mango/rt/maint/work/ReportWorkItem.java | 5 +- .../mango/rt/maint/work/SetPointWorkItem.java | 4 +- .../mango/rt/maint/work/WorkItem.java | 6 ++- .../mango/rt/maint/work/WorkItemExecute.java | 2 +- .../mango/rt/maint/work/WorkItemPriority.java | 14 +++-- .../persistent/PersistentSendThread.java | 4 +- .../rt/publish/persistent/SyncHandler.java | 9 ++-- .../mango/util/ThreadPoolExecutorUtils.java | 6 +-- .../sync/SingleExecutorSingleWaiter.java | 4 +- .../serotonin/timer/sync/Synchronizer.java | 4 +- src/com/serotonin/util/ProgressiveTask.java | 4 +- .../config/ThreadPoolExecutorConfig.java | 20 ++------ src/org/scada_lts/dao/SystemSettingsDAO.java | 1 + .../scada_lts/mango/service/EventService.java | 4 +- .../mango/service/PointValueService.java | 17 ++++--- .../scada_lts/utils/SystemSettingsUtils.java | 51 ++++++++++++++++--- .../web/mvc/api/WorkItemInfoApiService.java | 2 +- ...ExecutorConfigSystemSettingsUtilsTest.java | 12 ++--- .../mvc/api/json/WorkItemInfoListTest.java | 4 +- webapp-resources/env.properties | 13 +++-- 30 files changed, 152 insertions(+), 132 deletions(-) create mode 100644 src/com/serotonin/mango/rt/maint/work/GetWorkItemPriority.java diff --git a/src/com/serotonin/mango/MangoContextListener.java b/src/com/serotonin/mango/MangoContextListener.java index 75f1890e25..60dde9c580 100644 --- a/src/com/serotonin/mango/MangoContextListener.java +++ b/src/com/serotonin/mango/MangoContextListener.java @@ -33,6 +33,7 @@ import com.serotonin.mango.rt.maint.BackgroundProcessing; import com.serotonin.mango.rt.maint.DataPurge; import com.serotonin.mango.rt.maint.WorkItemMonitor; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import com.serotonin.mango.util.BackgroundContext; import com.serotonin.mango.view.DynamicImage; import com.serotonin.mango.view.ImageSet; @@ -61,7 +62,6 @@ import org.scada_lts.cache.PointHierarchyCache; import org.scada_lts.cache.ViewHierarchyCache; import org.scada_lts.config.ScadaVersion; -import org.scada_lts.config.ThreadPoolExecutorConfig; import org.scada_lts.dao.SystemSettingsDAO; import org.scada_lts.mango.adapter.MangoScadaConfig; import org.scada_lts.quartz.EverySecond; @@ -117,7 +117,7 @@ private void initialized(ServletContextEvent evt) { ScadaVersion.getInstance().printScadaVersionProperties(log); // Initialize the timer - Common.timer.init(createPool(ThreadPoolExecutorConfig.Priority.HIGH)); + Common.timer.init(createPool(WorkItemPriority.HIGH)); // Create all the stuff we need. constantsInitialize(ctx); diff --git a/src/com/serotonin/mango/rt/dataImage/DataPointRT.java b/src/com/serotonin/mango/rt/dataImage/DataPointRT.java index 831ef53bb2..7ffbe87f1b 100644 --- a/src/com/serotonin/mango/rt/dataImage/DataPointRT.java +++ b/src/com/serotonin/mango/rt/dataImage/DataPointRT.java @@ -27,7 +27,7 @@ import com.serotonin.mango.rt.dataSource.PointLocatorRT; import com.serotonin.mango.rt.event.detectors.PointEventDetectorRT; import com.serotonin.mango.rt.maint.work.AbstractBeforeAfterWorkItem; -import com.serotonin.mango.rt.maint.work.WorkItem; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import com.serotonin.mango.util.LoggingUtils; import com.serotonin.mango.util.timeout.TimeoutClient; import com.serotonin.mango.util.timeout.TimeoutTask; @@ -542,8 +542,8 @@ public void work() { } @Override - public int getPriority() { - return WorkItem.PRIORITY_MEDIUM; + public WorkItemPriority getPriorityType() { + return WorkItemPriority.MEDIUM; } @Override diff --git a/src/com/serotonin/mango/rt/dataSource/bacnet/BACnetIPDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/bacnet/BACnetIPDataSourceRT.java index 1407d64a20..4b1ece3cf7 100644 --- a/src/com/serotonin/mango/rt/dataSource/bacnet/BACnetIPDataSourceRT.java +++ b/src/com/serotonin/mango/rt/dataSource/bacnet/BACnetIPDataSourceRT.java @@ -24,6 +24,7 @@ import java.util.Map; import com.serotonin.mango.rt.maint.work.AbstractBeforeAfterWorkItem; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import com.serotonin.mango.util.LoggingUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -350,8 +351,8 @@ public void work() { } @Override - public int getPriority() { - return WorkItem.PRIORITY_HIGH; + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/com/serotonin/mango/rt/dataSource/http/HttpImageDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/http/HttpImageDataSourceRT.java index 89468b4d9b..2694fad9bc 100644 --- a/src/com/serotonin/mango/rt/dataSource/http/HttpImageDataSourceRT.java +++ b/src/com/serotonin/mango/rt/dataSource/http/HttpImageDataSourceRT.java @@ -23,6 +23,7 @@ import java.util.List; import com.serotonin.mango.rt.maint.work.AbstractBeforeAfterWorkItem; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import com.serotonin.mango.util.LoggingUtils; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; @@ -217,8 +218,9 @@ public LocalizableMessage getSaveFailure() { return saveFailure; } - public int getPriority() { - return WorkItem.PRIORITY_HIGH; + @Override + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/com/serotonin/mango/rt/dataSource/persistent/PersistentDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/persistent/PersistentDataSourceRT.java index 7b1ff0d15b..3c3419c8d2 100644 --- a/src/com/serotonin/mango/rt/dataSource/persistent/PersistentDataSourceRT.java +++ b/src/com/serotonin/mango/rt/dataSource/persistent/PersistentDataSourceRT.java @@ -655,8 +655,8 @@ public void work() { } @Override - public int getPriority() { - return WorkItemPriority.HIGH.getPriority(); + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override @@ -676,8 +676,8 @@ public String toString() { } @Override - public int getPriority() { - return WorkItemPriority.HIGH.getPriority(); + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/com/serotonin/mango/rt/maint/BackgroundProcessing.java b/src/com/serotonin/mango/rt/maint/BackgroundProcessing.java index 4f1bc98f23..e4e4b29959 100644 --- a/src/com/serotonin/mango/rt/maint/BackgroundProcessing.java +++ b/src/com/serotonin/mango/rt/maint/BackgroundProcessing.java @@ -22,13 +22,13 @@ import java.io.StringWriter; import java.util.concurrent.*; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.serotonin.mango.Common; import com.serotonin.mango.rt.maint.work.WorkItem; import com.serotonin.util.ILifecycle; -import org.scada_lts.config.ThreadPoolExecutorConfig; import static com.serotonin.mango.util.ThreadPoolExecutorUtils.createPool; @@ -63,10 +63,10 @@ public void run() { } }; - if (item.getPriority() == WorkItem.PRIORITY_HIGH) + if (item.getPriorityType() == WorkItemPriority.HIGH) Common.timer.execute(runnable); - else if (item.getPriority() == WorkItem.PRIORITY_MEDIUM) + else if (item.getPriorityType() == WorkItemPriority.MEDIUM) mediumPriorityService.execute(new Runnable() { public void run() { try { @@ -98,9 +98,9 @@ public int getMediumPriorityServiceQueueSize() { } public void initialize() { - mediumPriorityService = createPool(ThreadPoolExecutorConfig.Priority.MEDIUM); + mediumPriorityService = createPool(WorkItemPriority.MEDIUM); mediumPriorityService.allowCoreThreadTimeOut(true); - lowPriorityService = createPool(ThreadPoolExecutorConfig.Priority.LOW); + lowPriorityService = createPool(WorkItemPriority.LOW); } public void terminate() { diff --git a/src/com/serotonin/mango/rt/maint/work/AbstractBeforeAfterWorkItem.java b/src/com/serotonin/mango/rt/maint/work/AbstractBeforeAfterWorkItem.java index fb3dc1e424..9bd311d220 100644 --- a/src/com/serotonin/mango/rt/maint/work/AbstractBeforeAfterWorkItem.java +++ b/src/com/serotonin/mango/rt/maint/work/AbstractBeforeAfterWorkItem.java @@ -89,7 +89,7 @@ private static void addWorkItemAfterExecuted(WorkItem workItem, boolean failed, if(workItem instanceof ProcessWorkItem || workItem instanceof ProcessWorkItem.InputReader || workItem instanceof ProcessWorkItem.ProcessTimeout) HISTORY_PROCESS_WORK_ITEMS.add(workItem); - switch (WorkItemPriority.priorityOf(workItem.getPriority())) { + switch(workItem.getPriorityType()) { case HIGH: HISTORY_HIGH_PRIORITY_WORK_ITEMS.add(workItem); break; @@ -115,7 +115,7 @@ private static void addWorkItemIfNotRunning(WorkItem workItem, boolean running, protected AbstractBeforeAfterWorkItem() { this.systemSettingsService = new SystemSettingsService(); if(isEnabled(systemSettingsService)) { - switch (WorkItemPriority.priorityOf(getPriority())) { + switch(getPriorityType()) { case HIGH: HIGH_PRIORITY_WORK_ITEMS.add(this); break; @@ -327,7 +327,7 @@ public LocalDateTime getStartedDate() { } private String suffixThreadName() { - return ThreadUtils.reduceName(" - " + WorkItemPriority.priorityOf(getPriority()) + " - " + getDetails(), systemSettingsService); + return ThreadUtils.reduceName(" - " + getPriorityType() + " - " + getDetails(), systemSettingsService); } private static String exceptionsToString(Map exceptions) { diff --git a/src/com/serotonin/mango/rt/maint/work/EmailAfterWorkItem.java b/src/com/serotonin/mango/rt/maint/work/EmailAfterWorkItem.java index 02521a06ed..7a1550d665 100644 --- a/src/com/serotonin/mango/rt/maint/work/EmailAfterWorkItem.java +++ b/src/com/serotonin/mango/rt/maint/work/EmailAfterWorkItem.java @@ -42,8 +42,8 @@ public void workFail(Throwable exception) { } @Override - public int getPriority() { - return WorkItem.PRIORITY_MEDIUM; + public WorkItemPriority getPriorityType() { + return WorkItemPriority.MEDIUM; } @Override diff --git a/src/com/serotonin/mango/rt/maint/work/GetWorkItemPriority.java b/src/com/serotonin/mango/rt/maint/work/GetWorkItemPriority.java new file mode 100644 index 0000000000..b4fc9b1b5f --- /dev/null +++ b/src/com/serotonin/mango/rt/maint/work/GetWorkItemPriority.java @@ -0,0 +1,5 @@ +package com.serotonin.mango.rt.maint.work; + +public interface GetWorkItemPriority { + WorkItemPriority getPriorityType(); +} \ No newline at end of file diff --git a/src/com/serotonin/mango/rt/maint/work/ProcessWorkItem.java b/src/com/serotonin/mango/rt/maint/work/ProcessWorkItem.java index 65ca3e91d1..a45e3d28fb 100644 --- a/src/com/serotonin/mango/rt/maint/work/ProcessWorkItem.java +++ b/src/com/serotonin/mango/rt/maint/work/ProcessWorkItem.java @@ -122,8 +122,8 @@ public static void executeProcessCommand(String command, String details) throws } @Override - public int getPriority() { - return WorkItem.PRIORITY_HIGH; + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } static class ProcessTimeout extends AbstractBeforeAfterWorkItem { @@ -146,8 +146,8 @@ static class ProcessTimeout extends AbstractBeforeAfterWorkItem { } @Override - public int getPriority() { - return WorkItem.PRIORITY_HIGH; + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } public void interrupt() { @@ -229,8 +229,8 @@ public void join() { } @Override - public int getPriority() { - return WorkItem.PRIORITY_HIGH; + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override @@ -280,36 +280,4 @@ public String toString() { public String getDetails() { return this.toString(); } - - // - // public static void main(String[] args) throws Exception { - // // ServletContext ctx = new DummyServletContext(); - // BackgroundProcessing bp = new BackgroundProcessing(); - // bp.initialize(); - // // ctx.setAttribute(Common.ContextKeys.BACKGROUND_PROCESSING, bp); - // // Common.ctx = new ContextWrapper(ctx); - // // ProcessWorkItem.queueProcess(""); - // // bp.terminate(); - // - // // //ProcessBuilder pb = new ProcessBuilder("cmd /c dir"); - // // ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "dir"); - // // pb.redirectErrorStream(true); - // // Process process = pb.start(); - // Process process = Runtime.getRuntime().exec("cmd /c java -version"); - // - // InputReader out = new InputReader(process.getInputStream()); - // InputReader err = new InputReader(process.getErrorStream()); - // - // bp.addWorkItem(out); - // bp.addWorkItem(err); - // - // process.waitFor(); - // out.join(); - // err.join(); - // process.destroy(); - // bp.terminate(); - // - // System.out.println("out: "+ out.getInput()); - // System.out.println("err: "+ err.getInput()); - // } } \ No newline at end of file diff --git a/src/com/serotonin/mango/rt/maint/work/ReportWorkItem.java b/src/com/serotonin/mango/rt/maint/work/ReportWorkItem.java index c8ceff236a..ab69dbf16a 100644 --- a/src/com/serotonin/mango/rt/maint/work/ReportWorkItem.java +++ b/src/com/serotonin/mango/rt/maint/work/ReportWorkItem.java @@ -66,8 +66,9 @@ public class ReportWorkItem extends AbstractBeforeAfterWorkItem { public ReportWorkItem() {} - public int getPriority() { - return WorkItem.PRIORITY_LOW; + @Override + public WorkItemPriority getPriorityType() { + return WorkItemPriority.LOW; } public static void queueReport(ReportVO report) { diff --git a/src/com/serotonin/mango/rt/maint/work/SetPointWorkItem.java b/src/com/serotonin/mango/rt/maint/work/SetPointWorkItem.java index 4bcdee3ad8..bceb83c247 100644 --- a/src/com/serotonin/mango/rt/maint/work/SetPointWorkItem.java +++ b/src/com/serotonin/mango/rt/maint/work/SetPointWorkItem.java @@ -76,8 +76,8 @@ public void work() { } @Override - public int getPriority() { - return WorkItem.PRIORITY_HIGH; + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/com/serotonin/mango/rt/maint/work/WorkItem.java b/src/com/serotonin/mango/rt/maint/work/WorkItem.java index f00c004dd7..5dba61988c 100644 --- a/src/com/serotonin/mango/rt/maint/work/WorkItem.java +++ b/src/com/serotonin/mango/rt/maint/work/WorkItem.java @@ -22,7 +22,7 @@ * @author Matthew Lohbihler * */ -public interface WorkItem extends WorkItemDetails, WorkItemMetrics { +public interface WorkItem extends WorkItemDetails, WorkItemMetrics, GetWorkItemPriority { /** * Uses a thread pool to immediately execute a process. */ @@ -42,5 +42,7 @@ public interface WorkItem extends WorkItemDetails, WorkItemMetrics { void execute(); - int getPriority(); + default int getPriority() { + return getPriorityType().getPriority(); + } } diff --git a/src/com/serotonin/mango/rt/maint/work/WorkItemExecute.java b/src/com/serotonin/mango/rt/maint/work/WorkItemExecute.java index d55c12297e..be4635b52c 100644 --- a/src/com/serotonin/mango/rt/maint/work/WorkItemExecute.java +++ b/src/com/serotonin/mango/rt/maint/work/WorkItemExecute.java @@ -14,7 +14,7 @@ public WorkItemExecute(WorkItem workItem, long serial) { this.className = workItem.getClass().getName(); this.workItem = workItem; this.serial = serial; - this.priority = WorkItemPriority.priorityOf(workItem.getPriority()); + this.priority = workItem.getPriorityType(); } public WorkItem getWorkItem() { return workItem; diff --git a/src/com/serotonin/mango/rt/maint/work/WorkItemPriority.java b/src/com/serotonin/mango/rt/maint/work/WorkItemPriority.java index 9649ea93cc..b7451f413e 100644 --- a/src/com/serotonin/mango/rt/maint/work/WorkItemPriority.java +++ b/src/com/serotonin/mango/rt/maint/work/WorkItemPriority.java @@ -4,20 +4,26 @@ public enum WorkItemPriority { - HIGH(WorkItem.PRIORITY_HIGH), - MEDIUM(WorkItem.PRIORITY_MEDIUM), - LOW(WorkItem.PRIORITY_LOW); + HIGH(WorkItem.PRIORITY_HIGH, "high-priority."), + MEDIUM(WorkItem.PRIORITY_MEDIUM, "medium-priority."), + LOW(WorkItem.PRIORITY_LOW, "low-priority."); private final int priority; + private final String name; - WorkItemPriority(int priority) { + WorkItemPriority(int priority, String name) { this.priority = priority; + this.name = name; } public int getPriority() { return priority; } + public String getName() { + return name; + } + public static WorkItemPriority priorityOf(int priority) { return Stream.of(WorkItemPriority.values()) .filter(a -> a.getPriority() == priority) diff --git a/src/com/serotonin/mango/rt/publish/persistent/PersistentSendThread.java b/src/com/serotonin/mango/rt/publish/persistent/PersistentSendThread.java index f400cd4176..7488b7c9be 100644 --- a/src/com/serotonin/mango/rt/publish/persistent/PersistentSendThread.java +++ b/src/com/serotonin/mango/rt/publish/persistent/PersistentSendThread.java @@ -423,8 +423,8 @@ public String getDetails() { } @Override - public int getPriority() { - return WorkItemPriority.HIGH.getPriority(); + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/com/serotonin/mango/rt/publish/persistent/SyncHandler.java b/src/com/serotonin/mango/rt/publish/persistent/SyncHandler.java index b1b1f4835f..e9411a200a 100644 --- a/src/com/serotonin/mango/rt/publish/persistent/SyncHandler.java +++ b/src/com/serotonin/mango/rt/publish/persistent/SyncHandler.java @@ -133,8 +133,8 @@ void sendRequest(int id, int requestId, int pointIndex, long from, long to) { } @Override - public int getPriority() { - return WorkItemPriority.HIGH.getPriority(); + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override @@ -345,10 +345,11 @@ void responseReceived(int responseId, long responseCount) { } @Override - public int getPriority() { - return WorkItemPriority.HIGH.getPriority(); + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } + @Override public String toString() { return "PointSync{" + diff --git a/src/com/serotonin/mango/util/ThreadPoolExecutorUtils.java b/src/com/serotonin/mango/util/ThreadPoolExecutorUtils.java index 3215e37b94..fcaa505b63 100644 --- a/src/com/serotonin/mango/util/ThreadPoolExecutorUtils.java +++ b/src/com/serotonin/mango/util/ThreadPoolExecutorUtils.java @@ -1,6 +1,6 @@ package com.serotonin.mango.util; -import org.scada_lts.config.ThreadPoolExecutorConfig; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import org.scada_lts.utils.BlockingQueuesUtils; import org.scada_lts.utils.SystemSettingsUtils; import org.scada_lts.utils.TimeUnitUtils; @@ -11,7 +11,7 @@ public final class ThreadPoolExecutorUtils { private ThreadPoolExecutorUtils() {} - public static ThreadPoolExecutor createPool(ThreadPoolExecutorConfig.Priority priority) { + public static ThreadPoolExecutor createPool(WorkItemPriority priority) { int corePoolSize = SystemSettingsUtils.getThreadExecutorCorePoolSize(priority); int maximumPoolSize = SystemSettingsUtils.getThreadExecutorMaximumPoolSize(priority); @@ -22,7 +22,7 @@ public static ThreadPoolExecutor createPool(ThreadPoolExecutorConfig.Priority pr .orElse(TimeUnit.SECONDS); BlockingQueue blockingQueue = BlockingQueuesUtils .newBlockingQueue(SystemSettingsUtils.getThreadExecutorBlockingQueueInterfaceImpl(priority), - priority == ThreadPoolExecutorConfig.Priority.HIGH ? new SynchronousQueue<>() : new LinkedBlockingQueue<>(), objects); + priority == WorkItemPriority.HIGH ? new SynchronousQueue<>() : new LinkedBlockingQueue<>(), objects); return createThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, blockingQueue); } diff --git a/src/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java b/src/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java index 77b6c5146b..01ade83812 100644 --- a/src/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java +++ b/src/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java @@ -84,8 +84,8 @@ public void work() { } @Override - public int getPriority() { - return WorkItemPriority.HIGH.getPriority(); + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/com/serotonin/timer/sync/Synchronizer.java b/src/com/serotonin/timer/sync/Synchronizer.java index 55c4927a05..03f4e2da0e 100644 --- a/src/com/serotonin/timer/sync/Synchronizer.java +++ b/src/com/serotonin/timer/sync/Synchronizer.java @@ -187,8 +187,8 @@ public String toString() { } @Override - public int getPriority() { - return WorkItemPriority.HIGH.getPriority(); + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/com/serotonin/util/ProgressiveTask.java b/src/com/serotonin/util/ProgressiveTask.java index f38d47a8c8..3759da332d 100644 --- a/src/com/serotonin/util/ProgressiveTask.java +++ b/src/com/serotonin/util/ProgressiveTask.java @@ -74,8 +74,8 @@ private void declareFinished(boolean cancelled) { protected abstract void runImpl(); @Override - public int getPriority() { - return WorkItemPriority.HIGH.getPriority(); + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/org/scada_lts/config/ThreadPoolExecutorConfig.java b/src/org/scada_lts/config/ThreadPoolExecutorConfig.java index afa4e9990e..a44a56d553 100644 --- a/src/org/scada_lts/config/ThreadPoolExecutorConfig.java +++ b/src/org/scada_lts/config/ThreadPoolExecutorConfig.java @@ -1,5 +1,7 @@ package org.scada_lts.config; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; + /** * Enum with chain keys for thread pool config * @@ -27,23 +29,7 @@ public String getName() { return name; } - public enum Priority { - LOW("low-priority."), - MEDIUM("medium-priority."), - HIGH("high-priority."); - - private final String name; - - Priority(String priority) { - this.name = priority; - } - - public String getName() { - return name; - } - } - - public static String getKey(Priority priority, ThreadPoolExecutorConfig param) { + public static String getKey(WorkItemPriority priority, ThreadPoolExecutorConfig param) { return "thread-pool-executor." + priority.getName() + param.getName(); } } \ No newline at end of file diff --git a/src/org/scada_lts/dao/SystemSettingsDAO.java b/src/org/scada_lts/dao/SystemSettingsDAO.java index 286f763e0d..9a6ff52fdd 100644 --- a/src/org/scada_lts/dao/SystemSettingsDAO.java +++ b/src/org/scada_lts/dao/SystemSettingsDAO.java @@ -20,6 +20,7 @@ import com.serotonin.InvalidArgumentException; import com.serotonin.ShouldNeverHappenException; import com.serotonin.mango.Common; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import com.serotonin.mango.vo.DataPointVO; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/src/org/scada_lts/mango/service/EventService.java b/src/org/scada_lts/mango/service/EventService.java index 9e555d1e9a..0d1a54ad4d 100644 --- a/src/org/scada_lts/mango/service/EventService.java +++ b/src/org/scada_lts/mango/service/EventService.java @@ -104,8 +104,8 @@ public void work() { } @Override - public int getPriority() { - return WorkItemPriority.HIGH.getPriority(); + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/org/scada_lts/mango/service/PointValueService.java b/src/org/scada_lts/mango/service/PointValueService.java index deb730fbf1..5caa052eb9 100644 --- a/src/org/scada_lts/mango/service/PointValueService.java +++ b/src/org/scada_lts/mango/service/PointValueService.java @@ -33,6 +33,7 @@ import com.serotonin.mango.rt.dataSource.meta.MetaPointLocatorRT; import com.serotonin.mango.rt.dataSource.meta.ScriptExecutor; import com.serotonin.mango.rt.maint.work.AbstractBeforeAfterWorkItem; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import com.serotonin.mango.vo.DataPointVO; import com.serotonin.mango.vo.User; import com.serotonin.mango.vo.dataSource.DataSourceVO; @@ -46,6 +47,7 @@ import org.scada_lts.mango.adapter.MangoPointValues; import org.scada_lts.monitor.type.IntegerMonitor; +import org.scada_lts.utils.SystemSettingsUtils; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; @@ -56,7 +58,6 @@ import com.serotonin.mango.Common; import com.serotonin.mango.DataTypes; import com.serotonin.mango.ImageSaveException; -import com.serotonin.mango.rt.maint.work.WorkItem; import com.serotonin.mango.vo.AnonymousUser; import com.serotonin.mango.vo.bean.LongPair; import com.serotonin.util.queue.ObjectQueue; @@ -505,8 +506,8 @@ static class BatchWriteBehind extends AbstractBeforeAfterWorkItem { private static final ObjectQueue ENTRIES = new ObjectQueue(); private static final CopyOnWriteArrayList instances = new CopyOnWriteArrayList(); private static Log LOG = LogFactory.getLog(BatchWriteBehind.class); - private static final int SPAWN_THRESHOLD = 10000; - private static final int MAX_INSTANCES = 5; + private static int SPAWN_THRESHOLD = 10000; + private static int MAX_INSTANCES = 5; private static int MAX_ROWS = 1000; private static final IntegerMonitor ENTRIES_MONITOR = new IntegerMonitor( "BatchWriteBehind.ENTRIES_MONITOR", null); @@ -515,7 +516,10 @@ static class BatchWriteBehind extends AbstractBeforeAfterWorkItem { static { - MAX_ROWS = 2000; + MAX_ROWS = SystemSettingsUtils.getWorkItemsConfigBatchWriteBehindMaxRows(); + MAX_INSTANCES = SystemSettingsUtils.getWorkItemsConfigBatchWriteBehindMaxInstances(); + SPAWN_THRESHOLD = SystemSettingsUtils.getWorkItemsConfigBatchWriteBehindSpawnThreshold(); + Common.MONITORED_VALUES.addIfMissingStatMonitor(ENTRIES_MONITOR); Common.MONITORED_VALUES.addIfMissingStatMonitor(INSTANCES_MONITOR); @@ -607,8 +611,9 @@ public void work() { } } - public int getPriority() { - return WorkItem.PRIORITY_HIGH; + @Override + public WorkItemPriority getPriorityType() { + return WorkItemPriority.HIGH; } @Override diff --git a/src/org/scada_lts/utils/SystemSettingsUtils.java b/src/org/scada_lts/utils/SystemSettingsUtils.java index b37d5b556d..557ded4e45 100644 --- a/src/org/scada_lts/utils/SystemSettingsUtils.java +++ b/src/org/scada_lts/utils/SystemSettingsUtils.java @@ -4,9 +4,10 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.serotonin.mango.rt.dataImage.DataPointSyncMode; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import org.apache.commons.logging.LogFactory; import org.scada_lts.config.ScadaConfig; -import org.scada_lts.config.ThreadPoolExecutorConfig; + import org.scada_lts.web.mvc.api.AggregateSettings; import java.io.IOException; @@ -17,6 +18,8 @@ import static org.scada_lts.config.ThreadPoolExecutorConfig.getKey; import static org.scada_lts.utils.CreateObjectUtils.parseObjects; +import org.scada_lts.config.ThreadPoolExecutorConfig; + public final class SystemSettingsUtils { private SystemSettingsUtils() {} @@ -51,6 +54,10 @@ private SystemSettingsUtils() {} public static final String WEB_RESOURCE_GRAPHICS_PATH_KEY = "webresource.graphics.path"; public static final String WEB_RESOURCE_UPLOADS_PATH_KEY = "webresource.uploads.path"; + public static final String WORK_ITEMS_CONFIG_BATCH_WRITE_BEHIND_MAX_ROWS_KEY = "workitems.config.BatchWriteBehind.maxRows"; + public static final String WORK_ITEMS_CONFIG_BATCH_WRITE_BEHIND_MAX_INSTANCES_KEY = "workitems.config.BatchWriteBehind.maxInstances"; + public static final String WORK_ITEMS_CONFIG_BATCH_WRITE_BEHIND_SPAWN_THRESHOLD_KEY = "workitems.config.BatchWriteBehind.spawnThreshold"; + private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(SystemSettingsUtils.class); public static DataPointSyncMode getDataPointSynchronizedMode() { @@ -358,7 +365,7 @@ public static String getWebResourceGraphicsPath() { } } - public static String getThreadExecutorBlockingQueueInterfaceImpl(ThreadPoolExecutorConfig.Priority priority) { + public static String getThreadExecutorBlockingQueueInterfaceImpl(WorkItemPriority priority) { String defaultValue = "java.util.concurrent.LinkedBlockingQueue"; try { return ScadaConfig.getInstance().getConf().getProperty(getKey(priority, ThreadPoolExecutorConfig.BLOCKING_QUEUE_INTERFACE_IMPL), defaultValue); @@ -368,7 +375,7 @@ public static String getThreadExecutorBlockingQueueInterfaceImpl(ThreadPoolExecu } } - public static Object[] getThreadExecutorBlockingQueueInterfaceImplArgs(ThreadPoolExecutorConfig.Priority priority) { + public static Object[] getThreadExecutorBlockingQueueInterfaceImplArgs(WorkItemPriority priority) { Object[] defaultValue = new Object[0]; String defaultValue1 = ""; try { @@ -381,7 +388,7 @@ public static Object[] getThreadExecutorBlockingQueueInterfaceImplArgs(ThreadPoo } } - public static int getThreadExecutorCorePoolSize(ThreadPoolExecutorConfig.Priority priority) { + public static int getThreadExecutorCorePoolSize(WorkItemPriority priority) { int defaultValue = 1; try { String limit = ScadaConfig.getInstance().getConf().getProperty(getKey(priority, ThreadPoolExecutorConfig.CORE_POOL_SIZE), String.valueOf(defaultValue)); @@ -392,7 +399,7 @@ public static int getThreadExecutorCorePoolSize(ThreadPoolExecutorConfig.Priorit } } - public static int getThreadExecutorMaximumPoolSize(ThreadPoolExecutorConfig.Priority priority) { + public static int getThreadExecutorMaximumPoolSize(WorkItemPriority priority) { int defaultValue = 1; try { String limit = ScadaConfig.getInstance().getConf().getProperty(getKey(priority, ThreadPoolExecutorConfig.MAXIMUM_POOL_SIZE), String.valueOf(defaultValue)); @@ -403,7 +410,7 @@ public static int getThreadExecutorMaximumPoolSize(ThreadPoolExecutorConfig.Prio } } - public static long getThreadExecutorKeepAliveTime(ThreadPoolExecutorConfig.Priority priority) { + public static long getThreadExecutorKeepAliveTime(WorkItemPriority priority) { long defaultValue = 0; try { String limit = ScadaConfig.getInstance().getConf().getProperty(getKey(priority, ThreadPoolExecutorConfig.KEEP_ALIVE_TIME), String.valueOf(defaultValue)); @@ -414,7 +421,7 @@ public static long getThreadExecutorKeepAliveTime(ThreadPoolExecutorConfig.Prior } } - public static String getThreadExecutorTimeUnitEnumValue(ThreadPoolExecutorConfig.Priority priority) { + public static String getThreadExecutorTimeUnitEnumValue(WorkItemPriority priority) { String defaultValue = "MILLISECONDS"; try { return ScadaConfig.getInstance().getConf().getProperty(getKey(priority, ThreadPoolExecutorConfig.TIME_UNIT_ENUM_VALUE), defaultValue); @@ -423,4 +430,34 @@ public static String getThreadExecutorTimeUnitEnumValue(ThreadPoolExecutorConfig return defaultValue; } } + + public static int getWorkItemsConfigBatchWriteBehindMaxRows() { + try { + String config = ScadaConfig.getInstance().getConf().getProperty(WORK_ITEMS_CONFIG_BATCH_WRITE_BEHIND_MAX_ROWS_KEY, "255"); + return Integer.parseInt(config); + } catch (Exception e) { + LOG.error(e.getMessage()); + return 255; + } + } + + public static int getWorkItemsConfigBatchWriteBehindMaxInstances() { + try { + String config = ScadaConfig.getInstance().getConf().getProperty(WORK_ITEMS_CONFIG_BATCH_WRITE_BEHIND_MAX_INSTANCES_KEY, "255"); + return Integer.parseInt(config); + } catch (Exception e) { + LOG.error(e.getMessage()); + return 255; + } + } + + public static int getWorkItemsConfigBatchWriteBehindSpawnThreshold() { + try { + String config = ScadaConfig.getInstance().getConf().getProperty(WORK_ITEMS_CONFIG_BATCH_WRITE_BEHIND_SPAWN_THRESHOLD_KEY, "255"); + return Integer.parseInt(config); + } catch (Exception e) { + LOG.error(e.getMessage()); + return 255; + } + } } diff --git a/src/org/scada_lts/web/mvc/api/WorkItemInfoApiService.java b/src/org/scada_lts/web/mvc/api/WorkItemInfoApiService.java index 223a6c3c21..77c804d242 100644 --- a/src/org/scada_lts/web/mvc/api/WorkItemInfoApiService.java +++ b/src/org/scada_lts/web/mvc/api/WorkItemInfoApiService.java @@ -649,7 +649,7 @@ static Predicate isRunning() { } static Predicate isPriority(WorkItemPriority priority) { - return execute -> WorkItemPriority.priorityOf(execute.getWorkItem().getPriority()) == priority; + return execute -> execute.getPriority() == priority; } } } diff --git a/test/org/scada_lts/utils/ThreadPoolExecutorConfigSystemSettingsUtilsTest.java b/test/org/scada_lts/utils/ThreadPoolExecutorConfigSystemSettingsUtilsTest.java index c69852d8cb..c8c2543ea7 100644 --- a/test/org/scada_lts/utils/ThreadPoolExecutorConfigSystemSettingsUtilsTest.java +++ b/test/org/scada_lts/utils/ThreadPoolExecutorConfigSystemSettingsUtilsTest.java @@ -1,12 +1,12 @@ package org.scada_lts.utils; import com.serotonin.mango.Common; +import com.serotonin.mango.rt.maint.work.WorkItemPriority; import com.serotonin.mango.web.ContextWrapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import org.scada_lts.config.ThreadPoolExecutorConfig; import javax.servlet.ServletContext; @@ -25,13 +25,13 @@ public class ThreadPoolExecutorConfigSystemSettingsUtilsTest { @Parameterized.Parameters(name = "{index}: priority: {0}, blockingQueueInterfaceImpl: {1}, corePoolSize: {2}, maximumPoolSize: {3}, keepAliveTime: {4}, timeUnitEnumValue: {5}") public static List data() { List datas = new ArrayList<>(); - datas.add(new Object[] {ThreadPoolExecutorConfig.Priority.LOW, "java.util.concurrent.LinkedBlockingQueue", 1, 1, 0L, "MILLISECONDS", new Object[]{3, 4L}}); - datas.add(new Object[] {ThreadPoolExecutorConfig.Priority.MEDIUM, "java.util.concurrent.LinkedBlockingQueue", 3, 100, 60L, "SECONDS", new Object[]{"abc", true}}); - datas.add(new Object[] {ThreadPoolExecutorConfig.Priority.HIGH, "java.util.concurrent.SynchronousQueue", 0, 1000, 30L, "SECONDS", new Object[]{}}); + datas.add(new Object[] {WorkItemPriority.LOW, "java.util.concurrent.LinkedBlockingQueue", 1, 1, 0L, "MILLISECONDS", new Object[]{3, 4L}}); + datas.add(new Object[] {WorkItemPriority.MEDIUM, "java.util.concurrent.LinkedBlockingQueue", 3, 100, 60L, "SECONDS", new Object[]{"abc", true}}); + datas.add(new Object[] {WorkItemPriority.HIGH, "java.util.concurrent.SynchronousQueue", 0, 1000, 30L, "SECONDS", new Object[]{}}); return datas; } - private final ThreadPoolExecutorConfig.Priority priority; + private final WorkItemPriority priority; private final String blockingQueueInterfaceImpl; private final int corePoolSize; private final int maximumPoolSize; @@ -39,7 +39,7 @@ public static List data() { private final String timeUnitEnumValue; private final Object[] args; - public ThreadPoolExecutorConfigSystemSettingsUtilsTest(ThreadPoolExecutorConfig.Priority priority, String blockingQueueInterfaceImpl, int corePoolSize, int maximumPoolSize, long keepAliveTime, String timeUnitEnumValue, Object[] args) { + public ThreadPoolExecutorConfigSystemSettingsUtilsTest(WorkItemPriority priority, String blockingQueueInterfaceImpl, int corePoolSize, int maximumPoolSize, long keepAliveTime, String timeUnitEnumValue, Object[] args) { this.priority = priority; this.blockingQueueInterfaceImpl = blockingQueueInterfaceImpl; this.corePoolSize = corePoolSize; diff --git a/test/org/scada_lts/web/mvc/api/json/WorkItemInfoListTest.java b/test/org/scada_lts/web/mvc/api/json/WorkItemInfoListTest.java index 4d14941ae6..7c37a3e409 100644 --- a/test/org/scada_lts/web/mvc/api/json/WorkItemInfoListTest.java +++ b/test/org/scada_lts/web/mvc/api/json/WorkItemInfoListTest.java @@ -48,8 +48,8 @@ public void work() { } @Override - public int getPriority() { - return 0; + public WorkItemPriority getPriorityType() { + return WorkItemPriority.LOW; } @Override diff --git a/webapp-resources/env.properties b/webapp-resources/env.properties index b0e81e724b..f0cfcf037c 100644 --- a/webapp-resources/env.properties +++ b/webapp-resources/env.properties @@ -106,6 +106,8 @@ svg.validator.schemas=svg/svg11-flat-20110816/svg11-flat-20110816.xsd;svg/svg10- # rdf:RDF - https://www.w3.org/TR/SVGTiny12/metadata.html svg.validator.tags.ignore=rdf:RDF;sodipodi:namedview;inkscape:perspective svg.validator.messages.ignore=must appear on element;muss in Element;Attribute 'blend' is not allowed to appear in element 'feBlend'.;sodipodi:;inkscape:;Attribute 'vector-effect' is not allowed to appear in element 'g'.;Attribut 'vector-effect' darf nicht in Element 'g' vorkommen.; +svg.validator.disallow-doctype-decl.enabled=false + systemsettings.http.response.headers={} datapoint.runtime.value.synchronized=NONE @@ -145,9 +147,8 @@ workitems.reporting.itemspersecond.limit=20000 webresource.uploads.path=static/uploads webresource.graphics.path=static/graphics -svg.validator.disallow-doctype-decl.enabled=false -thread-pool-executor.low-priority.core-pool-size=1 +thread-pool-executor.low-priority.core-pool-size=0 thread-pool-executor.low-priority.maximum-pool-size=1 thread-pool-executor.low-priority.keep-alive-time=0 #blocking-queue-interface-impl: LinkedBlockingDeque, LinkedBlockingQueue, LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue @@ -156,7 +157,7 @@ thread-pool-executor.low-priority.blocking-queue-interface-impl.args= thread-pool-executor.low-priority.blocking-queue-interface-impl.args-types= thread-pool-executor.low-priority.time-unit-enum-value=MILLISECONDS -thread-pool-executor.medium-priority.core-pool-size=3 +thread-pool-executor.medium-priority.core-pool-size=16 thread-pool-executor.medium-priority.maximum-pool-size=100 thread-pool-executor.medium-priority.keep-alive-time=60 #blocking-queue-interface-impl: LinkedBlockingDeque, LinkedBlockingQueue, LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue @@ -172,4 +173,8 @@ thread-pool-executor.high-priority.keep-alive-time=30 thread-pool-executor.high-priority.blocking-queue-interface-impl=java.util.concurrent.SynchronousQueue thread-pool-executor.high-priority.blocking-queue-interface-impl.args= thread-pool-executor.high-priority.blocking-queue-interface-impl.args-types= -thread-pool-executor.high-priority.time-unit-enum-value=SECONDS \ No newline at end of file +thread-pool-executor.high-priority.time-unit-enum-value=SECONDS + +workitems.config.BatchWriteBehind.maxRows=4000 +workitems.config.BatchWriteBehind.maxInstances=5 +workitems.config.BatchWriteBehind.spawnThreshold=10000 \ No newline at end of file