4

我想建立一个简单的监视器。谁在时间窗口中侦听事件并执行侦听器。但是监听器没有被执行。我感觉 Apama 引擎不支持这一点。

来自文档:临时操作是 CEP 的常见要求。例如,我们可能想对我们的表达设置时间限制。within 运算符指定表达式必须完成的时间(以秒为单位),从第一次激活组成模板时开始。当我们在 15.0 秒内同时收到带有相应字段的 MyEvent 和 MyOtherEvent 时,下面的表达式就完成了。为了澄清,在这个表达式中,计时器在 MyEvent 或 MyOtherEvent 匹配时启动:

on all MyEvent(id="important") and MyOtherEvent(id="important") within 15.0
//Eventdefinition
&FLUSHING(1)
&SETTIME("2019-04-03T14:07:00.0+01:00")

&TIME("2019-04-03T14:07:01.0+01:00") // sec 1
TestEvent("START","1")

&TIME("2019-04-03T14:07:02.0+01:00") // sec 2
TestEvent("BODY_ID","1") 

&TIME("2019-04-03T14:07:03.0+01:00") // sec 3
TestEvent("BODY_TYPE","1") 

&TIME("2019-04-03T14:07:20.0+01:00") // sec 4
TestEvent("BODY_MODELL","1") 

//EPL monitor Rule
on all TestEvent(tag= "BODY_ID") as test
  and TestEvent(tag = "START") as test1 within(5.0)
  {
    log "test" + test.tag at INFO; //never called!
  }

- - -编辑 - - -

另一种解决方案是这个,但不漂亮!而且您无法访问事件的详细信息。

on all (
    TestEvent(tag = "START") as e1
    or TestEvent(tag= "BODY_ID") as e2
    or TestEvent(tag= "BODY_TYPE") as e3
    or TestEvent(tag= "BODY_MODELL") as e4
) -> (//followd by random tag
   TestEvent(tag = "START")
    or TestEvent(tag = "BODY_ID")
    or TestEvent(tag = "BODY_TYPE")
    or TestEvent(tag = "BODY_MODELL")
) within(3.0) -> (//followd by random tag
   TestEvent(tag = "START")
    or TestEvent(tag = "BODY_ID")
    or TestEvent(tag = "BODY_TYPE")
    or TestEvent(tag = "BODY_MODELL")
) within(3.0) -> (//followd by random tag
   TestEvent(tag = "START")
    or TestEvent(tag = "BODY_ID")
    or TestEvent(tag = "BODY_TYPE")
    or TestEvent(tag = "BODY_MODELL")
) within(3.0) {
   //Problem: No e1, e2,e3,e4 are not accessible...
}
4

2 回答 2

2

为什么监听器不触发


参考见: http: //www.apamacommunity.com/documents/10.3.0.2/apama_10.3.0.2_webhelp/apama-webhelp/index.html#page/apama-webhelp%2Fta-DevApaAppInEpl_listening_for_event_patterns_within_a_set_time.html%23

当您运行代码时,将创建一个事件侦听器,该侦听器尝试根据您选择的运算符匹配事件序列。所以

on A() within(10.0) listenerAction();

相关器设置此事件侦听器后,事件侦听器必须在 10 秒内检测到 A 事件。如果在 10 秒内没有检测到 A 事件,则事件表达式永久为假,并且相关器随后终止事件侦听器。

用你的表达方式,“内部”基本上表现如上。

on all TestEvent(tag= "BODY_ID") as test
  and TestEvent(tag = "START") as test1 within(5.0) 
{
  log "test" + test.tag at INFO; //never called!
}

如果任一操作数的计算结果为假,则该and运算符将为假。这会触发事件侦听器的删除。

在这种情况下,within如果超时到期而没有收到事件,则将为 false。这within实际上是参考事件侦听器的创建,因为and它没有顺序或时间的概念。这意味着评估返回permanently false并且all不会重新创建事件模板,因为它永远不会为真,and.

如果您尝试使用方括号强制将“内部”应用于第二个事件,则仅适用相同的结果(超时仍来自侦听器创建)。

如果您删除within并忽略计时,则按and预期工作,任一顺序都会触发事件主体。但是,如果您有一系列事件,例如:

一个

一个

由于事件侦听器的行为方式,您将触发主体两次,A+B 和 B+A。

解决方案


实现您想要的最简单的方法是使用“跟随”运算符和内部。因为您想以任一顺序接收事件,我们需要使用or运算符并使用within.

on all ( ( TestEvent(tag= "BODY_ID") as test
          -> TestEvent(tag = "START") as test1 within(5.0)) 
or 
       ( TestEvent(tag= "START") as test
          -> TestEvent(tag = "BODY_ID") as test1 within(5.0)) )
{
  log "test" + test.tag at INFO; //never called!
}

当您创建事件侦听器时,它不会在“->”的右侧评估(启动计时器),直到收到 START 或 BODY_ID。如果在计时器到期之前没有事件进入,那么侦听器将像以前一样终止,但它现在不是永久错误的,因此“all”重新创建事件侦听器并等待第一个事件到达。

有关更多详细信息,请参阅此内容:在设定的时间内侦听事件模式

选择


另一种方法是使用我下面提到的流。

我已经研究了一下,这很有效,但我不完全确定这是否是你需要的。可能有更好的方法来设置流,以便它们执行您需要的操作

    from t1 in all TestEvent () select t1.tag as tag1 
    from t2 in all TestEvent () 
         within (5.0) select t2.tag as tag2 {
    if( ( tag1 = "BODY_ID" and tag2 = "START" ) or 
        ( tag1 = "START" and tag2 = "BODY_ID" ) ) {
            log "t1 " + tag1 + " t2 " + tag2  at INFO;
        }
    }

在文档中查看此处的部分:流网络

于 2019-04-04T11:07:23.287 回答
1

流媒体是一个神奇的词:

from t1 in all TestEvent () select t1.tag as tag1 
from t2 in all TestEvent () 
     within (5.0) select t2.tag as tag2 {
if( ( tag1 = "BODY_ID" and tag2 = "START" ) or 
    ( tag1 = "START" and tag2 = "BODY_ID" ) ) {
        log "t1 " + tag1 + " t2 " + tag2  at INFO;
    }
}

谢谢驯鹿!

于 2019-04-08T06:27:34.150 回答