当前位置: 首页 > 知识库问答 >
问题:

事件处理

彭弘伟
2023-03-14

我不喜欢流口水。我正在尝试使用Drools Fusion编写一个简单的复杂事件处理(CEP)应用程序。

我的要求是

  - on receipt of a CRITICAL event, perform an action (right now that's a SOP)
  - if another CRITICAL event arrives within 5 minutes of the previous event 
    and from the same source, ignore it

我有一个简单的Event类,如下所示:

public class Event {

    private String id;
    private Date timestamp;
    private String source;
    private Event.Severity severity;
    private String description;

 /// With Getter and Setter ///

}

规则文件如下:

declare Event
 @role(event)  
 end
 rule "Alert for CRITICAL events. Don't alert for the next 5 minutes if
 from the same source"
 when
        $ev1: Event($source: source, severity == Event.Severity.CRITICAL) 
              from entry-point "events"
        not (
              Event(this != $ev1, source == $source, 
              severity == Event.Severity.CRITICAL,
              this before [1ms, 5m] $ev1) from entry-point "events"
              )
 then
        System.err.println("###### CRITICAL alert caused by event: " 
                            + $ev1.getId()); 
 end

为了进行测试,我将向工作内存中注入4个事件,分别是e1、e2、e3、e4,时间线分别为0m、4m、10m、12m。

Jave类文件

Event event1 = new Event("e1", new Date(), "server1",
        Event.Severity.CRITICAL, "server down");

//calendar.add(Calendar.MINUTE, 4);
Event event2 = new Event("e2", new Date(), "server1",
        Event.Severity.CRITICAL, "server down");

//calendar.add(Calendar.MINUTE, 6);
Event event3 = new Event("e3", new Date(), "server1",
        Event.Severity.CRITICAL, "server down");

//calendar.add(Calendar.MINUTE, 2);
Event event4 = new Event("e4", new Date(), "server1",
        Event.Severity.CRITICAL, "server down");

eventsEP.insert(event1);
clock.advanceTime(4, TimeUnit.MINUTES);
eventsEP.insert(event2);
clock.advanceTime(6, TimeUnit.MINUTES);
eventsEP.insert(event3);
clock.advanceTime(2, TimeUnit.MINUTES);
eventsEP.insert(event4);

ksession.fireAllRules();

我希望e1通过规则,因为它没有前面的事件。我还预计e3将通过,因为前面的比赛还有6分钟。

但是,我得到了不同的输出:

预期输出

  • 事件引起的严重警报:e1

但是我正在得到

  • 事件引起的严重警报:e1
  • 事件引起的严重警报:e2
  • 事件导致的严重警报:e3

附加信息:我正在使用流模式进行事件处理。谁能解释一下输出,告诉我哪里错了。谢谢

共有2个答案

孟正志
2023-03-14

使用您提供的代码,我得到了预期的输出:


Drools版本:5.5.0-final

倪德业
2023-03-14

我相信您确实这样做了,但只是想检查您是否显式地将时钟类型设置为伪时钟,而不是默认的实时时钟:

KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
config.setOption( ClockTypeOption.get("pseudo") );

在多次调用advanceTime()之后只调用fireAllRules()一次也可能存在问题。您可能希望在单独的线程中运行fireUntilHalt(),或者在每次调用advanceTime()后调用fireAllRules()。查看此链接:

Drools融合样本

 类似资料:
  • 我们需要在constructor中对于事件与对应的handler函数进行绑定. 大多数时候我们在发出DOM事件的组件内部写我们的handler函数. 在下面的例子中,我们在组件内部创建了一个click handler, 因为我们想所有的Swithcer Component当被点击时,做出同样的响应. class Switcher extends React.Component { render

  • 事件处理概述 事件处理是对象化编程的一个很重要的环节,没有了事件处理,程序就会变得很死,缺乏灵活性。事件处理的过程可以这样表示:发生事件 - 启动事件处理程序 - 事件处理程序作出反应。其中,要使事件处理程序能够启动,必须先告诉对象,如果发生了什么事情,要启动什么处理程序,否则这个流程就不能进行下去。事件的处理程序可以是任意 JavaScript 语句,但是我们一般用特定的自定义函数(functi

  • Mpx在事件处理上基于原生小程序,支持原生小程序的全部事件处理技术规范,在此基础上新增了事件处理内联传参的增强机制。 原生小程序事件处理详情请参考这里 增强的内联传参能力对于传递参数的个数和类型没有特殊限制,可以传递各种字面量,可以传递组件数据,甚至可以传递for中的item和index, 当内联事件处理器中需要访问原始事件对象时,可以传递$event特殊关键字作为参数,在事件处理器的对应参数位置

  • Rax 元素的事件处理和 HTML 的 DOM 元素类似,但在语法上有一些区别: 事件采用驼峰式命名。 传入函数作为事件处理器而不是字符串。 例如,在 HTML 中为 DOM 元素绑定事件的写法为: <button onclick="activateLasers()">激活按钮</button> <scripts> var activateLasers = function() { al

  • 事件绑定 通过ev-*属性,可以在dom上绑定事件 例如: <button ev-click={function() { alert('点击了按钮') }}>点击按钮</button> 绑定方法 大多数情况下,事件处理函数都比较复杂,直接写在模板中不太优雅。 一般通过将事件处理传入模板的render方法,来进行绑定 例如: <button ev-click={onClick.bind(self)

  • Nerv 元素的事件处理和 DOM 元素的很相似。但是有一点语法上的不同: Nerv 事件绑定属性的命名采用驼峰式写法,而不是小写。 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法) 例如,传统的 HTML: <button onclick="activateLasers()"> Activate Lasers </button> Nerv 中