Hi!
I've detected some problems in my rules regarding event expiration but I can't
understand why. Maybe someone with more experience could help me out.
I think the example is quite simple: the application receives transactions. The lack of
transactions for an hour should raise an alarm. If there's a transaction when the
alarm is on, then the application should rearm, clear the alarm state and check for lack
of transactions.
The rules:
package com.company.application;
import com.company.application.Notifier;
import com.company.application.Notification;
import com.company.application.Transaction;
dialect "java"
# event which represents an alarm state
declare NoTransactions
@role( event )
dummy1: long
end
# event which represents the start of drools engine
declare EngineStarted
@role( event )
dummy2 : long
end
# event which represents the need to check for absence of transactions for the first hour
declare CheckFirstTransaction
@role( event )
@expire( 1h )
dummy3: long
end
# event which represents a Transaction
declare Transaction
@role( event )
@expires( 1h )
end
# Notification System
global Notifier notifier;
rule "***start***"
when
not( EngineStarted() )
then
insert( new EngineStarted() );
insert( new CheckFirstTransaction() );
end
rule "***notrx_after_start***"
when
$engineStarted : EngineStarted()
$checkFirstTransaction : CheckFirstTransaction()
not( NoTransactions() )
not( Transaction( this after[0s,1h] $engineStarted ) from entry-point
"incoming" )
then
insert ( new NoTransactions() );
retract( $checkFirstTransaction );
notifier.send( new Notification( "ALARM" ) );
end
rule "***notrx_after_trx***"
when
EngineStarted()
not( NoTransactions() )
$transaction: Transaction() from entry-point "incoming"
not( Transaction( this != $transaction, this after [0s,1h] $transaction ) from
entry-point "incoming" )
then
insert( new NoTransactions());
notifier.send( new Notification( "ALARM" ) );
end
rule "***rearm***"
when
EngineStarted()
$noTransactions : NoTransactions()
$transaction: Transaction( this after $noTransactions ) from entry-point
"incoming"
then
retract( $noTransactions );
notifier.send( new Notification( "REARM" ) );
end
The unit test:
kSession.fireAllRules(); // needed to detect lack of transactions in the first hour
/* here, "***start***" rule fires => "EngineStarted" and
"CheckFirstTransaction" inserted */
clock.advanceTime( 1, TimeUnit.HOURS );
/* here, "***notrx_after_start***" rule fires => "NoTransactions"
inserted, "CheckFirstTransaction" retracted */
clock.advanceTime(10, TimeUnit.MINUTES );
entryPoint.insert( new Transaction() );
/* before inserting "Transaction" into EntryPoint, "NoTransactions" is
retracted */
kSession.fireAllRules();
The problem:
After inserting the last transaction, automatically the NoTransactions event is retracted.
Debugging inside drools-core project, I've discovered that the event was retracted
because expiration (WorkingMemoryReteExpireAction on actionQueue).
I've also found some more explain how expiration events works, by Edison
(
http://drools-java-rules-engine.46999.n3.nabble.com/Events-are-not-automa...).
That shed some light on *when* the event is retracted but I don't understand *why*
it's retracted.
Thanks In Advance!
Vítor Mendonça Moreira
Analista / Programador
Direcção de Investigação e Desenvolvimento
Rua Dr. Francisco Sá Carneiro, nº. 4 r/c esq.
2500 - 206 - Caldas da Rainha
Tel: (+351) 262 832 196
Fax: (+351) 262 186 455
Web:
www.makewise.pt <
http://www.makewise.pt>
Uma empresa: Grupo Sousa Pedro <
http://www.sousapedro.com>