Apama "within" 和 "and" 运算符不执行侦听器?

Apama "within" and "and" operator not execute listener?

我想构建一个简单的监视器。谁在时间 window 中监听事件并执行监听器。但是监听器没有被执行。我感觉 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...
}

为什么监听不触发


参考: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

When you run the code an event listener is created that attempts to match the sequence of events based on the operators you choose. So

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

After the correlator sets up this event listener, the event listener must detect an A event within 10 seconds. If no A event is detected within 10 seconds, the event expression becomes permanently false and the correlator subsequently terminates the event listener.

根据您的表达,'within' 基本上表现如上。

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 将为假。 within 实际上是参考事件监听器的创建,因为 and 没有顺序或时间的概念。这意味着评估 returns permanently falseall 不会重新创建事件模板,因为它永远不会为真,and 也不会。

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

如果您删除 within 并忽略计时,那么 and 将按您预期的方式工作,任一顺序都会触发事件主体。但是,如果您有一系列事件,则可能会产生副作用,例如:

A

B

A

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

解决方案


实现所需内容的最简单方法是使用 'follows' 运算符和 within。因为您想以任一顺序接收事件,所以我们需要使用 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

流媒体是一个神奇的词:

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

谢谢驯鹿!