Apama“within”和“and”运算符不执行监听器?

问题描述 投票:4回答:2

我想构建一个简单的监视器。谁在时间窗口中侦听事件并执行侦听器。但是听众没有被执行。我有一种感觉,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...
}
operator-keyword apama
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!
}

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

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

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

如果你删除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'重新创建事件监听器并等待第一个事件到达。

有关更多详细信息,请参阅此内容:listening for event patterns within a set time

替代


如下所述,替代方案是使用流。

我看了一点,这有效,但我不完全确定这是否是你需要的。可能有更好的方法来设置流,以便它们能够满足您的需求

    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;
        }
    }

查看文档中的各个部分:Stream network


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;
    }
}

谢谢驯鹿!

© www.soinside.com 2019 - 2024. All rights reserved.