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-automatically-expiring-from-working-memory-td61127.html).
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 |
|