[rules-users] Sliding window behavior in stream mode and realtime clock

MarcoMojana marco.mojana at exmachina.ch
Wed Dec 7 04:51:20 EST 2011


I have set the session clock type to pseudo, the processing mode is still
stream and I have added the following rule:

rule "SingleEvent" 
	dialect "mvel"
	when
		$e0 : TriggerEvent() over window:time(1h) from entry-point EventStream
	then
		System.err.println("SingleEvent " + $e0);
end

And I have changed the code in the following way:

eventStream.insert(new InhibitEvent(new GregorianCalendar(2011,
Calendar.DECEMBER, 6, 12,  0, 0).getTime()));
eventStream.insert(new TriggerEvent(new GregorianCalendar(2011,
Calendar.DECEMBER, 6, 13,  0, 0).getTime()));
eventStream.insert(new InhibitEvent(new GregorianCalendar(2011,
Calendar.DECEMBER, 6, 14,  0, 0).getTime()));
eventStream.insert(new TriggerEvent(new GregorianCalendar(2011,
Calendar.DECEMBER, 6, 14, 10, 0).getTime()));
EventFactHandle lastEventHandle = (EventFactHandle) eventStream.insert(new
InhibitEvent(new GregorianCalendar(2011, Calendar.DECEMBER, 6, 14, 20,
0).getTime()));

System.err.println("The session clock is set to: " + new
Date(pseudoClock.getCurrentTime()));
ksession.fireAllRules();
System.err.println("The session clock is set to: " + new
Date(pseudoClock.getCurrentTime()));

It prints:

The session clock is set to: Thu Jan 01 01:00:00 CET 1970
SingleEvent TriggerEvent [timestamp=Tue Dec 06 14:10:00 CET 2011]
SingleEvent TriggerEvent [timestamp=Tue Dec 06 13:00:00 CET 2011]
The session clock is set to: Thu Jan 01 01:00:00 CET 1970

This means that, with a pseudo clock, even if you don't update it,
drools will consider also the events happening after it (The events are 
inserted in the entry-point, not as facts). In my opinion this doesn't
make any sense.

Adding others fireAllRules() and clock updates doesn't change the output.
What am I doing wrong?

Now I would like to trigger also the "EventNotInhibited" rule. I have
defined a method that updates the session clock in one big step:

private static void advanceSessionClock(StatefulKnowledgeSession ksession,
long time) {
		
	final SessionPseudoClock pseudoClock = ksession.getSessionClock();
	
	final long advance = time - pseudoClock.getCurrentTime();
	if(advance > 0)
		pseudoClock.advanceTime(advance, TimeUnit.MILLISECONDS);
	ksession.fireAllRules();
	
}

The event insertion is done like this:

lastEventHandle = (EventFactHandle) eventStream.insert(new InhibitEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 12,  0, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());
lastEventHandle = (EventFactHandle) eventStream.insert(new TriggerEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 13,  0, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());
lastEventHandle = (EventFactHandle) eventStream.insert(new InhibitEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 14,  0, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());
lastEventHandle = (EventFactHandle) eventStream.insert(new TriggerEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 14, 10, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());
lastEventHandle = (EventFactHandle) eventStream.insert(new InhibitEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 14, 20, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());

This works as expected, but the rule is triggered after inserting the event
at 13:00:00, so it could also be that drools has already removed the event
at 12:00:00 (the 1h window is strict) and it triggers the event, so I have
modified the timestamps like this:

lastEventHandle = (EventFactHandle) eventStream.insert(new InhibitEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 12, 10, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());
lastEventHandle = (EventFactHandle) eventStream.insert(new TriggerEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 13,  0, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());
lastEventHandle = (EventFactHandle) eventStream.insert(new InhibitEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 13, 50, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());
lastEventHandle = (EventFactHandle) eventStream.insert(new TriggerEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 14,  0, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());
lastEventHandle = (EventFactHandle) eventStream.insert(new InhibitEvent(new
GregorianCalendar(2011, Calendar.DECEMBER, 6, 14, 10, 0).getTime()));
advanceSessionClock(ksession, lastEventHandle.getStartTimestamp());

The rule should still be triggered, for example considering a 1h window
betweeen 12:30:00 and 13:30:00. It is not, even changing the clock
update method as follows:

private static void advanceSessionClock(StatefulKnowledgeSession ksession,
long time) {
	
	final SessionPseudoClock pseudoClock = ksession.getSessionClock();
	
	while(pseudoClock.getCurrentTime() < time) {
		
		pseudoClock.advanceTime(1, TimeUnit.SECONDS);
		ksession.fireAllRules();
		
	}
	ksession.fireAllRules();
	
}

I would like to have a clear and consistent idea of what is happening
and why.

--
MM


--
View this message in context: http://drools.46999.n3.nabble.com/Sliding-window-behavior-in-stream-mode-and-realtime-clock-tp3564950p3566923.html
Sent from the Drools: User forum mailing list archive at Nabble.com.



More information about the rules-users mailing list