Explorar o código

排查触发条件为设备触发触发方式为用量值的规则引擎没有生效的问题

james hai 6 días
pai
achega
73e431e5a3

+ 1 - 1
service-rule/service-rule-biz/src/main/java/com/usky/rule/cache/RuleEngineCache.java

@@ -19,7 +19,7 @@ public class RuleEngineCache {
     )
     public Cache<Long, List<DeviceTrigger>> consumptionTriggerCache() {
         return (new Cache2kBuilder<Long, List<DeviceTrigger>>() {
-        }).name("consumptionTriggerCache").eternal(false).expireAfterWrite(1L, TimeUnit.HOURS).entryCapacity(100000L).build();
+        }).name("consumptionTriggerCache").eternal(true).entryCapacity(100000L).build();
     }
 
     @Bean(

+ 10 - 1
service-rule/service-rule-biz/src/main/java/com/usky/rule/config/CronTaskManager.java

@@ -112,7 +112,16 @@ public class CronTaskManager {
     }
 
     public void performConsumptionTask() {
-        JobDetail consumptionJob = JobBuilder.newJob(ConsumptionJob.class).withIdentity("consumption", "device").build();
+        JobKey consumptionKey = JobKey.jobKey("consumption", "device");
+        try {
+            if (this.scheduler.checkExists(consumptionKey)) {
+                return;
+            }
+        } catch (SchedulerException e) {
+            throw new RuntimeException(e);
+        }
+
+        JobDetail consumptionJob = JobBuilder.newJob(ConsumptionJob.class).withIdentity(consumptionKey).build();
         CronTrigger consumptionTrigger = (CronTrigger)TriggerBuilder.newTrigger().forJob(consumptionJob).withIdentity("consumptionTrigger").withSchedule(CronScheduleBuilder.cronSchedule("0 */5 * * * ?")).build();
 //        JobDetail spaceJob = JobBuilder.newJob(SpaceJob.class).withIdentity("space").build();
 //        CronTrigger spaceTrigger = (CronTrigger)TriggerBuilder.newTrigger().forJob(spaceJob).withIdentity("spaceTrigger", "space").withSchedule(CronScheduleBuilder.cronSchedule("0 0 * * * ?")).build();

+ 24 - 7
service-rule/service-rule-biz/src/main/java/com/usky/rule/crons/TriggerCronTask.java

@@ -59,9 +59,8 @@ public class TriggerCronTask implements ApplicationContextAware, InitializingBea
 
                 this.setDeviceConsumptionCache(ruleEngine.getId(), ruleEngineDetail);
             }
-
-            this.cronTaskManager.performConsumptionTask();
         }
+        this.cronTaskManager.performConsumptionTask();
     }
 
     private void startCronTask() {
@@ -85,13 +84,25 @@ public class TriggerCronTask implements ApplicationContextAware, InitializingBea
 
     }
 
+    /**
+     * 与库里的规则详情对齐能耗类设备触发器。去掉/改掉 consumption 时必须 remove,否则 ConsumptionJob 仍用旧缓存。
+     */
     public void setDeviceConsumptionCache(Long ruleEngineId, RuleEngineDetail ruleEngineDetail) {
+        if (ruleEngineId == null) {
+            return;
+        }
         List<DeviceTrigger> deviceTriggers = this.ruleEngineService.getDeviceTriggers(ruleEngineDetail.getTriggers());
-        if (deviceTriggers != null && !deviceTriggers.isEmpty()) {
-            List<DeviceTrigger> consumptionTrigger = (List)deviceTriggers.stream().filter((deviceTrigger) -> deviceTrigger.getMethod().equals("consumption")).collect(Collectors.toList());
-            if (!consumptionTrigger.isEmpty()) {
-                this.consumptionTriggerCache.put(ruleEngineId, consumptionTrigger);
-            }
+        if (deviceTriggers == null || deviceTriggers.isEmpty()) {
+            this.consumptionTriggerCache.remove(ruleEngineId);
+            return;
+        }
+        List<DeviceTrigger> consumptionTriggers = deviceTriggers.stream()
+                .filter((t) -> "consumption".equals(t.getMethod()))
+                .collect(Collectors.toList());
+        if (consumptionTriggers.isEmpty()) {
+            this.consumptionTriggerCache.remove(ruleEngineId);
+        } else {
+            this.consumptionTriggerCache.put(ruleEngineId, consumptionTriggers);
         }
 
 //        List<SpaceTrigger> spaceTriggers = this.ruleEngineService.getSpaceTriggers(ruleEngineDetail.getTriggers());
@@ -101,6 +112,12 @@ public class TriggerCronTask implements ApplicationContextAware, InitializingBea
 
     }
 
+    public void removeDeviceConsumptionCache(Long ruleEngineId) {
+        if (ruleEngineId != null) {
+            this.consumptionTriggerCache.remove(ruleEngineId);
+        }
+    }
+
     private void processCronTask(Long id, Long projectId, Long spaceId, RuleEngineDetail engineDetail, List<CronTrigger> cronTriggers) {
         List<CronConstraint> cronConstraints = this.ruleEngineService.getCronConstraints(engineDetail.getConstraints());
         List<DeviceConstraint> deviceConstraints = this.ruleEngineService.getDeviceConstraints(engineDetail.getConstraints());

+ 5 - 3
service-rule/service-rule-biz/src/main/java/com/usky/rule/jobs/ConsumptionJob.java

@@ -8,11 +8,10 @@ import com.usky.demo.domain.HistorysInnerRequestVO;
 import com.usky.demo.domain.HistorysInnerResultVO;
 import com.usky.demo.domain.MetricVO;
 import com.usky.rule.domain.RuleEngine;
-import com.usky.rule.vo.Result;
-import com.usky.rule.util.JsonUtil;
 import com.usky.rule.enums.TimeTypeEnum;
 import com.usky.rule.enums.TriggerTypeEnum;
 import com.usky.rule.enums.TriggerValueTypeEnum;
+import com.usky.rule.util.JsonUtil;
 import com.usky.rule.vo.DataPointVO;
 import com.usky.rule.vo.Condition;
 import com.usky.rule.vo.Expression;
@@ -71,8 +70,11 @@ public class ConsumptionJob implements Job {
             log.info("consumptionTriggerCache: {}, now: {}", entry.getKey(), now);
             Long engineId = (Long)entry.getKey();
             RuleEngine ruleEngine = (RuleEngine)this.ruleEngineService.getById(engineId);
+            if (ruleEngine == null || ruleEngine.getStatus() == null || ruleEngine.getStatus() != 1) {
+                continue;
+            }
             Long spaceId = ruleEngine.getSpaceId();
-            RuleEngineDetail ruleEngineDetail = (RuleEngineDetail)JsonUtil.toObject(ruleEngine.getDetail(), RuleEngineDetail.class);
+            RuleEngineDetail ruleEngineDetail = (RuleEngineDetail) JsonUtil.toObject(ruleEngine.getDetail(), RuleEngineDetail.class);
             List<RuleEngineAction> actions = this.ruleEngineService.getActions(ruleEngineDetail.getActions());
             if (!actions.isEmpty()) {
                 RuleEngineDetailLog ruleEngineDetailLog = new RuleEngineDetailLog();

+ 13 - 11
service-rule/service-rule-biz/src/main/java/com/usky/rule/service/impl/RuleEngineDetailServiceImpl.java

@@ -33,20 +33,21 @@ public class RuleEngineDetailServiceImpl implements RuleEngineDetailService {
 
     public Boolean save(RuleEngineDTO dto) {
         if (dto.getStatus() != null && dto.getStatus() == 0) {
+            this.triggerCronTask.removeDeviceConsumptionCache(dto.getId());
             return true;
-        } else if (StringUtils.isBlank(dto.getDetail())) {
+        }
+        if (StringUtils.isBlank(dto.getDetail())) {
+            this.triggerCronTask.removeDeviceConsumptionCache(dto.getId());
             return true;
-        } else {
-            RuleEngineDetail ruleEngineDetail = (RuleEngineDetail)JsonUtil.toObject(dto.getDetail(), RuleEngineDetail.class);
-            List<RuleEngineAction> actions = this.ruleEngineService.getActions(ruleEngineDetail.getActions());
-            if (actions != null && !actions.isEmpty()) {
-                this.triggerCronTask.setDeviceConsumptionCache(dto.getId(), ruleEngineDetail);
-                this.createCronTask(dto, ruleEngineDetail, actions);
-                return true;
-            } else {
-                return true;
-            }
         }
+        RuleEngineDetail ruleEngineDetail = (RuleEngineDetail)JsonUtil.toObject(dto.getDetail(), RuleEngineDetail.class);
+        // 必须先同步缓存:与 actions 是否为空无关,否则仅改触发器/去掉能耗时仍沿用旧 consumption 列表
+        this.triggerCronTask.setDeviceConsumptionCache(dto.getId(), ruleEngineDetail);
+        List<RuleEngineAction> actions = this.ruleEngineService.getActions(ruleEngineDetail.getActions());
+        if (actions != null && !actions.isEmpty()) {
+            this.createCronTask(dto, ruleEngineDetail, actions);
+        }
+        return true;
     }
 
     private void createCronTask(RuleEngineDTO dto, RuleEngineDetail ruleEngineDetail, List<RuleEngineAction> actions) {
@@ -70,6 +71,7 @@ public class RuleEngineDetailServiceImpl implements RuleEngineDetailService {
     public Boolean remove(Long id) {
         Assert.notNull(id, "id不能为空");
         this.historyRecordCache.deleteConditions(id);
+        this.triggerCronTask.removeDeviceConsumptionCache(id);
         return this.cronTaskManager.deleteAllJobsInJobGroup(id);
     }