Skip to content

Commit

Permalink
#2618 Improved stability for a large number of events - added paramet…
Browse files Browse the repository at this point in the history
…er 'Enabled Event Pending Cache' to System Settings old and new ui;
  • Loading branch information
Limraj committed Jul 18, 2023
1 parent 26d58f8 commit 429b19e
Show file tree
Hide file tree
Showing 24 changed files with 174 additions and 33 deletions.
8 changes: 8 additions & 0 deletions WebContent/WEB-INF/jsp/systemSettings.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
$set("<c:out value="<%= SystemSettingsDAO.VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN %>"/>", settings.<c:out value="<%= SystemSettingsDAO.VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN %>"/>);
$set("<c:out value="<%= SystemSettingsDAO.EVENT_PENDING_LIMIT %>"/>", settings.<c:out value="<%= SystemSettingsDAO.EVENT_PENDING_LIMIT %>"/>);
$set("<c:out value="<%= SystemSettingsDAO.EVENT_PENDING_CACHE_ENABLED %>"/>", settings.<c:out value="<%= SystemSettingsDAO.EVENT_PENDING_CACHE_ENABLED %>"/>);
var sel = $("<c:out value="<%= SystemSettingsDAO.LANGUAGE %>"/>");
<c:forEach items="${availableLanguages}" var="lang">
sel.options[sel.options.length] = new Option("${lang.value}", "${lang.key}");
Expand Down Expand Up @@ -271,6 +272,7 @@
$get("<c:out value="<%= SystemSettingsDAO.VIEW_FORCE_FULL_SCREEN_MODE %>"/>"),
$get("<c:out value="<%= SystemSettingsDAO.VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN %>"/>"),
$get("<c:out value="<%= SystemSettingsDAO.EVENT_PENDING_LIMIT %>"/>"),
$get("<c:out value="<%= SystemSettingsDAO.EVENT_PENDING_CACHE_ENABLED %>"/>"),
function(response) {
stopImageFader("saveMiscSettingsImg");
if (response.hasMessages)
Expand Down Expand Up @@ -874,6 +876,12 @@
<input type="checkbox" id="<c:out value="<%= SystemSettingsDAO.VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN %>"/>" />
</td>
</tr>
<tr>
<td class="formLabelRequired"><fmt:message key="systemsettings.event.pendingCacheEnabled"/></td>
<td class="formField">
<input id="<c:out value="<%= SystemSettingsDAO.EVENT_PENDING_CACHE_ENABLED %>"/>" type="checkbox" />
</td>
</tr>
<tr>
<td class="formLabelRequired"><fmt:message key="systemsettings.event.pendingLimit"/></td>
<td class="formField">
Expand Down
3 changes: 2 additions & 1 deletion scadalts-ui/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1054,5 +1054,6 @@
"userDetails.view.forceAdminTitle": "The function is enforced by the Admin",
"userDetails.view.enableFullScreen": "Enable full screen mode",
"userDetails.view.hideShortcutDisableFullScreen": "Hide shortcut to disable full screen",
"systemsettings.event.pendingLimit": "Event Pending Limit"
"systemsettings.event.pendingLimit": "Event Pending Limit",
"systemsettings.event.pendingCacheEnabled": "Enabled Event Pending Cache"
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
@change="watchDataChange()"
></v-switch>
</v-col>
<v-col cols="12">
<v-switch
v-model="miscSettings.eventPendingCacheEnabled"
:label="$t('systemsettings.event.pendingCacheEnabled')"
@change="watchDataChange()"
></v-switch>
</v-col>
<v-col cols="12">
<v-text-field
v-model="miscSettings.eventPendingLimit"
Expand Down
28 changes: 20 additions & 8 deletions src/com/serotonin/mango/rt/event/type/SystemEventType.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@
*/
package com.serotonin.mango.rt.event.type;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import com.serotonin.json.JsonException;
import com.serotonin.json.JsonObject;
import com.serotonin.json.JsonReader;
import com.serotonin.json.JsonRemoteEntity;
import com.serotonin.mango.Common;
import com.serotonin.mango.util.LoggingUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.scada_lts.dao.SystemSettingsDAO;
import com.serotonin.mango.rt.event.AlarmLevels;
import com.serotonin.mango.util.ExportCodes;
Expand All @@ -40,6 +43,7 @@ public class SystemEventType extends EventType {
// / Static stuff
// /
//
private static final Log LOG = LogFactory.getLog(SystemEventType.class);
private static final String SYSTEM_SETTINGS_PREFIX = "systemEventAlarmLevel";

public static final int TYPE_SYSTEM_STARTUP = 1;
Expand Down Expand Up @@ -74,7 +78,7 @@ public class SystemEventType extends EventType {

public static List<EventTypeVO> getSystemEventTypes() {
if (systemEventTypes == null) {
systemEventTypes = new ArrayList<EventTypeVO>();
systemEventTypes = new CopyOnWriteArrayList<>();

addEventTypeVO(TYPE_SYSTEM_STARTUP, "event.system.startup",
AlarmLevels.INFORMATION);
Expand Down Expand Up @@ -118,18 +122,26 @@ public static EventTypeVO getEventType(int type) {

public static void setEventTypeAlarmLevel(int type, int alarmLevel) {
EventTypeVO et = getEventType(type);
et.setAlarmLevel(alarmLevel);
if(et != null) {
et.setAlarmLevel(alarmLevel);

SystemSettingsDAO dao = new SystemSettingsDAO();
dao.setIntValue(SYSTEM_SETTINGS_PREFIX + type, alarmLevel);
SystemSettingsDAO dao = new SystemSettingsDAO();
dao.setIntValue(SYSTEM_SETTINGS_PREFIX + type, alarmLevel);
} else {
LOG.warn(LoggingUtils.eventTypeInfo(type, alarmLevel));
}
}

public static void raiseEvent(SystemEventType type, long time, boolean rtn,
LocalizableMessage message) {
EventTypeVO vo = getEventType(type.getSystemEventTypeId());
int alarmLevel = vo.getAlarmLevel();
Common.ctx.getEventManager().raiseEvent(type, time, rtn, alarmLevel,
message, null);
if(vo != null) {
int alarmLevel = vo.getAlarmLevel();
Common.ctx.getEventManager().raiseEvent(type, time, rtn, alarmLevel,
message, null);
} else {
LOG.warn(LoggingUtils.systemEventTypInfo(type));
}
}

public static void returnToNormal(SystemEventType type, long time) {
Expand Down
25 changes: 25 additions & 0 deletions src/com/serotonin/mango/util/LoggingUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
import com.serotonin.mango.rt.dataImage.SetPointSource;
import com.serotonin.mango.rt.dataSource.DataSourceRT;
import com.serotonin.mango.rt.event.EventInstance;
import com.serotonin.mango.rt.event.type.SystemEventType;
import com.serotonin.mango.view.component.ScriptComponent;
import com.serotonin.mango.vo.DataPointVO;
import com.serotonin.mango.vo.User;
import com.serotonin.mango.vo.dataSource.DataSourceVO;
import com.serotonin.mango.vo.event.EventHandlerVO;
import com.serotonin.mango.vo.event.EventTypeVO;
import com.serotonin.mango.vo.event.PointEventDetectorVO;
import com.serotonin.mango.vo.link.PointLinkVO;
import com.serotonin.mango.vo.mailingList.MailingList;
Expand Down Expand Up @@ -164,4 +166,27 @@ public static String mailingListInfo(MailingList mailingList) {
String info = "mailingList: {0} (id: {1}, xid: {2})";
return MessageFormat.format(info, mailingList.getName(), mailingList.getId(), mailingList.getXid());
}

public static String eventTypeInfo(EventTypeVO event) {
if(event == null)
return "";
String info = "event type: {0} (typeId: {1}, typeRef1: {2}, typeRef2: {3}, alarmLevel: {4}, eventDetectorKey: {4})";
return MessageFormat.format(info, event.getDescription(), event.getTypeId(), event.getTypeRef1(), event.getTypeRef2(), event.getAlarmLevel(), event.getEventDetectorKey());
}

public static String systemEventTypInfo(SystemEventType event) {
if(event == null)
return "";
String info = "system event type (systemEventTypeId: {0}, dataSourceId: {1}, dataPointId: {2}, eventSourceId: {3}, " +
"duplicateHandling: {4}, referenceId1: {5}, referenceId2: {6}, compoundEventDetectorId: {7}, scheduleId: {8}, " +
"publisherId: {9}, systemMessage: {10})";
return MessageFormat.format(info, event.getSystemEventTypeId(), event.getDataSourceId(), event.getDataPointId(),
event.getEventSourceId(), event.getDuplicateHandling(), event.getReferenceId1(), event.getReferenceId2(),
event.getCompoundEventDetectorId(), event.getScheduleId(), event.getPublisherId(), event.isSystemMessage());
}

public static String eventTypeInfo(int type, int alarmLevel) {
String info = "event type: {0} (alarmLevel: {1})";
return MessageFormat.format(info, type, alarmLevel);
}
}
5 changes: 4 additions & 1 deletion src/com/serotonin/mango/web/dwr/SystemSettingsDwr.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ public Map<String, Object> getSettings() {
systemSettingsService.getMiscSettings().isEnableFullScreen());
settings.put(SystemSettingsDAO.EVENT_PENDING_LIMIT,
systemSettingsService.getMiscSettings().getEventPendingLimit());
settings.put(SystemSettingsDAO.EVENT_PENDING_CACHE_ENABLED,
systemSettingsService.getMiscSettings().isEventPendingCacheEnabled());
return settings;
}

Expand Down Expand Up @@ -311,7 +313,7 @@ public DwrResponseI18n saveHttpSettings(boolean useProxy, String host, int port,

public DwrResponseI18n saveMiscSettings(int uiPerformance, String dataPointRtValueSynchronized,
boolean viewEnableFullScreen, boolean viewHideShortcutDisableFullScreen,
int eventPendingLimit) {
int eventPendingLimit, boolean eventPendingCacheEnabled) {
Permissions.ensureAdmin();
SystemSettingsDAO systemSettingsDAO = new SystemSettingsDAO();
DwrResponseI18n response = new DwrResponseI18n();
Expand All @@ -331,6 +333,7 @@ public DwrResponseI18n saveMiscSettings(int uiPerformance, String dataPointRtVal
} else {
systemSettingsDAO.setIntValue(SystemSettingsDAO.EVENT_PENDING_LIMIT, eventPendingLimit);
}
systemSettingsDAO.setBooleanValue(SystemSettingsDAO.EVENT_PENDING_CACHE_ENABLED, eventPendingCacheEnabled);
return response;
}

Expand Down
61 changes: 53 additions & 8 deletions src/org/scada_lts/cache/PendingEventsCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.scada_lts.config.ScadaConfig;
import org.scada_lts.mango.service.PendingEventService;
import org.scada_lts.mango.service.SystemSettingsService;
import org.scada_lts.quartz.UpdatePendingEvents;

import com.serotonin.mango.rt.event.EventInstance;
Expand All @@ -49,6 +47,10 @@ public class PendingEventsCache {
private int countBuffer;
private Map<Integer, List<EventInstance>> mapPendingEvents;
private final PendingEventService eventService;
private final Scheduler scheduler;
private final SystemSettingsService systemSettingsService;
private final JobDetail job;
private final SimpleTrigger trigger;

public static PendingEventsCache getInstance() throws SchedulerException, IOException {
if (LOG.isTraceEnabled()) {
Expand Down Expand Up @@ -113,17 +115,55 @@ private PendingEventsCache() throws SchedulerException, IOException {
}
eventService = new PendingEventService();
mapPendingEvents = eventService.getPendingEvents();
scheduler = new StdSchedulerFactory().getScheduler();
systemSettingsService = new SystemSettingsService();
trigger = createTrigger();
job = createJob();
cacheInitialize();
}

private void cacheInitialize() throws SchedulerException, IOException {
if (LOG.isTraceEnabled()) {
LOG.trace("cacheInitialize");
}
scheduler.start();
startUpdate();
}

public void startUpdate() {
try {
if(!isScheduled(scheduler, job.getName()))
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
LOG.error(e.getMessage(), e);
}
}

public void stopUpdate() {
try {
if(isScheduled(scheduler, job.getName()))
scheduler.deleteJob(job.getName(), job.getGroup());
} catch (SchedulerException e) {
LOG.error(e.getMessage(), e);
}
}

public void resetUpdate() {
boolean cacheEnable = systemSettingsService.getMiscSettings().isEventPendingCacheEnabled();
if(cacheEnable)
startUpdate();
else
stopUpdate();
}

private static JobDetail createJob() {
JobDetail job = new JobDetail();
job.setName("UpdatePendingEvents");
job.setJobClass(UpdatePendingEvents.class);
return job;
}

private static SimpleTrigger createTrigger() throws IOException {
SimpleTrigger trigger = new SimpleTrigger();
Date startTime = new Date(System.currentTimeMillis()
+ ScadaConfig.getInstance().getLong(ScadaConfig.START_UPDATE_PENDING_EVENTS, 10_000_000));
Expand All @@ -138,10 +178,15 @@ private void cacheInitialize() throws SchedulerException, IOException {
}
trigger.setRepeatInterval(interval);
trigger.setName("Quartz - trigger-UpdatePendingEvents");

Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
return trigger;
}

private static boolean isScheduled(Scheduler scheduler, String jobName) throws SchedulerException {
for (String groupName : scheduler.getJobGroupNames()) {
Trigger[] triggers = scheduler.getTriggersOfJob(jobName, groupName);
if(triggers.length > 0)
return true;
}
return false;
}
}
5 changes: 4 additions & 1 deletion src/org/scada_lts/dao/SystemSettingsDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public class SystemSettingsDAO {
private static final String DELETE_POINT_VALUES = "delete from pointValues";
private static final String DELETE_MAINTENANCE_EVENTS = "delete from maintenanceEvents";
private static final String DELETE_MAILING_LISTS = "delete from mailingLists";
@Deprecated
@Deprecated(since = "2.7.5.4")
private static final String DELETE_USERS = "delete from users";
private static final String DELETE_PUBLISHERS = "delete from publishers";
private static final String DELETE_DATA_POINT_USERS = "delete from dataPointUsers";
Expand All @@ -156,6 +156,8 @@ public class SystemSettingsDAO {
public static final String VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN = "hideShortcutDisableFullScreen";
public static final String VIEW_FORCE_FULL_SCREEN_MODE = "viewForceFullScreenMode";
public static final String EVENT_PENDING_LIMIT = "eventPendingLimit";

public static final String EVENT_PENDING_CACHE_ENABLED = "eventPendingCacheEnabled";
// @formatter:off
private static final String SELECT_SETTING_VALUE_WHERE = ""
+ "select "
Expand Down Expand Up @@ -390,6 +392,7 @@ public String getDatabaseSchemaVersion(String key, String defaultValue) {
DEFAULT_VALUES.put(VIEW_FORCE_FULL_SCREEN_MODE, SystemSettingsUtils.isForceFullScreenMode());
DEFAULT_VALUES.put(VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN, SystemSettingsUtils.isHideShortcutDisableFullScreen());
DEFAULT_VALUES.put(EVENT_PENDING_LIMIT, SystemSettingsUtils.getEventPendingLimit());
DEFAULT_VALUES.put(EVENT_PENDING_CACHE_ENABLED, SystemSettingsUtils.isEventPendingCacheEnabled());
}

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED, rollbackFor = SQLException.class)
Expand Down
7 changes: 5 additions & 2 deletions src/org/scada_lts/mango/service/EventService.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public List<EventInstance> getPendingEvents(int typeId, int typeRef1, int userId

}

@Deprecated
@Deprecated(since = "2.7.5.4")
@Override
public List<EventInstance> getPendingSimpleEvents(int typeId, int typeRef1, int userId) {

Expand Down Expand Up @@ -261,13 +261,16 @@ public List<EventInstance> getPendingEventsAlarmLevelMin(int userId, int alarmLe
public List<EventInstance> getPendingEventsAlarmLevelMin(int userId, int alarmLevelMin, int limit, boolean forceDisabledCache) {
List<EventInstance> results = null;
try {
boolean cacheEnable = ScadaConfig.getInstance().getBoolean(ScadaConfig.ENABLE_CACHE, false);
boolean cacheEnable = systemSettingsService.getMiscSettings().isEventPendingCacheEnabled();
if (!forceDisabledCache && cacheEnable) {
PendingEventsCache.getInstance().startUpdate();
results = PendingEventsCache.getInstance().getPendingEvents(userId).stream()
.sorted(Comparator.comparing(EventInstance::getActiveTimestamp))
.filter(a -> alarmLevelMin < 0 || a.getAlarmLevel() >= alarmLevelMin)
.collect(Collectors.toList());
} else {
if(!forceDisabledCache)
PendingEventsCache.getInstance().stopUpdate();
int fromSystemSettingsLimit = systemSettingsService.getMiscSettings().getEventPendingLimit();
int calcLimit = limit > -1 ? limit : fromSystemSettingsLimit;
if(alarmLevelMin > 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/org/scada_lts/mango/service/SystemSettingsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ public JsonSettingsMisc getMiscSettings() {
json.setHideShortcutDisableFullScreen(SystemSettingsDAO.getBooleanValue(SystemSettingsDAO.VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN, false));
json.setEnableFullScreen(SystemSettingsDAO.getBooleanValue(SystemSettingsDAO.VIEW_FORCE_FULL_SCREEN_MODE, false));
json.setEventPendingLimit(SystemSettingsDAO.getIntValue(SystemSettingsDAO.EVENT_PENDING_LIMIT, 100));
json.setEventPendingCacheEnabled(SystemSettingsDAO.getBooleanValue(SystemSettingsDAO.EVENT_PENDING_CACHE_ENABLED, false));
return json;
}

Expand All @@ -143,6 +144,7 @@ public void saveMiscSettings(JsonSettingsMisc json) {
systemSettingsDAO.setBooleanValue(SystemSettingsDAO.VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN, json.isHideShortcutDisableFullScreen());
systemSettingsDAO.setBooleanValue(SystemSettingsDAO.VIEW_FORCE_FULL_SCREEN_MODE, json.isEnableFullScreen());
systemSettingsDAO.setIntValue(SystemSettingsDAO.EVENT_PENDING_LIMIT, json.getEventPendingLimit());
systemSettingsDAO.setBooleanValue(SystemSettingsDAO.EVENT_PENDING_CACHE_ENABLED, json.isEventPendingCacheEnabled());
}

public SettingsDataRetention getDataRetentionSettings() {
Expand Down
1 change: 1 addition & 0 deletions src/org/scada_lts/quartz/UpdatePendingEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public UpdatePendingEvents() {
public void execute(JobExecutionContext arg0) throws JobExecutionException {
LOG.trace("UpdatePendingEvents");
try {
PendingEventsCache.getInstance().resetUpdate();
PendingEventsCache.getInstance().setMapPendingEvents(pendingEventService.getPendingEvents());
PendingEventsCache.getInstance().resetCountBuffer();
} catch (SchedulerException | IOException e) {
Expand Down
11 changes: 11 additions & 0 deletions src/org/scada_lts/utils/SystemSettingsUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ private SystemSettingsUtils() {}
public static final String VIEW_FORCE_FULL_SCREEN_MODE = "view.forceFullScreen";
public static final String VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN = "view.hideShortcutDisableFullScreen";
public static final String EVENT_PENDING_LIMIT = "event.pending.limit";
public static final String EVENT_PENDING_CACHE_ENABLED = "abilit.cacheEnable";
private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(SystemSettingsUtils.class);

public static DataPointSyncMode getDataPointSynchronizedMode() {
Expand Down Expand Up @@ -213,4 +214,14 @@ public static int getEventPendingLimit() {
return 100;
}
}

public static boolean isEventPendingCacheEnabled() {
try {
String eventPendingCache = ScadaConfig.getInstance().getConf().getProperty(EVENT_PENDING_CACHE_ENABLED, "false");
return Boolean.parseBoolean(eventPendingCache);
} catch (Exception e) {
LOG.error(e.getMessage());
return false;
}
}
}
Loading

0 comments on commit 429b19e

Please sign in to comment.