On Jan 11, 2008, at 12:30 AM, Barry Flower wrote:


Hi,
I am experiencing a deadlock issue that is more likely the higher the event rate in a real-time application. Does anybody know how to avoid such a deadlock but not miss processing any of the events? I have included the java class and the jess rules as an attachment. Any help regarding tools or methods to capture the internal state of the Jess engine so I can at least determine how the deadlock is occurring would be appreciated.



Hi  Barry,

This was a tricky one; I had to run the code, fiddle a bit, and think for a while until I saw what was going on. After that, I had to think for a minute to decide whether it was a bug in Jess or not. It's definitely not: Jess is doing exactly what you're telling it to do. Chalk this one up to the difficulty of thinking in multiple threads!

First of all, in any Java program you can get a thread dump by typing Control-Break on Windows, or Control-\ on UNIX. The thread dump here tells you that the main thread is sitting in waitForActivations(), waiting for something to do, and your second thread is looping, waiting for the status property to become zero. Since there's a rule that should be making that change, something funny is going on; for some reason, that rule isn't firing.

There's a very subtle clue if you use "watch all". Here's the trace, starting from the second-to-last time rule PROCESS_UPDATES::new_value activates:

==> Activation: PROCESS_UPDATES::new_value :  f-1
<== Activation: MAIN::stop :  f-0,, f-2
 <== Focus MAIN
 ==> Focus PROCESS_UPDATES
FIRE 1 PROCESS_UPDATES::new_value f-1
name = s1, value = 628
==> Activation: MAIN::stop :  f-0,, f-2
<=> f-1 (MAIN::faststream (class <Java-Object:java.lang.Class>) (name "s1") (status 0) (value 628) (OBJECT <Java-Object:FastStream>))
<== Activation: MAIN::stop :  f-0,, f-2
==> Activation: MAIN::stop :  f-0,, f-2
<=> f-1 (MAIN::faststream (class <Java-Object:java.lang.Class>) (name "s1") (status 0) (value 633) (OBJECT <Java-Object:FastStream>))
<== Activation: MAIN::stop :  f-0,, f-2
==> Activation: MAIN::stop :  f-0,, f-2
<=> f-1 (MAIN::faststream (class <Java-Object:java.lang.Class>) (name "s1") (status 1) (value 633) (OBJECT <Java-Object:FastStream>))
==> Activation: PROCESS_UPDATES::new_value :  f-1
<== Activation: MAIN::stop :  f-0,, f-2
 <== Focus PROCESS_UPDATES
 ==> Focus MAIN

Notice that at the top, the rule activates, and this causes MAIN to lose focus, and PROCESS_UPDATES to get the focus. new_value then fires and you see the facts changing as they should. Then you see new_value get activated again, but it doesn't fire. Instead, PROCESS_UPDATES *loses* focus at that point. Weird -- activating the rule is supposed to focus that module, since it's an auto-focus rule.

But wait; PROCESS_UPDATES keeps the focus the whole time until the second-to-last line, then it loses the focus. Activating the rule doesn't cause a "==> Focus PROCESS_UPDATES" message since the module is *already focussed*.

So, this was the mystery: why does this module lose focus at this crucial moment? After looking at the code again, I found out. PROCESS_UPDATES is not losing the focus because at this point PROCESS_UPDATES has an empty agenda; it's losing it because you're calling "return" from new_value. What's happening is that new_value isn't even done firing before your Java loop modifies the Java object again. Jess is processing the working memory changes on your second thread, and so the CPU is tied up, and the main thread hasn't had the chance to finish firing the rule yet. The working memory changes activate the rule again, but then the first activation finishes executing, and does a forcible return, which removes the focus from PROCESS_UPDATES. Therefore that last activation, even though it's on the PROCESS_UPDATES agenda, never fires, since you deliberately moved the focus back to MAIN.

The fix is easy: since the default behavior is for the focus stack to be popped when a module's agenda is empty, you can just remove that "return", and your program works as expected! Explicitly returning from a module is something you do only when you want to prevent other activated rules from firing, and as you can see, it works well in that capacity :)

---------------------------------------------------------
Ernest Friedman-Hill
Informatics & Decision Sciences          Phone: (925) 294-2154
Sandia National Labs                FAX:   (925) 294-2234
PO Box 969, MS 9012                 [EMAIL PROTECTED]
Livermore, CA 94550                 http://www.jessrules.com

--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------

Reply via email to