#operator-keyword #apama
#оператор-ключевое слово #apama
Вопрос:
Я хотел бы создать простой монитор. Кто прослушивает события во временном окне и выполняет прослушиватель. Но прослушиватель не выполняется. У меня такое чувство, что движок Apama этого не поддерживает.
Из документации: Временные операции являются общим требованием для CEP. Например, мы можем захотеть установить ограничение по времени для наших выражений. Оператор «внутри» указывает время в секундах, в течение которого выражение должно завершиться, начиная с момента первой активации составляющего шаблона. Приведенное ниже выражение завершено, когда мы получаем как MyEvent, так и MyOtherEvent с соответствующими полями в течение 15,0 секунд. Чтобы уточнить, в этом выражении таймер запускается при совпадении либо MyEvent, либо MyOtherEvent:
on all MyEvent(id="important") and MyOtherEvent(id="important") within 15.0
//Eventdefinition
amp;FLUSHING(1)
amp;SETTIME("2019-04-03T14:07:00.0 01:00")
amp;TIME("2019-04-03T14:07:01.0 01:00") // sec 1
TestEvent("START","1")
amp;TIME("2019-04-03T14:07:02.0 01:00") // sec 2
TestEvent("BODY_ID","1")
amp;TIME("2019-04-03T14:07:03.0 01:00") // sec 3
TestEvent("BODY_TYPE","1")
amp;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...
}
Ответ №1:
Почему прослушиватель не запускается
Для справки смотрите: http://www.apamacommunity.com/documents/10.3.0.2/apama_10.3.0.2_webhelp/apama-webhelp/index.html#page/apama-webhelp/ta-DevApaAppInEpl_listening_for_event_patterns_within_a_set_time.html#
При запуске кода создается прослушиватель событий, который пытается сопоставить последовательность событий на основе выбранных вами операторов. Итак
on A() within(10.0) listenerAction();
После того, как коррелятор настроит этот прослушиватель событий, прослушиватель событий
необходимо обнаружить событие A в течение 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
Оператор будет ложным, если любой из операндов примет значение false. Это вызывает удаление прослушивателя событий.
В этом случае within
будет равно false, если время ожидания истекает без получения события. within
На самом деле относится к созданию прослушивателя событий, потому что and
не имеет понятия о порядке или таймингах. Это означает, что оценка возвращается, permanently false
и all
не воссоздает шаблон события, потому что он никогда не будет истинным, как и and
.
Если вы попытаетесь использовать скобки, чтобы принудительно применить ‘внутри’ ко второму событию, будет применен только тот же результат (время ожидания все еще с момента создания прослушивателя).
Если вы удалите 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. Если событие не поступит до истечения таймера, то прослушиватель завершится, как и раньше, но теперь оно не является постоянным false, и поэтому «все» воссоздает прослушиватель событий и ожидает прибытия первого события.
Смотрите это для получения более подробной информации: прослушивание шаблонов событий в течение установленного времени
Альтернатива
Альтернативой было бы использовать потоки, как я упоминал ниже.
Я немного изучил, и это работает, но я не совсем уверен, что это то, что вам нужно. Может быть лучший способ настроить потоки так, чтобы они выполняли то, что вам нужно
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;
}
}
Проверьте разделы здесь, в документах: Потоковая сеть
Комментарии:
1. Привет, спасибо за ваш ответ. Во втором примере с использованием (следующего оператора) это работает. Но только если события происходят в том порядке, в котором они были реализованы. К сожалению, мы не можем предположить, что эти события происходят в том же порядке. Правило также состоит из нескольких событий, у нас есть до четырех событий, которые мы хотели бы просмотреть. Я хотел, чтобы пример был достаточно простым.
2. @Hack я полагаю, вам нужно будет посмотреть на потоки, я смотрю на это сейчас, чтобы понять, что с этим связано.
3. По теме «РЕДАКТИРОВАТЬ 2»: Спасибо за вашу идею. Я попробую это и вернусь к вам!
4. обратите внимание на последнее редактирование этого — я изначально вставил неправильную вещь
5. @Hack просто К ВАШЕМУ сведению, мы рассматривали этот вопрос в офисе, и я добавлю еще одно РЕДАКТИРОВАНИЕ, ответ на самом деле проще, чем потоки в конце — скоро добавим новый ответ.
Ответ №2:
Потоковая передача — волшебное слово:
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;
}
}
спасибо Карибу!