1

We have a scenario where facts need to be processed in insertion sequence or as per date associated with the fact. To be precise, I need to add the transactions till the sum reaches a threshold. The moment the threshold is reached, I need to ignore rest of the transactions. Hence the order of transactions by time is important. Here is the sample code that I am working with:

declare HasTransactionDetails
    @role(event)
    @expires(1d)
    @timestamp (txnDate)
end

dialect "mvel" 

rule "Max per day"
    agenda-group "evaluate"
    no-loop true
    lock-on-active true
    when
        tp : TransactionProfile(maxAmount != null,
                maxAmountPeriod.value == "Day")
        tr : HasTransactionDetails() from entry-point "transactionEntry"
        helper : ProfileTransactionMatchHelper(profileId == tp.id, txnId == tr.txnId)
then
...
...

And the way I invoke it:

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
KieBaseConfiguration kieConfiguration = KieServices.Factory.get().newKieBaseConfiguration();
kieConfiguration.setOption(EventProcessingOption.STREAM);
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KnowledgeBase kieBase = KnowledgeBaseFactory.newKnowledgeBase(kieConfiguration);

kieBase.addKnowledgePackages(kbuilder.getKnowledgePackages());
KieSessionConfiguration sessionConfiguration = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
sessionConfiguration.setOption(ClockTypeOption.get("realtime"));

KieSession session = kContainer.newKieSession("TransactionSession", sessionConfiguration);
EntryPoint entry = session.getEntryPoint("transactionEntry");
for (Object fact : facts) {
  if (fact instanceof HasTransactionDetails) {
    entry.insert(fact);
  }
  session.insert(fact);
}
  session.fireAllRules();

So, I have set the mode to STREAM, defined a stream 'transactionEntry', added all transaction facts to this stream and rest of the facts to session, marked the timestamp on the transaction fact, and fired rules in the end. My expectation was that all the transaction facts would be processed in the order of the 'txnDate' specified on the transaction fact but the order is always random.

I did read this example where to ensure facts are processed in order, rules were being fired after adding a fact in session and this was done for each fact. This did not make sense to me. Can someone please guide me if my expectation was wrong or any step I missed?

1 Answers1

0

Call fireAllRules after each insertion (of a HasTransactionDetails object)

for (Object fact : facts) {
  if (fact instanceof HasTransactionDetails) {
    entry.insert(fact);
    session.fireAllRules();   // here or ...
  } else {
    session.insert(fact);
  }
  session.fireAllRules();     // here
}
laune
  • 31,114
  • 3
  • 29
  • 42
  • If i have to fire rules after every fact insertion, I can do the same in Cloud mode itself right? How do I leverage the temporal functionalities of Drools through Stream mode? – Tushar Bhasme Apr 28 '17 at 16:23
  • Temporal operators are just comparison operators with syntactic sugar. – laune Apr 28 '17 at 18:27
  • Alternatives to my proposed solution are conceivable, although they might require a little more effort. One would need to know much more about the scenarios in order to recommend s.th. else. – laune Apr 28 '17 at 18:29
  • Updated my question with precise requirement. – Tushar Bhasme May 03 '17 at 16:57