Drools is reactive by default, what you propose would require to change
the engine's semantics completely - at least for those rules which use
"upon".
In fact, the dual approach - DISABLING reactivity - has been discussed and
has been on the TODO list for a while:
when
SomeEvent()
?SomeFact()
then
...
Notice the ? in front of SomeFact: this would achieve your desired result.
To this date, the closest supported workaround involves the use of queries:
query someFact()
SomeFact()
end
when
SomeEvent()
?someFact()
then ... end
In this case, only SomeEvent can trigger activations with preexisting
SomeFact instances.
But you are right, there are other languages which use the syntax
on ... when/if ... then ... end
and do not exhibit a reactive behaviour unless the optional "on" part is
specified.
I'd wait for others to add their 2 cents to the discussion.
Davide
On 05/26/2013 04:27 AM, Jörg Henne wrote:
Hi all,
after using drools for some time now, I have repeatedly stumbled upon
situations where it would have been useful to be able to tell Drools to fire
a rule only upon the insertion of a particular event, but not other
events/facts on which the rule depends. It might be that I am hopelessly
mis-guided, but I would like to float an idea and see what you think.
To illustrate what I am talking about, please consider the following rules:
------------------------------------------------------------------------------------------------------------
package test
declare SomeEvent
@role(event)
name: String
end
declare SomeFact
@role(fact)
name: String
end
rule "Trigger on some event when there is some fact"
when
e: SomeEvent()
f: SomeFact()
then
System.out.println("=> Got Event '" + e.getName() + "'
and Fact '" +
f.getName() + "'");
end
rule "Discard 'used' events"
salience -99999
when
e: SomeEvent()
then
retract(e);
end
------------------------------------------------------------------------------------------------------------
Now we insert facts and events, for example like this
------------------------------------------------------------------------------------------------------------
rule "Insert fact"
when
then
System.out.println("Inserting initial Fact");
insert(new SomeFact("initial fact"));
end
rule "Insert an event"
timer(int: 5s)
when
then
System.out.println("Inserting initial Event");
insert(new SomeEvent("initial event"));
end
rule "Insert yet another fact"
timer(int: 10s)
when
then
System.out.println("Inserting yet another fact");
insert(new SomeFact("yet another"));
end
rule "Insert yet another event"
timer(int: 10s)
when
then
System.out.println("Inserting yet another event");
insert(new SomeEvent("yet another"));
end
------------------------------------------------------------------------------------------------------------
The result of running those rules is, of course:
------------------------------------------------------------------------------------------------------------
Inserting initial Fact
Inserting initial Event
=> Got Event 'initial event' and Fact 'initial fact'
Inserting yet another fact
=> Got Event 'initial event' and Fact 'yet another'
Inserting yet another event
=> Got Event 'yet another' and Fact 'yet another'
=> Got Event 'yet another' and Fact 'initial fact'
------------------------------------------------------------------------------------------------------------
Please note the output does not match the name of the rule "Trigger on some
event when there is some fact". In fact, this rule fires irrespective of
whether an event is inserted or a fact. But what I really want is, that it
just fires upon the 'arrival' of events. A possible syntax extension whould
be something along the lines of:
------------------------------------------------------------------------------------------------------------
rule "Trigger on some event when there is some fact"
when
upon(e: SomeEvent())
f: SomeFact()
then
System.out.println("=> Got Event '" + e.getName() + "'
and Fact '" +
f.getName() + "'");
end
------------------------------------------------------------------------------------------------------------
The expected output of that would be:
------------------------------------------------------------------------------------------------------------
Inserting initial Fact
Inserting initial Event
=> Got Event 'initial event' and Fact 'initial fact'
Inserting yet another fact
Inserting yet another event
=> Got Event 'yet another' and Fact 'yet another'
=> Got Event 'yet another' and Fact 'initial fact'
------------------------------------------------------------------------------------------------------------
There are work-arounds that let me achieve the desired behaviour, for
example this one:
------------------------------------------------------------------------------------------------------------
rule "Focus on 'process SomeEvent'"
agenda-group "process SomeEvent"
auto-focus
when
e: SomeEvent()
then
// nothing to do but focus the agenda-group
end
rule "Trigger on some event when there is some fact"
agenda-group "process SomeEvent"
when
e: SomeEvent()
f: SomeFact()
then
System.out.println("=> Got Event '" + e.getName() + "'
and Fact '" +
f.getName() + "'");
end
------------------------------------------------------------------------------------------------------------
However, I think the hypothetical 'upon'-keyword would be a lot clearer. Is
there any fundamental reason (e.g. rooted in the rete-algorithm or the way
Drools implements it) that would preclude the implementation of 'upon'? And,
more importantly, do you even agree with me that it would be a useful
extension?
Please note that while I always spoke of events in conjunction with 'upon' I
don't see a reason why it should not behave this way with plain facts as
well. Please not as well that the inverse of upon would also be conceivable:
"don't fire this rule just because <some pattern> triggered", e.g.
maybe
simply "not(upon(Pattern()))".
Thanks
Joerg Henne
--
View this message in context:
http://drools.46999.n3.nabble.com/Fire-rule-only-upon-change-of-particula...
Sent from the Drools: User forum mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users