[rules-users] Listening to changes on facts

Davide Sottara dsotty at gmail.com
Thu Oct 11 19:09:38 EDT 2012


/"When a rule is successfully executed. I need to generate an action such as
sending a message to a queue... Can anyone please share a piece of code on
how to listen on changes to facts"
/
Are you interested in rules firing, facts being modified or both? The
problem is that rules could activate and fire WITHOUT modifying any fact at
all :) This said, very generally speaking, there could be several ways to
monitor for WM activity and send messages on a queue as a result...


Rules themselves are some kind of "observers" - they react to changes in the
working memory such as the assertion, retraction or modification of facts.
You can then implement the observation logic with rules:

rule "x" when X( /*filtering conditions here*/ ) then QueueHelper.send(...)
end

QueueHelper here is a class that (statically) exposes the method you need,
but you may use a global, insert it as a fact, etc.... The advantage with
this is that you can "listen" to insertions and modifications, and use
complex selection patterns. 
The problem is that detecting when a RULE has fired (as opposed to when a
fact has been modified) is more complicated: the easiest way would be to
insert temporary facts:

rule "y" when .. then ... insert( new FireEvent( drools.getActivation() ) );
.. end

rule "notifier" when $f: FireEvent(...) then retract($f);
Queuehelper.send(...); end

the notifier rule will activate and react to the insertion of any
"FireEvent" instance (notice: this is a custom class you'd have to create or
declare!). Passing the "activation" as a parameter will carry complete
information about the "source" rule. The disadvantage here is that you will
need to "mix" your business logic with this monitoring logic. A cleaner, but
technically more challenging, approach would be to use the "declarativa
agenda" -- essentially meta-rules. If you are interested, let me know and
I'll provide more details.

A completely different approach would be to use plain java listeners.
KnowledgeSessions fire (java) 
"events" whenever facts are created/modified/etc. and rules
activated/cancelled/fired/etc..:

kSession.addEventListener( new [Debug]AgendaEventListener( ) );
kSession.addEventListener( new [Debug]WorkingMemoryEventListener( ) );

The listeners are actually interfaces, the only default implementation is
the "Debug" which logs the events on the console. The benefit of using
listeners is that you keep the business and the monitoring logic completely
separate. The drawback is that you can't handle complex monitoring logic as
elegantly as you would have done with (meta)rules.

There are other variants and possible solutions, with pros and cons, it
would be helpful if you could provide some additional details on what you're
exactly trying to achieve.

Best
Davide



--
View this message in context: http://drools.46999.n3.nabble.com/Listening-to-changes-on-facts-tp4020231p4020233.html
Sent from the Drools: User forum mailing list archive at Nabble.com.


More information about the rules-users mailing list