4.4. Rule execution modes and thread safety in the decision engine


The decision engine supports the following rule execution modes that determine how and when the decision engine executes rules:

  • Passive mode: (Default) The decision engine evaluates rules when a user or an application explicitly calls fireAllRules(). Passive mode in the decision engine is best for applications that require direct control over rule evaluation and execution, or for complex event processing (CEP) applications that use the pseudo clock implementation in the decision engine.

    Example CEP application code with the decision engine in passive mode

    KieSessionConfiguration config = KieServices.Factory.get().newKieSessionConfiguration();
    config.setOption( ClockTypeOption.get("pseudo") );
    KieSession session = kbase.newKieSession( conf, null );
    SessionPseudoClock clock = session.getSessionClock();
    
    session.insert( tick1 );
    session.fireAllRules();
    
    clock.advanceTime(1, TimeUnit.SECONDS);
    session.insert( tick2 );
    session.fireAllRules();
    
    clock.advanceTime(1, TimeUnit.SECONDS);
    session.insert( tick3 );
    session.fireAllRules();
    
    session.dispose();

  • Active mode: If a user or application calls fireUntilHalt(), the decision engine starts in active mode and evaluates rules continually until the user or application explicitly calls halt(). Active mode in the decision engine is best for applications that delegate control of rule evaluation and execution to the decision engine, or for complex event processing (CEP) applications that use the real-time clock implementation in the decision engine. Active mode is also optimal for CEP applications that use active queries.

    Example CEP application code with the decision engine in active mode

    KieSessionConfiguration config = KieServices.Factory.get().newKieSessionConfiguration();
    config.setOption( ClockTypeOption.get("realtime") );
    KieSession session = kbase.newKieSession( conf, null );
    
    new Thread( new Runnable() {
      @Override
      public void run() {
          session.fireUntilHalt();
      }
    } ).start();
    
    session.insert( tick1 );
    
    ... Thread.sleep( 1000L ); ...
    
    session.insert( tick2 );
    
    ... Thread.sleep( 1000L ); ...
    
    session.insert( tick3 );
    
    session.halt();
    session.dispose();

    This example calls fireUntilHalt() from a dedicated execution thread to prevent the current thread from being blocked indefinitely while the decision engine continues evaluating rules. The dedicated thread also enables you to call halt() at a later stage in the application code.

Although you should avoid using both fireAllRules() and fireUntilHalt() calls, especially from different threads, the decision engine can handle such situations safely using thread-safety logic and an internal state machine. If a fireAllRules() call is in progress and you call fireUntilHalt(), the decision engine continues to run in passive mode until the fireAllRules() operation is complete and then starts in active mode in response to the fireUntilHalt() call. However, if the decision engine is running in active mode following a fireUntilHalt() call and you call fireAllRules(), the fireAllRules() call is ignored and the decision engine continues to run in active mode until you call halt().

For added thread safety in active mode, the decision engine supports a submit() method that you can use to group and perform operations on a KIE session in a thread-safe, atomic action:

Example application code with submit() method to perform atomic operations in active mode

KieSession session = ...;

new Thread( new Runnable() {
  @Override
  public void run() {
      session.fireUntilHalt();
  }
} ).start();

final FactHandle fh = session.insert( fact_a );

... Thread.sleep( 1000L ); ...

session.submit( new KieSession.AtomicAction() {
  @Override
  public void execute( KieSession kieSession ) {
    fact_a.setField("value");
    kieSession.update( fh, fact_a );
    kieSession.insert( fact_1 );
    kieSession.insert( fact_2 );
    kieSession.insert( fact_3 );
  }
} );

... Thread.sleep( 1000L ); ...

session.insert( fact_z );

session.halt();
session.dispose();

Thread safety and atomic operations are also helpful from a client-side perspective. For example, you might need to insert more than one fact at a given time, but require the decision engine to consider the insertions as an atomic operation and to wait until all the insertions are complete before evaluating the rules again.

Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

Red Hat ドキュメントについて

Legal Notice

Theme

© 2026 Red Hat
トップに戻る