Resolve issues with multi threaded applications

Resolve issues with multi threaded applications

The following information outlines some of the issues surrounding multi threaded applications and the Oracle Policy Automation Determinations Engine API, and also presents a suggested application architecture that resolves these issues.

What do you want to do?

Understand the relationship between the Determinations Engine and installable handlers

Understand the relationship between rulebases and installable handlers

Understand the relationship between sessions Engine and installable handlers

Apply a recommended architecture solution

Understand the relationship between the Determinations Engine and installable handlers

The only class provided by the Oracle Policy Automation Determinations Engine API that can be created directly, is the Engine class. The Engine is a singleton object that is synchronized internally, so, even though its methods are not apparently synchronized by the Java API, all methods on the Engine are thread safe. In the case of the following methods:

 

These methods are synchronized against the Engine object.

Understand the relationship between rulebases and installable handlers

Rulebase object references are acquired by calling GetRulebase() against an Engine object.  

The first time this method is called for a given rulebase path, the engine loads the rulebase file(s) from disk, and caches a reference to the loaded rulebase.  Subsequent calls to GetRulebase() with the same path will return the cached reference.  

Rulebase objects are the root of the static view of a rulebase, and as such, will be shared among threads in a multithreaded application.  For this reason, all members of the rulebase are internally thread safe.

Note:
The rulebase path supplied to GetRulebase() is used as the key into the cached rulebases collection, and two different paths that refer to the same rulebase file will be considered as two different rulebase instances; that is, “.\MyRulebase.nrb” and “c:\zz\MyRulebase.nrb” might possibly refer to the same physical rulebase file, but Oracle will consider them to be different rulebase instances.

Understand the relationship between sessions Engine and installable handlers

Session object references are acquired by calling CreateSession() against an Engine object.  

If the SessionSynchronizationMode passed in was SYNCHRONIZED, then all methods on the session and entity instance objects will be thread safe.  Where synchronization is required, it will occur against the Session object.  

If the SessionSynchronizationMode passed in was UNSYNCHRONIZED, then thread safety cannot be guaranteed by the engine.  

The methods affected by synchronization include the following installable handler methods:

 

If a managed session object is obtained by the GetManagedSession() method of an Engine object, the session will retain the same synchronization setting as at creation time. This can be queried by calling the GetSynchronizationMode() method of the Session object.

Apply a recommended architecture solution

The following section describes a technique that will ensure that rulebase handlers are only installed once per rulebase. It assumes that the application already has a synchronized ‘bootstrap’ routine, or can create a static initializer block on the main class.

 

Application initialization or ‘bootstrap’

The application, during its initialization, should create an instance of the Engine(), and install a log handler, if desired, and install an instance of an EngineEventHandler.

 

EngineEventHandler:

  // It is assumed that this method  is called once per process, and is thread safe.
                
 void bootstrap() {
    …
    Engine engine = new Engine();
    // Optionally install a log handler
    If ( EngineLoggingEnabled ) {
       engine.installLogHandler( new MyLogHandler() );
    }
    // And install an EngineEventHandler
    engine.installEngineEventHandler( new MyEngineEventHandler() );
    …
}

The Engine Event Handler

public  class MyEngineEventHandler {
                
  public void OnRulebaseLoaded( Rulebase rb ) throws ExpertException {
    // This will only happen once per rulebase, so its perfect for installing the
    // handlers
    rb.installCustomFunctionHandler( new MyCustomFunctionHandler() );
    rb.setFormatter( new MyCustomFormatter() );
  }