You can customize the ruleset cache by writing your own
implementation class and then modifying the deployment descriptor
of the execution unit (XU) accordingly.
Before you begin
For memory information to be available, you must install the Rule Execution Server memory
profiler Java™ Agent.
About this task
The execution unit (XU) uses a cache of ruleset instances
to avoid having to parse rulesets for each execution. Rulesets stay
in memory if at least one connection exists in the JCA connection
pool of the XU that references that ruleset. Even if the JCA connection
is not in use, it references the ruleset until the application server
deletes it. When no JCA connection references the ruleset any more,
the ruleset can be garbage-collected. This default behavior guarantees
that unused rulesets are removed from the memory. If a ruleset is
rarely used compared to another ruleset, reparsing might occur.
The ruleset.cache.maintenance.period property
is set to 300 by default. This value means that the
maintenance thread is run every 5 minutes.
You can write your
own implementation of the ruleset cache by packaging a different implementation
class in the ra.xml XU configuration file.
Procedure
- Write a class that implements the IlrRulesetCache interface.
Your class can define custom properties.
package ilog.rules.res.xu.ruleset.cache.sample;
import java.util.*;
import java.util.logging.*;
import ilog.rules.res.xu.ruleset.*;
public class RulesetCacheImpl implements IlrRulesetCache {
public static final int DEFAULT_MAXIMUM_SIZE = 2;
protected IlrRulesetUsageInformationMonitor monitor;
protected Logger logger;
protected ArrayList<IlrXURuleset> rulesets = new ArrayList<IlrXURuleset>();
/** Maximum number of rulesets that can be stored in the cache */
protected int maxSize = DEFAULT_MAXIMUM_SIZE;
public synchronized void addRuleset(IlrXURuleset ruleset) {
if (rulesets.size() == maxSize) {
logger.info("Max size reached, removing less used ruleset");
removeLessUsedRuleset();
}
rulesets.add(ruleset);
}
/**
* Removes the least executed ruleset.
*/
protected void removeLessUsedRuleset() {
long minExecCount = Long.MAX_VALUE;
IlrXURuleset minExecRuleset = null;
for(IlrXURuleset ruleset: rulesets) {
IlrRulesetUsageInformation info
= monitor.getRulesetUsageInformation(ruleset.getCanonicalRulesetPath());
long execCounter = info.getExecutionCount();
if (execCounter <= minExecCount) {
minExecRuleset = ruleset;
minExecCount = execCounter;
}
}
if (minExecRuleset != null) {
logger.info("Remove ruleset: "+minExecRuleset.getCanonicalRulesetPath());
rulesets.remove(minExecRuleset);
}
}
public synchronized void clear() {
rulesets.clear();
}
public synchronized IlrXURuleset getDeprecatedRuleset(String canonicalRulesetPath,
ClassLoader xomClassLoader) {
return null;
}
public synchronized IlrXURuleset getRuleset(String canonicalRulesetPath,
ClassLoader xomClassLoader) {
for(IlrXURuleset ruleset: rulesets) {
if (ruleset.getCanonicalRulesetPath().equals(canonicalRulesetPath) &&
ruleset.getXOMClassLoader() == xomClassLoader) {
return ruleset;
}
}
return null;
}
public void initialize(Logger logger, Map<String, String> properties,
IlrRulesetUsageInformationMonitor monitor)
throws IlrRulesetCacheException {
this.monitor = monitor;
this.logger = logger;
}
public synchronized void rulesetChanged(String canonicalRulesetPath) {
Iterator<IlrXURuleset> iterator = rulesets.iterator();
while(iterator.hasNext()) {
IlrXURuleset ruleset = iterator.next();
if (ruleset.getCanonicalRulesetPath().equals(canonicalRulesetPath)) {
iterator.remove();
}
}
}
}
- Add the implementation class to the ra.xml XU
deployment descriptor.
- Implement the custom ruleset cache.
<config-property>
<config-property-name>rulesetCacheProperties</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>ruleset.cache.class=mypackage.MyRulesetCache</config-property-value>
</config-property>
- Set a custom cache property.
<config-property>
<config-property-name>rulesetCacheProperties</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>ruleset.cache.class=mypackage.MyRulesetCache,mycustomprop=mycustomvalue/config-property-value>
</config-property>
- Make sure that the rulesetUsageMonitorEnabled property
is set to true, its default value.
<config-property>
<config-property-name>rulesetUsageMonitorEnabled</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
- Package the class.
For a Java SE deployment, you must add the class to
the same class path as the XU or its parent. In Jakarta EE, you must package the class in the XU .rar file.