Drools 6.5伪时钟

Drools 6.5伪时钟,drools,drools-fusion,Drools,Drools Fusion,我有一些困难做流口水运行在伪时钟。 我在流模式下配置我的引擎,并通过realMode属性选择我使用的时钟类型 Date refDate = new Date(System.currentTimeMillis()); boolean realMode = false; SessionPseudoClock clock = null; KieServices ks = KieServices.Factory.get(); KieSessionConfigu

我有一些困难做流口水运行在伪时钟。 我在流模式下配置我的引擎,并通过realMode属性选择我使用的时钟类型

    Date refDate = new Date(System.currentTimeMillis());
    boolean realMode = false;
    SessionPseudoClock clock = null;

    KieServices ks = KieServices.Factory.get();

    KieSessionConfiguration config = KieServices.Factory.get().newKieSessionConfiguration();
    if(realMode) {
        config.setOption( ClockTypeOption.get("realtime") );                        
    } else {
        config.setOption( ClockTypeOption.get("pseudo") );  
    }

    KieContainer kc = ks.getKieClasspathContainer();
    KieSession ksession = kc.newKieSession("cep-rules",config);
    KieRuntimeLogger logger = ks.getLoggers().newFileLogger( ksession, "./out/helloworld" );

    addNewLogLine (ksession, "GDE" , 0);
    addNewLogLine (ksession, "GDE" , 11);
    addNewLogLine (ksession, "GDE" , 3);
    addNewLogLine (ksession, "GDE" , 8);

    logger.close();

    ksession.dispose();
AddNewLogLine函数的代码

    if( realMode) {
        try {
            Thread.sleep(delaiInSeconds*1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }           
    } else {
        if (clock==null) {
            clock = ksession.getSessionClock();
        }
        clock.advanceTime( delaiInSeconds, TimeUnit.SECONDS );
    }
    delai += delaiInSeconds;

    LogItem logLine = new LogItem();
    logLine.setEventDate(new Date (refDate.getTime()+(delai*1000)));
    logLine.setMessage("Message number " + count);
    logLine.setSourceSystemName(sourceSystemName);

    System.out.println(logLine);
    ksession.insert( logLine );

    ksession.fireAllRules();
我留下了一些与我的问题无关的额外代码

规则:

    declare LogItem
        @role (event)
        @timestamp( eventDate )
    end

    rule "LogInserted"
        dialect "mvel"
        when
            l : LogItem ( )
        then
        System.out.println ("New Log inside from " + l.getSourceSystemName() );
    end

    rule "Nb Log SameSystem" 
        dialect "mvel"
        when
            accumulate( LogItem ( sourceSystemName == "GDE") over window:time(10s) ; $cnt: count(1); $cnt == 2 )
        then
        System.out.println ("2 Logs in engine" );
    end 
目标:在10秒内检测两条日志线。 第一行和第二行不是(11s),下面两行是

在真实模式下,它工作良好。结果如下:

    LogItem { message : Message number 1, date : 28/03/2017 11:17:26, sourceSystemName : GDE }
    New Log inside from GDE
    LogItem { message : Message number 2, date : 28/03/2017 11:17:37, sourceSystemName : GDE }
    New Log inside from GDE
    LogItem { message : Message number 3, date : 28/03/2017 11:17:40, sourceSystemName : GDE }
    New Log inside from GDE
    2 Logs in engine
    LogItem { message : Message number 4, date : 28/03/2017 11:17:48, sourceSystemName : GDE }
    New Log inside from GDE
    2 Logs in engine
    LogItem { message : Message number 1, date : 28/03/2017 11:17:26, sourceSystemName : GDE }
    New Log inside from GDE
    LogItem { message : Message number 2, date : 28/03/2017 11:17:37, sourceSystemName : GDE }
    New Log inside from GDE
    2 Logs in engine
    LogItem { message : Message number 3, date : 28/03/2017 11:17:40, sourceSystemName : GDE }
    New Log inside from GDE
    LogItem { message : Message number 4, date : 28/03/2017 11:17:48, sourceSystemName : GDE }
    New Log inside from GDE
在伪时钟模式下,它不工作。因为这4行是同时插入的,所以2行首先激活规则。所以没有使用伪时钟

结果如下:

    LogItem { message : Message number 1, date : 28/03/2017 11:17:26, sourceSystemName : GDE }
    New Log inside from GDE
    LogItem { message : Message number 2, date : 28/03/2017 11:17:37, sourceSystemName : GDE }
    New Log inside from GDE
    LogItem { message : Message number 3, date : 28/03/2017 11:17:40, sourceSystemName : GDE }
    New Log inside from GDE
    2 Logs in engine
    LogItem { message : Message number 4, date : 28/03/2017 11:17:48, sourceSystemName : GDE }
    New Log inside from GDE
    2 Logs in engine
    LogItem { message : Message number 1, date : 28/03/2017 11:17:26, sourceSystemName : GDE }
    New Log inside from GDE
    LogItem { message : Message number 2, date : 28/03/2017 11:17:37, sourceSystemName : GDE }
    New Log inside from GDE
    2 Logs in engine
    LogItem { message : Message number 3, date : 28/03/2017 11:17:40, sourceSystemName : GDE }
    New Log inside from GDE
    LogItem { message : Message number 4, date : 28/03/2017 11:17:48, sourceSystemName : GDE }
    New Log inside from GDE
我想这是因为我没有管理伪时钟。但我找不到我错的地方

有人吗?
提前感谢

我认为您的问题是由于对伪时钟的错误操作造成的。此外,为了获得最佳结果,请在执行fireUntilHalt的线程中运行会话:

Runnable fireUntilHaltRunnable = new Runnable() {
    public void run() {
        //      System.out.println( "fireUntilHalt" );
        kSession.fireUntilHalt()
    }
};
Thread fireUntilHaltThread = new Thread(fireUntilHaltRunnable);
事实是从另一个线程插入的。如果使用伪时钟运行测试,如果使用包含时间戳的事件作为字段,请确保将伪时钟设置为事件的时间戳:

private void advance( Date eventDate ){
    long currentTime = clock.getCurrentTime();
    long eventTime = eventDate.getTime();
    clock.advanceTime( eventTime - currentTime, TimeUnit.MILLISECONDS );
}
在插入下一个事实之前执行此操作。插入之间不需要休眠