[rules-users] agenda-groups

gboro54 gboro54 at gmail.com
Tue May 8 09:09:02 EDT 2012


Here is the code I am using to manage the running session(switched to
fireUntilHalt()). This seems to lockup after sometime. Any thoughts why?



import org.apache.log4j.Logger;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.runtime.ObjectFilter;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.FactHandle;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

/**
 * *Description:* RuleRunner is responsible for managing a drools session
 * running on another thread. The thread will allow insertion of facts and
 * global during it's execution.
 * 
 * @author Michael Weiss
 * 
 */
public class RuleRunner implements Runnable {

	private static final Logger logger = Logger.getLogger(RuleRunner.class);

	private StatefulKnowledgeSession session;

	private WorkingMemoryFileLogger sessionLogger;

	private boolean running;

	private ImmutableList<ObjectFilter> filters;

	private String runningThreadName;

	/**
	 * *Description: * Construct a RuleRunner object with the given drools
	 * stateful session
	 * 
	 * @param session
	 *            - The {@link org.drools.runtime.StatefulKnowledgeSession
	 *            StatefulKnowledgeSession} to be managed by the RuleRunner.
All
	 *            facts will be passed into this session for drools evaluation
	 */
	public RuleRunner(StatefulKnowledgeSession session) {
		this.session = session;
		this.running = false;
	}

	/**
	 * *Description: * Construct a RuleRunner object with the given drools
	 * stateful session
	 * 
	 * @param session
	 *            - The {@link org.drools.runtime.StatefulKnowledgeSession
	 *            StatefulKnowledgeSession} to be managed by the RuleRunner.
All
	 *            facts will be passed into this session for drools evaluation
	 * 
	 * @param filters
	 *            - An immutable list of {@link org.drools.runtime.ObjectFilter
	 *            object filters} which will be used to determine if the
session
	 *            is still processing.
	 * 
	 */
	public RuleRunner(StatefulKnowledgeSession session,
			ImmutableList<ObjectFilter> filters) {
		this.session = session;
		this.filters = filters;
		this.running = false;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		this.runningThreadName = Thread.currentThread().getName();
		if (logger.isDebugEnabled()) {
			logger.debug("Rule Runner has been kicked off on "
					+ this.runningThreadName);
		}
		running = true;
		while (running) {
			session.fireUntilHalt();
		}
		logger.info("Disposing session....");
		session.halt();
		if (sessionLogger != null) {
			sessionLogger.writeToDisk();
			sessionLogger = null;
		}
		this.session.dispose();

	}

	/**
	 * *Description: * Insert's or update's the object based on weather the
	 * object already exists in the currently active drools session.
	 * 
	 * @param fact
	 *            - The object to be inserted or updated.
	 */
	public synchronized void insertOrUpdate(Object fact) {
		insert(fact);
	}

	private synchronized void insert(Object fact) {
		if (!running) {
			logger.warn("Inserting objects into non-running rules session");
		}
		Preconditions.checkNotNull(fact);
		FactHandle factHandle = this.session.getFactHandle(fact);
		if (factHandle == null) {
			this.session.insert(fact);
		} else {
			this.session.update(factHandle, fact);
		}
	}

	/**
	 * *Description: * Add a global object with the given id to the drools
	 * session. It is important to note that globals should not be used for an
	 * object which needs to be evaluation by the drools session each time it
is
	 * modified. A global placed in the drools session will not cause the rule
	 * session to reevaluate. However globals are a great way to keep track of
	 * information that may be needed to be retrieved from the running session.
	 * 
	 * @param identifier
	 *            - The identifier of the global as defined in the rules
	 * @param value
	 *            - The global object
	 */
	public synchronized void addGlobal(String identifier, Object value) {
		if (!running) {
			logger.warn("Inserting objects into non-running rules session");
		}
		this.session.setGlobal(identifier, value);

	}

	/**
	 * *Description: * Shutdown the thread the currently running drools
	 * session. If set to shutdown in safe mode, object filters will be used to
	 * determine if any of the filtered objects exists in the session. If any
do
	 * that the session will stay active until all are removed.
	 * 
	 * @param safeMode
	 *            - Weather the session should wait until all facts are removed
	 *            from the running session(Determined by provided object
	 *            filters)
	 */
	public synchronized boolean shutDown(boolean safeMode) {

		if (logger.isDebugEnabled()) {
			logger.debug("Ending session...");

		}
		if (!safeMode) {
			running = false;
		} else {
			while (!safeToShutDown()) {

			}
			running = false;
		}

		return true;

	}

	/**
	 * *Description: * Log all activity of the running drools session. This
	 * information is written to an XML formated file in the given file
location
	 * and by the file name.***WARNING** Session logging will slow performance
	 * of the rule session.*
	 * 
	 * @param fileLocation
	 *            - The location to output the file to. The location must
exists
	 *            on disk.
	 * @param fileName
	 *            - The name of the file to write to. If the file does not
	 *            exists the file will be created.
	 */
	public synchronized void turnSessionAuditLogOn(String fileLocation,
			String fileName) {
		sessionLogger = new WorkingMemoryFileLogger(this.session);
		if (fileLocation == null || fileLocation.isEmpty()) {
			sessionLogger.setFileName(fileName + this.runningThreadName);
		} else {
			sessionLogger.setFileName(fileLocation + "/" + fileName
					+ this.runningThreadName);
		}

	}

	/**
	 * *Description: * Using the given object filters determine if there
	 * are still objects in the session that we care about before shutting
down;
	 * 
	 * @return boolean - is the session safe to shut down
	 */
	private synchronized boolean safeToShutDown() {
		boolean safeToShutDown = true;

		if (this.filters != null) {
			for (ObjectFilter of : this.filters) {
				if (this.session.getFactHandles(of).size() > 0) {
					safeToShutDown = false;
					break;
				}
			}
		}

		return safeToShutDown;
	}

}





laune wrote
> 
> Periodically calling fireAllRules() in a thread running parallel to the
> one(s)
> doing insertions doesn't make sense to me.
> 
> -W
> 
> On 08/05/2012, gboro54 &lt;gboro54@&gt; wrote:
>> I am not currently using agenda-groups. I believe my issue right now is
>> one
>> of thread safety. A little background: I currently have a thread pulling
>> messages from a database running on the main thread. In several other
>> threads, I have drools session being fired every so often. It appears
>> that
>> there may be a some type of deadlock caused by invoking fireAllRules on
>> one
>> thread, while another is trying to insert. I am working through right now
>> to
>> debug the issue. Has anyone else experienced this issue?
>>
>>
>> Vincent Legendre wrote
>>>
>>>> I am having an issue where I have a catch all
>>>> retraction rule setup as the lowest salience.
>>>
>>> Not sure to understand that (note that I am not english native ...)
>>>
>>>> I see activations created for the facts but they are never fired.  Any
>>>> thoughts on why this may happen?
>>>
>>> Send some rules. Activations never fired is just too vague to have a
>>> single answer.
>>> If you use agenda groups, may be that the group is simply not on focus
>>> ...
>>>
>>> Add a first rule that set the focus, or set auto-focus for all your "low
>>> salience" rules, or don't set agenda group for them (their group will be
>>> the MAIN group).
>>>
>>>> The session is run on a separate thread with fireAllRules called every
>>>> 1/2
>>>> second. I have tried syncronizing inserts on the session so that thread
>>>> would not be in the middle of firing when new facts come in but that
>>>> does
>>>> not seem to do anything....
>>>
>>> Why not using fireUntilHalt instead ?
>>> Run your session.fireUntilHalt in a separate thread, and insert things
>>> in
>>> that session.
>>> insert (or update or retract) will wake up the session.
>>>
>>> Of course, one day, you have to call halt() on your session to get out.
>>> _______________________________________________
>>> rules-users mailing list
>>> rules-users at .jboss
>>> https://lists.jboss.org/mailman/listinfo/rules-users
>>>
>>
>>
>> --
>> View this message in context:
>> http://drools.46999.n3.nabble.com/agenda-groups-tp3968541p3971147.html
>> Sent from the Drools: User forum mailing list archive at Nabble.com.
>> _______________________________________________
>> rules-users mailing list
>> rules-users at .jboss
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>
> _______________________________________________
> rules-users mailing list
> rules-users at .jboss
> https://lists.jboss.org/mailman/listinfo/rules-users
> 


--
View this message in context: http://drools.46999.n3.nabble.com/agenda-groups-tp3968541p3971267.html
Sent from the Drools: User forum mailing list archive at Nabble.com.


More information about the rules-users mailing list