Timer in Drools Fusion not working

995 Views Asked by At

I am trying to run following rules in Drool Fusion( Version 5.4.1 ), but it's not working.

Ideally it should print "HELLO WORLD" every 7 seconds, it's not even triggering once.

Can anybody please help me to understand the timer in Drools?

     import com.drools.message.Message

rule "Test" 
    timer(int: 7s 7s)
when
    message:Message (type=="Hello")
then
    System.out.println("Hello World, Drools! " + message.getMsgtext());
end
   My code to run the above Rule is:
public class TestDrools {

  private static String DRL_FILE = "test_drools.drl";
  private static KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
          .newKnowledgeBuilder();
  private static Collection pkgs;
  private static KnowledgeBase kbase = KnowledgeBaseFactory
          .newKnowledgeBase();
  private static StatefulKnowledgeSession ksession;

  private static WorkingMemoryEntryPoint entryPoint;

  public static void main(String[] args) {
      init();
      while (true) {
          Message msg = new Message();
          msg.setType("Hello");
          msg.setMsgtext("1");
          ksession.insert(msg);
      }
  }

  private static void init() {
      initialiseDrools();
  }

  private static void initialiseDrools() {
      kbuilder.add(ResourceFactory.newClassPathResource(DRL_FILE),
              ResourceType.DRL);
      if (kbuilder.hasErrors()) {
          System.out.println(kbuilder.getErrors().toString());
          throw new RuntimeException("Unable to compile drl\".");
      }
      pkgs = kbuilder.getKnowledgePackages();
      KnowledgeBaseConfiguration config = KnowledgeBaseFactory
              .newKnowledgeBaseConfiguration();
      config.setOption(EventProcessingOption.STREAM);
      kbase = KnowledgeBaseFactory.newKnowledgeBase(config);
      kbase.addKnowledgePackages(pkgs);
      KnowledgeSessionConfiguration conf = KnowledgeBaseFactory
              .newKnowledgeSessionConfiguration();
      conf.setOption(ClockTypeOption.get("pseudo"));
      ksession = kbase.newStatefulKnowledgeSession(conf, null);
      entryPoint = ksession.getWorkingMemoryEntryPoint("entryone");
      new Thread() {
          @Override
          public void run() {
              ksession.fireUntilHalt();
          }
      }.start();
  }
}

Thank you -Sanjay

2

There are 2 best solutions below

3
On

then condition happens when when condition fulfills,so you need to at least put eval(true) in when condition and trigger an insert into knowledgeSession so that the rule engine figure out what to do when some condition fulfills.

1
On

As per @laune's comment, you've used the pseudo clock. If you want to use the realtime clock, change the following line:

  conf.setOption(ClockTypeOption.get("realtime"));

Or just remove the line altogether - realtime is the default clock.

If you want to use the pseudo clock, you'll need to advance it yourself. This is typically use in unit testing, e.g.

  SessionPseudoClock  clock = ksession.getSessionClock();
  // insert some facts ... 
  clock.advanceTime(1, TimeUnit.HOURS);
  ksession().fireAllRules();

  // Do your unit test asserts / verify mocks here to verify that 
  // time-reasoned rules were / weren't fired