2017-03-28 2 views
0

J'ai quelques difficultés à faire des drools en pseudo-horloge. Je configure mon moteur en mode flux et je choisis le type d'horloge que j'utilise via la propriété realMode.Drools 6.5 Pseudo-Horloge

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(); 

Le code de AddNewLogLine Fonction

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(); 

Je laisse un peu de code supplémentaire appart qui ne sont pas pertinentes pour mon problema.

La règle:

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 

L'objectif: détecter la ligne de deux journaux dans une fenêtre de 10 secondes. La première et les secondes ne sont pas (11s) et les 2 lignes suivantes, oui.

En mode réel, cela fonctionne très bien. Voici le résultat:

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 

En mode d'horloge pseudo il ne travail. Comme les 4 lignes sont insérées en même temps, les 2 premières activent la règle. Donc, la pseudo-horloge n'est pas utilisée.

Voici le résultat:

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 

Je suppose que c'est parce que je ne parviens pas de pseudo horloge. Mais je ne suis pas capable de trouver où je me trompe.

Quelqu'un? Merci d'avance;

Répondre

0

Je pense que votre problème est dû à une manipulation incorrecte de la pseudo-horloge. De plus, pour obtenir les meilleurs résultats, exécutez la session dans un fil de sa propre qui exécute fireUntilHalt:

Runnable fireUntilHaltRunnable = new Runnable() { 
    public void run() { 
     //  System.out.println("fireUntilHalt"); 
     kSession.fireUntilHalt() 
    } 
}; 
Thread fireUntilHaltThread = new Thread(fireUntilHaltRunnable); 

Les faits sont insérés d'un autre fil. Si vous effectuez des tests avec le pseudo-horloge, assurez-vous que le pseudo-horloge est réglée sur l'horodatage de l'événement si vous utilisez des événements contenant l'horodatage comme un champ:

private void advance(Date eventDate){ 
    long currentTime = clock.getCurrentTime(); 
    long eventTime = eventDate.getTime(); 
    clock.advanceTime(eventTime - currentTime, TimeUnit.MILLISECONDS); 
} 

Est-ce que ce avant vous insérez le fait suivant. Il n'y a pas besoin de dormir entre les inserts.