Почему слушатель не запускает
Для справки см .: 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 секунд выражение события становится постоянно ложным и
коррелятор впоследствии завершает прослушиватель событий.
С вашим выражением «внутри» ведет себя так же, как и выше.
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
не имеет понятия порядка или времени. Это означает, что оценка возвращает permanently false
, а all
не воссоздает шаблон события, поскольку он никогда не будет истинным и не будет and
.
Если вы попытаетесь использовать квадратные скобки, чтобы заставить 'inside' применить ко второму событию, будет применен только тот же результат (тайм-аут все еще от создания слушателя).
Если вы удалите within
и проигнорируете тайминги, то and
будет работать так, как вы ожидаете, любой ордер вызовет тело события. Тем не менее, есть побочный эффект, который может быть нежелательным, если у вас есть последовательность событий, таких как:
A
B
A
Вы бы дважды вызвали тело, 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;
}
}
Оформление разделов здесь в документах: Потоковая сеть