0

I am trying to test the firing of a rule based on a cron timer using the pseudo clock in Drools Fusion 5.5. I want the rule to fire everyday at 1am:

rule "CALCULATING DATE FOR NEXT DAY"
timer (cron:00 00 01 * * ?)
no-loop
when 
     $summary: FxSummary(sameDayCcyFlag == false)
then
    BusinessDayUtil b = new BusinessDayUtil();
    modify($summary) {  
        setSettlementDate(b);
    }
end

I then do the following in my test case:

PseudoClockScheduler timeService = ( PseudoClockScheduler ) ksession.getSessionClock();
DateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZ" );
Date date = df.parse( "2014-01-16T01:00:00.000-0000" );

Summary sum = new Summary("YEN").setSameDayCcyFlag(false);
ksession.fireAllRules();
timeService.advanceTime( date.getTime(), TimeUnit.MILLISECONDS );
ksession.fireAllRules();

It doesn't seem to do anything...no indication that the timer fired or anything. I've also tried to insert a date at say 12:59:50 and advanced the clock 10sec. Also, fireUntilHalt to have the engine running, etc. Nothing seems to work. Am I using this correctly? Does the pseudo clock work with timers? Also, does it fire "missed" timers if I advance the clock past a timer that was supposed to fire?

Odi
  • 6,916
  • 3
  • 34
  • 52
i850eggs
  • 55
  • 6

1 Answers1

3

Think about how cron can be implemented. The basic function is timer, and this works like ye olde kitchen's egg-timer: at one point in time you wind it up, and then it'll ring 4 or 5 minutes later. Thus, for the next cron ring of the bell, the Cook will have to look at the clock and calculate the interval to the indicated point in time.

You'll have to let the Cook look at the clock some time before the next 1:00am, say, around midnight. The code goes something like this, with advance() overloaded with Date and long to advance the pseudo-clock:

    date = df.parse( "2014-01-15T00:00:00.000-0000" ); // Note: midnight
    advance( date );
    kSession.fireAllRules();  // (Ah, ring in one hour!)

    advance( 1000*60*60 );
    kSession.fireAllRules();  // Ring!

    advance( 24*1000*60*60 );
    kSession.fireAllRules();  // Ring!

The postman only rings twice ;-)

laune
  • 31,114
  • 3
  • 29
  • 42
  • Don't think this was exactly my issue, but it did get me on the right path! It seems for me the initial advance(date) doesn't really do anything...I can pass basically anything to it and it doesn't seems to advance. However, after on the second advance(), it then "kicks in" so to speak and works correctly. Thank you! – i850eggs Jan 17 '14 at 00:07
  • @i850eggs The clock is advanced due to the advance calls, but someone has to look at it. - The code sequence I posted is tested and works as described in the comments. – laune Jan 17 '14 at 09:19