Each rule session is associated with an execution unit
(XU) connection. You can configure ruleset execution to share server
resources by setting up connection pools. The number of concurrent
connections in a pool affects performance.
Connection pooling is a technique for sharing server resources
among requesting clients. When you set up connection pools, consider
performance aspects: changes in the way in which resources are shared
can affect the performance of your application or application server.
Rule sessions and XU connections
Each
rule session is associated with an execution unit (XU) connection.
The
maximum number of concurrent rule sessions depends directly on how
the XU connection pool is set up.
- In Java™ SE rule sessions,
the connection pool is implemented by the XU and you can tune it in
the ra.xml deployment descriptor.
- In Java EE rule sessions,
the connection pool is provided by the application server. You can
use the administration facilities of the application server to tune
the JCA connection pool that corresponds to the XU.
Connection pool configuration
Connection
pools are configured differently depending on whether you deploy on Java EE or Java SE.
- In Java EE, the Rule Execution Server execution
stack takes advantage of the pooling services of the application server.
You set the pooling parameters on the server side according to the
application requirements and specific characteristics. These parameters
rely on the related Java EE
services.
- In Java SE, Decision Server handles
connection pooling. The execution unit (XU) JAR file includes a Java EE Connector Architecture (JCA)
container, which creates and pools connections to the XU. Each Java SE factory that you create
generates one XU and, therefore, one engine pool. The XU contains
a default pool implementation. To replace or modify it, provide any
class that implements the IlrPool interface.
The pool configuration is stored in the deployment descriptor META-INF/ra.xml file
of the resource adapter. To configure Java SE
pools, use the defaultConnectionManagerProperties property.
You
can modify the pool implementation class and the pool initialization
by setting the following properties in the
META-INF/ra.xml file:
- To change the name of the pool implementation class, use the pool.class property.
- To change a set of key-value properties to initialize the pool,
use the pool.maxSize property.
A call to the method IlrPool.initialize sends
all the properties that are defined in defaultConnectionManagerProperties to
the pool instance.
A Connection object
represents a connection with a ruleset. A single application can have
one or more connections to a single ruleset, or connections to many
different rulesets.
Restriction: The default implementation
sets the maximum number of connections in a pool to 10. You cannot
change that number after the pool is started.
Connection pools are managed as follows:
- When the pool is created, it is empty.
- When the pool is full, the oldest connection is replaced by the
new connection.
- The pool never garbage-collects the released connections.
- A failed connection is always removed from the pool.
Connection pools and performance
One
way to increase the throughput consists in increasing the number of
concurrent connections in a pool. From the performance point of view,
execution is more efficient when each ruleset has its own XU pool.
However, the choice of multiple pools has a memory cost.
- Benefit
- When dedicated engine pools are created for different rulesets,
some rulesets are kept available for longer. Therefore, they do not
have to be parsed again if they are used more often than others. The
rulesets that are used less often can be removed from the pool and
garbage-collected.
- Drawback
- Multiple pools increase the memory consumption. When you set up
the size of your pools, make sure that the application server can
take this additional load. To do so, check that the application server
has the required memory to host the pools at their maximum capacity.
As a consequence, before you configure engine
pools, examine against your requirements whether the choice of one
XU pool for each ruleset is necessary. It is efficient to configure
one pool per ruleset when a pool contains rulesets that are not used
equally. Such a configuration becomes even more relevant when the
parsing time is long and the response time is critical. In this case,
you must tune the pool to ensure that an engine is always ready to
execute a parsed ruleset. The performance remains tied to your server
capacity in processor and memory but when the response time is critical,
dedicated pools can help. If you choose to have a pool for each ruleset,
ensure that you always create rule sessions for the same ruleset in
each factory. To this end, pass the ruleset path when the rule session
is created, not when the factory is created.
BOM to XOM conversion
The conversion of
XOM objects to BOM strings and, conversely, of BOM strings to XOM
objects uses DocumentBuilder and Transformer instances.
As the creation of these objects has a significant cost, the XU uses
two dedicated object pools. You can change the settings of these object
pools by setting the XU configuration properties documentBuilderPoolProperties and transformerPoolProperties in
the JCA descriptor file ra.xml of the execution
unit.
Both properties support the following string parameters:
Separate the two parameters with a comma, as in the following
example.
<config-property>
<config-property-name>documentBuilderPoolProperties</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>pool.maxSize=20,pool.waitTimeout=-1</config-property-value>
</config-property>