I try to stop a clips run "stucked" in a loop. But every instruction send to clips make the JVM crash. Is there a way to stop clips when it is running ?
For example the following java code :
finalEnvironmentclips=newEnvironment();clips.load("./src/test/resources/boucle.clp");finalExecutorServiceexecutors=Executors.newFixedThreadPool(1);finalFuture<?>task=executors.submit(newRunnable(){@Overridepublicvoidrun(){System.out.println("**********************************************************");System.out.println("THREAD : clips running");System.out.println("**********************************************************");clips.run();}});Thread.sleep(1000);System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");System.out.println("MAIN THREAD : clips running");System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");//clips.eval("(halt)");//do nothing or make the JVM crash because clips is in a while infinite loopclips.destroy();//JVM crash hereSystem.out.println("clips destroyed");
The HaltRules flag stops execution after the currently executing rule has finished firing, so it won't stop a loop in the right hand side of a rule. Also, CLIPS is not reentrant for a single environment, so you can't execute a run command on one thread for a single environment and an eval on another thread for that same environment. Calling setHaltExecution is just invoking a single line of code on the CLIPS side to set a boolean flag. Calling eval invokes hundreds/thousands of lines of code that could alter data structures being used by another thread of execution for that environment.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Calling setHaltExecution terminates the execution of rules regardless of whether the rule is stuck in RHS loop. Calling setHaltRules terminates the execution of rules after the currently executing rule finishes RHS actions (so it will not terminate if the RHS is stuck in a loop).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The problem described above seems to apply once again to clips_jni_641.
It now seems to be trying to delete non-existent routers when destroying.
With the Java and Clips code above, using 6.4.1 I get an exception:
java.lang.IllegalArgumentException: Router named 'BaseRouter0' does not exist.
at net.sf.clipsrules.jni.Environment.deleteRouter(Environment.java:857)
at net.sf.clipsrules.jni.Environment.destroy(Environment.java:1821)
at net.sf.clipsrules.jni.test.LoadClipsTest.destroyRunningEnvironment(LoadClipsTest.java:451)
Should I catch and ignore this exception in the case of an abrupt destroy?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I checked in a fix to the svn repository. There's a router that get created when commands are executed to capture any error output. It wasn't getting removed from a HashMap that kept track of existing routers. The change was made in Environment.java to the method deleteRouter.
publicvoiddeleteRouter(RoutertheRouter){
if(theRouter==null){thrownewNullPointerException("theRouter"); }if(deleteRouter(theEnvironment,theRouter.getName())){routerMap.remove(theRouter.getName()); } ;; <-- Changeelse{thrownewIllegalArgumentException("Router named '"+theRouter.getName()+"' does not exist."); }}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I try to stop a clips run "stucked" in a loop. But every instruction send to clips make the JVM crash. Is there a way to stop clips when it is running ?
For example the following java code :
withe the following clips code for "boucle.clp"
make the jvm crash when the instruction "destroy" is send
Last edit: Chaubert Jérôme 2017-04-03
Add this to net_sf_clipsrules_jni_Environment.h:
Add this to net_sf_clipsrules_jni_Environment.c:
Add this to Environment.java:
You can then destroy the CLIPS environment with this:
Ok thanks, I will try that.
But, just to know, is that really different from calling
before clips.destroy() ? (I already try that)
In other words : will the "HaltRules" flag be checked when clips is in a "loop" in a right hand side of a rule or only "between" two fires ?
Last edit: Chaubert Jérôme 2017-04-05
The HaltRules flag stops execution after the currently executing rule has finished firing, so it won't stop a loop in the right hand side of a rule. Also, CLIPS is not reentrant for a single environment, so you can't execute a run command on one thread for a single environment and an eval on another thread for that same environment. Calling setHaltExecution is just invoking a single line of code on the CLIPS side to set a boolean flag. Calling eval invokes hundreds/thousands of lines of code that could alter data structures being used by another thread of execution for that environment.
Ok, so your suggestion will work if rules fire indefinitly (and an eval("(halt)" won't work fine because of the possible data structure alteration).
On the other hand, your suggestion will not work if CLIPS is "stucked" in a loop in a right hand side of a rule.
Do you have an idea of a workaround to make it work in both case ? Is it even possible ?
Calling setHaltExecution terminates the execution of rules regardless of whether the rule is stuck in RHS loop. Calling setHaltRules terminates the execution of rules after the currently executing rule finishes RHS actions (so it will not terminate if the RHS is stuck in a loop).
Thanks !
That's perfect.
I will try that as soon as possible and tell you when it is done.
It works fine! Thank you.
Will you integrate these functions in the next version of clips JNI ?
Yes. It was already in the next version I'm working on.
Hi,
The problem described above seems to apply once again to clips_jni_641.
It now seems to be trying to delete non-existent routers when destroying.
With the Java and Clips code above, using 6.4.1 I get an exception:
Should I catch and ignore this exception in the case of an abrupt destroy?
I can reproduce the issue with the code at the beginning of this thread, so I'll take a look and try to figure out what's going on.
I checked in a fix to the svn repository. There's a router that get created when commands are executed to capture any error output. It wasn't getting removed from a HashMap that kept track of existing routers. The change was made in Environment.java to the method deleteRouter.
Thanks for the fast fast correction. It works.
I'm (finally) upgrading to 6.4.1, so I'm sure I'll have more questions and problems. Thanks for your work and help.