Skip to content

Instantly share code, notes, and snippets.

@jlprat
Last active August 29, 2015 13:59
Show Gist options
  • Save jlprat/10449616 to your computer and use it in GitHub Desktop.
Save jlprat/10449616 to your computer and use it in GitHub Desktop.
Gist describing a problem while migrating to Drools 6.0.1 from Drools 5.5.0. The snippets contain the same test situation using drools 5.5.0, then 6.0.1 using fireAllRules, and finally using fireUntilHalt. As we have rules that use timers, and this ones might cause other rules to be triggered, we can't use fireAllRules even if using the TimedRul…
// With Drools 5.5
@Before
public void setupSession() {
final KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption(EventProcessingOption.STREAM);
final KnowledgeBuilder kbuilder = TestHelper.buildRules();
kbase = KnowledgeBaseFactory.newKnowledgeBase(config);
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
ksession = kbase.newStatefulKnowledgeSession();
}
@Test
public void testInvitationsAreSent() {
PartyPreparation partyPreparation = new PartyPreparation(4);
ksession.insert(partyPreparation);
ksession.fireAllRules();
final Collection<Invitation> invitations = getObjectsStream(Invitation.class);
Assert.assertEquals("Invitations to a party should be in the mail stream", 4, invitations.size());
}
private<T extends Object> Collection<T> getObjectsStream(final Class<T> _class) {
return (Collection<T>) ksession.getEntryPoint("mail stream").getObjects(new ObjectFilter() {
@Override
public boolean accept(final Object object) {
return _class.isInstance(object);
}
});
}
private<T extends Object> T retrieveObject(final Class<T> _class) {
Collection<?> objects = ksession.getObjects(new ObjectFilter() {
@Override
public boolean accept(Object o) {
return _class.isInstance(o);
}
});
return objects.size() > 0 ? _class.cast(objects.iterator().next()) : null;
}
@Test
public void partyStartsOnTime() throws InterruptedException {
Party party = new Party(4);
Attendee attendee = new Attendee(1);
ksession.insert(table);
ksession.insert(attendee);
ksession.fireAllRules();
party = retrieveObject(Party.class);
Assert.assertFalse("Party should not be started yet", party.isRunning());
Utils.letSomeMinutesPass(5); //a timer gets triggered behind the scenes and marks the party as running.
party = retrieveObject(Party.class);
Assert.assertTrue("Party should be started", party.isRunning());
DJ dj = retrieveOjbect(DJ.class); //the DJ gets inserted into working memory by a ruled "triggered" by the timer rule
Assert.assertNotNull("If the party started, we need a DJ", dj);
}
//This works fine
//Now let's migrate to Drools 6.0.1 using fireAllRules and TimedRuleExecutionOption
//V1
@Before
public void setupSession() {
//...
final KieSessionConfiguration ksconf = KieServices.Factory.get().newKieSessionConfiguration();
ksconf.setOption( TimedRuleExectionOption.YES );
ksession = kbase.newStatefulKnowledgeSession(ksconf, null);
}
@Test
public void testInvitationsAreSent() {
System.out.println("joining AIS test");
PartyPreparation partyPreparation = new PartyPreparation(4);
ksession.insert(partyPreparation);
ksession.fireAllRules();
final Collection<Invitation> invitations = getObjectsStream(Invitation.class);
Assert.assertEquals("Invitations to a party should be in the mail stream", 4, invitations.size());
}
@Test
public void partyStartsOnTime() throws InterruptedException {
Party party = new Party(4);
ksession.insert(table);
ksession.fireAllRules();
party = retrieveObject(Party.class);
Assert.assertFalse("Party should not be started yet", party.isRunning());
Attendee attendee = new Attendee(1);
ksession.insert(attendee);
ksession.fireAllRules();
party = retrieveObject(Party.class);
Assert.assertFalse("Party should not be started yet", party.isRunning());
Utils.letSomeMinutesPass(5); //a timer gets triggered behind the scenes and marks the party as running.
party = retrieveObject(Party.class);
Assert.assertTrue("Party should be started", party.isRunning());
DJ dj = retrieveOjbect(DJ.class); //the DJ gets inserted into working memory by a ruled "triggered" by the timer rule
Assert.assertNotNull("If the party started, we need a DJ", dj); //<-- This fails!!!! The execution of this rule is delayed until the next fireAllRules
}
//Let's try the variant with fireUntilHalt
@Before
public void setupSession() {
//...
ksession = kbase.newStatefulKnowledgeSession();
final Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("session running");
ksession.fireUntilHalt();
System.out.println("session stopped");
}
};
final Thread thread = new Thread(runnable);
thread.start();
}
@After
public void after() {
ksession.halt();
}
@Test
public void testInvitationsAreSent() {
System.out.println("joining AIS test");
PartyPreparation partyPreparation = new PartyPreparation(4);
ksession.insert(partyPreparation);
final Collection<Invitation> invitations = getObjectsStream(Invitation.class);
Assert.assertEquals("Invitations to a party should be in the mail stream", 4, invitations.size()); // <-- This fails!!! We try to retrieve the objects from memory too early becuase the test doesn't block now. Is there any way to insert an object into the memory, and know when all the rules have been triggered (meaning the planner has no more rules to activate)
}
@Test
public void partyStartsOnTime() throws InterruptedException {
Party party = new Party(4);
ksession.insert(table);
Attendee attendee = new Attendee(1);
ksession.insert(attendee);
party = retrieveObject(Party.class);
Assert.assertFalse("Party should not be started yet", party.isRunning());
Utils.letSomeMinutesPass(5); //a timer gets triggered behind the scenes and marks the party as running.
party = retrieveObject(Party.class);
Assert.assertTrue("Party should be started", party.isRunning());
DJ dj = retrieveOjbect(DJ.class); //the DJ gets inserted into working memory by a ruled "triggered" by the timer rule
Assert.assertNotNull("If the party started, we need a DJ", dj);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment