This is an automated email from the ASF dual-hosted git repository. shuber pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/unomi.git
The following commit(s) were added to refs/heads/master by this push: new 1e6ca58 UNOMI-235 Exceptions cancel timers Due to the way Executors work, any uncaught exceptions will cancel a timer, preventing it to executed in the future. This fix makes sure that all exceptions are caught and logged. 1e6ca58 is described below commit 1e6ca5877351188f53aaee884fbb55466bf6eea9 Author: Serge Huber <shu...@apache.org> AuthorDate: Sun Jun 9 15:48:26 2019 +0200 UNOMI-235 Exceptions cancel timers Due to the way Executors work, any uncaught exceptions will cancel a timer, preventing it to executed in the future. This fix makes sure that all exceptions are caught and logged. Signed-off-by: Serge Huber <shu...@apache.org> --- .../services/services/ClusterServiceImpl.java | 6 +- .../services/services/DefinitionsServiceImpl.java | 8 ++- .../services/services/ProfileServiceImpl.java | 81 ++++++++++++---------- .../unomi/services/services/RulesServiceImpl.java | 12 +++- .../services/services/SegmentServiceImpl.java | 36 +++++++--- 5 files changed, 92 insertions(+), 51 deletions(-) diff --git a/services/src/main/java/org/apache/unomi/services/services/ClusterServiceImpl.java b/services/src/main/java/org/apache/unomi/services/services/ClusterServiceImpl.java index 03a4dc6..06792cc 100644 --- a/services/src/main/java/org/apache/unomi/services/services/ClusterServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/services/ClusterServiceImpl.java @@ -159,7 +159,11 @@ public class ClusterServiceImpl implements ClusterService { TimerTask statisticsTask = new TimerTask() { @Override public void run() { - updateSystemStats(); + try { + updateSystemStats(); + } catch (Throwable t) { + logger.error("Error updating system statistics", t); + } } }; schedulerService.getScheduleExecutorService().scheduleWithFixedDelay(statisticsTask, 0, nodeStatisticsUpdateFrequency, TimeUnit.MILLISECONDS); diff --git a/services/src/main/java/org/apache/unomi/services/services/DefinitionsServiceImpl.java b/services/src/main/java/org/apache/unomi/services/services/DefinitionsServiceImpl.java index 65f767e..10ad331 100644 --- a/services/src/main/java/org/apache/unomi/services/services/DefinitionsServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/services/DefinitionsServiceImpl.java @@ -98,8 +98,12 @@ public class DefinitionsServiceImpl implements DefinitionsService, SynchronousBu TimerTask task = new TimerTask() { @Override public void run() { - loadConditionTypesFromPersistence(); - loadActionTypesFromPersistence(); + try { + loadConditionTypesFromPersistence(); + loadActionTypesFromPersistence(); + } catch (Throwable t) { + logger.error("Error loading definitions from persistence back-end", t); + } } }; schedulerService.getScheduleExecutorService().scheduleAtFixedRate(task, 10000, definitionsRefreshInterval, TimeUnit.MILLISECONDS); diff --git a/services/src/main/java/org/apache/unomi/services/services/ProfileServiceImpl.java b/services/src/main/java/org/apache/unomi/services/services/ProfileServiceImpl.java index 9f023e3..0300d46 100644 --- a/services/src/main/java/org/apache/unomi/services/services/ProfileServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/services/ProfileServiceImpl.java @@ -25,7 +25,10 @@ import org.apache.unomi.api.conditions.Condition; import org.apache.unomi.api.conditions.ConditionType; import org.apache.unomi.api.query.Query; import org.apache.unomi.api.segments.Segment; -import org.apache.unomi.api.services.*; +import org.apache.unomi.api.services.DefinitionsService; +import org.apache.unomi.api.services.ProfileService; +import org.apache.unomi.api.services.SchedulerService; +import org.apache.unomi.api.services.SegmentService; import org.apache.unomi.persistence.spi.CustomObjectMapper; import org.apache.unomi.persistence.spi.PersistenceService; import org.apache.unomi.persistence.spi.PropertyHelper; @@ -255,7 +258,11 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList TimerTask task = new TimerTask() { @Override public void run() { - loadPropertyTypesFromPersistence(); + try { + loadPropertyTypesFromPersistence(); + } catch (Throwable t) { + logger.error("Error loading property types from persistence back-end", t); + } } }; schedulerService.getScheduleExecutorService().scheduleAtFixedRate(task, 10000, propertiesRefreshInterval, TimeUnit.MILLISECONDS); @@ -284,47 +291,51 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList TimerTask task = new TimerTask() { @Override public void run() { - long t = System.currentTimeMillis(); - logger.debug("Profile purge: Purge triggered"); - - if (purgeProfileQuery == null) { - ConditionType profilePropertyConditionType = definitionsService.getConditionType("profilePropertyCondition"); - ConditionType booleanCondition = definitionsService.getConditionType("booleanCondition"); - if (profilePropertyConditionType == null || booleanCondition == null) { - // definition service not yet fully instantiate - return; - } + try { + long purgeStartTime = System.currentTimeMillis(); + logger.debug("Profile purge: Purge triggered"); + + if (purgeProfileQuery == null) { + ConditionType profilePropertyConditionType = definitionsService.getConditionType("profilePropertyCondition"); + ConditionType booleanCondition = definitionsService.getConditionType("booleanCondition"); + if (profilePropertyConditionType == null || booleanCondition == null) { + // definition service not yet fully instantiate + return; + } - purgeProfileQuery = new Condition(booleanCondition); - purgeProfileQuery.setParameter("operator", "or"); - List<Condition> subConditions = new ArrayList<>(); + purgeProfileQuery = new Condition(booleanCondition); + purgeProfileQuery.setParameter("operator", "or"); + List<Condition> subConditions = new ArrayList<>(); - if (purgeProfileInactiveTime > 0) { - Condition inactiveTimeCondition = new Condition(profilePropertyConditionType); - inactiveTimeCondition.setParameter("propertyName", "lastVisit"); - inactiveTimeCondition.setParameter("comparisonOperator", "lessThanOrEqualTo"); - inactiveTimeCondition.setParameter("propertyValueDateExpr", "now-" + purgeProfileInactiveTime + "d"); - subConditions.add(inactiveTimeCondition); - } + if (purgeProfileInactiveTime > 0) { + Condition inactiveTimeCondition = new Condition(profilePropertyConditionType); + inactiveTimeCondition.setParameter("propertyName", "lastVisit"); + inactiveTimeCondition.setParameter("comparisonOperator", "lessThanOrEqualTo"); + inactiveTimeCondition.setParameter("propertyValueDateExpr", "now-" + purgeProfileInactiveTime + "d"); + subConditions.add(inactiveTimeCondition); + } - if (purgeProfileExistTime > 0) { - Condition existTimeCondition = new Condition(profilePropertyConditionType); - existTimeCondition.setParameter("propertyName", "firstVisit"); - existTimeCondition.setParameter("comparisonOperator", "lessThanOrEqualTo"); - existTimeCondition.setParameter("propertyValueDateExpr", "now-" + purgeProfileExistTime + "d"); - subConditions.add(existTimeCondition); + if (purgeProfileExistTime > 0) { + Condition existTimeCondition = new Condition(profilePropertyConditionType); + existTimeCondition.setParameter("propertyName", "firstVisit"); + existTimeCondition.setParameter("comparisonOperator", "lessThanOrEqualTo"); + existTimeCondition.setParameter("propertyValueDateExpr", "now-" + purgeProfileExistTime + "d"); + subConditions.add(existTimeCondition); + } + + purgeProfileQuery.setParameter("subConditions", subConditions); } - purgeProfileQuery.setParameter("subConditions", subConditions); - } + persistenceService.removeByQuery(purgeProfileQuery, Profile.class); - persistenceService.removeByQuery(purgeProfileQuery, Profile.class); + if (purgeSessionsAndEventsTime > 0) { + persistenceService.purge(getMonth(-purgeSessionsAndEventsTime).getTime()); + } - if (purgeSessionsAndEventsTime > 0) { - persistenceService.purge(getMonth(-purgeSessionsAndEventsTime).getTime()); + logger.info("Profile purge: purge executed in {} ms", System.currentTimeMillis() - purgeStartTime); + } catch (Throwable t) { + logger.error("Error while purging profiles", t); } - - logger.info("Profile purge: purge executed in {} ms", System.currentTimeMillis() - t); } }; schedulerService.getScheduleExecutorService().scheduleAtFixedRate(task, 1, purgeProfileInterval, TimeUnit.DAYS); diff --git a/services/src/main/java/org/apache/unomi/services/services/RulesServiceImpl.java b/services/src/main/java/org/apache/unomi/services/services/RulesServiceImpl.java index 36f349b..ca4b139 100644 --- a/services/src/main/java/org/apache/unomi/services/services/RulesServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/services/RulesServiceImpl.java @@ -398,7 +398,11 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn TimerTask task = new TimerTask() { @Override public void run() { - allRules = getAllRules(); + try { + allRules = getAllRules(); + } catch (Throwable t) { + logger.error("Error loading rules from persistence back-end", t); + } } }; schedulerService.getScheduleExecutorService().scheduleWithFixedDelay(task, 0,rulesRefreshInterval, TimeUnit.MILLISECONDS); @@ -406,7 +410,11 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn TimerTask statisticsTask = new TimerTask() { @Override public void run() { - syncRuleStatistics(); + try { + syncRuleStatistics(); + } catch (Throwable t) { + logger.error("Error synching rule statistics between memory and persistence back-end", t); + } } }; schedulerService.getScheduleExecutorService().scheduleWithFixedDelay(statisticsTask, 0, rulesStatisticsRefreshInterval, TimeUnit.MILLISECONDS); diff --git a/services/src/main/java/org/apache/unomi/services/services/SegmentServiceImpl.java b/services/src/main/java/org/apache/unomi/services/services/SegmentServiceImpl.java index c76df29..ec9a14a 100644 --- a/services/src/main/java/org/apache/unomi/services/services/SegmentServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/services/SegmentServiceImpl.java @@ -18,14 +18,20 @@ package org.apache.unomi.services.services; import com.fasterxml.jackson.core.JsonProcessingException; -import org.apache.unomi.api.*; +import org.apache.unomi.api.Event; +import org.apache.unomi.api.Metadata; +import org.apache.unomi.api.PartialList; +import org.apache.unomi.api.Profile; import org.apache.unomi.api.actions.Action; import org.apache.unomi.api.conditions.Condition; import org.apache.unomi.api.conditions.ConditionType; import org.apache.unomi.api.query.Query; import org.apache.unomi.api.rules.Rule; import org.apache.unomi.api.segments.*; -import org.apache.unomi.api.services.*; +import org.apache.unomi.api.services.EventService; +import org.apache.unomi.api.services.RulesService; +import org.apache.unomi.api.services.SchedulerService; +import org.apache.unomi.api.services.SegmentService; import org.apache.unomi.persistence.spi.CustomObjectMapper; import org.apache.unomi.persistence.spi.aggregate.TermsAggregate; import org.osgi.framework.Bundle; @@ -974,16 +980,20 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe TimerTask task = new TimerTask() { @Override public void run() { - for (Metadata metadata : rulesService.getRuleMetadatas()) { - Rule rule = rulesService.getRule(metadata.getId()); - for (Action action : rule.getActions()) { - if (action.getActionTypeId().equals("setEventOccurenceCountAction")) { - Condition pastEventCondition = (Condition) action.getParameterValues().get("pastEventCondition"); - if (pastEventCondition.containsParameter("numberOfDays")) { - updateExistingProfilesForPastEventCondition(rule.getCondition(), pastEventCondition); + try { + for (Metadata metadata : rulesService.getRuleMetadatas()) { + Rule rule = rulesService.getRule(metadata.getId()); + for (Action action : rule.getActions()) { + if (action.getActionTypeId().equals("setEventOccurenceCountAction")) { + Condition pastEventCondition = (Condition) action.getParameterValues().get("pastEventCondition"); + if (pastEventCondition.containsParameter("numberOfDays")) { + updateExistingProfilesForPastEventCondition(rule.getCondition(), pastEventCondition); + } } } } + } catch (Throwable t) { + logger.error("Error while updating profiles for past event conditions", t); } } }; @@ -992,8 +1002,12 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe task = new TimerTask() { @Override public void run() { - allSegments = getAllSegmentDefinitions(); - allScoring = getAllScoringDefinitions(); + try { + allSegments = getAllSegmentDefinitions(); + allScoring = getAllScoringDefinitions(); + } catch (Throwable t) { + logger.error("Error while loading segments and scoring definitions from persistence back-end", t); + } } }; schedulerService.getScheduleExecutorService().scheduleAtFixedRate(task, 0, segmentRefreshInterval, TimeUnit.MILLISECONDS);