2017-11-14 1 views
0

Ich bin neu in Drools. Ich habe die folgende Regel definiert, um die letzten beiden Zahlen im Stream zusammenzufügen. I dann in einem Strom von 100 Ereignissen senden, wobei die von 1 bis 100 eingestellten Werte So würde ich die Ausgabe erwarten, 0 zu sein, 1, 3, 5, 7, 9, 11, 13 usw.Drools - Schiebefenster funktioniert nicht wie erwartet

declare TestEvent 
    @role(event) 
    value : int 
end 
rule "Simple Rule" 
when 
    $sum : Integer() from accumulate (TestEvent($value : value) over window:length(2); sum($value) ) 
then 
    System.out.println("Value: " + $sum); 
end 

Die Sitzung wird mit "FireUntilHalt" in einem separaten Thread gestartet. Wenn ich eine Verzögerung von 10 Millisekunden zwischen jedem eingefügten Ereignis einstelle, funktioniert es wie erwartet. Wenn ich jedoch die Verzögerung nicht habe, sind die Ergebnisse nicht wie erwartet. Normalerweise druckt es nur 0 und 197. Manchmal kann ich auch eine Nummer oder zwei dazwischen bekommen.

Warum passiert das und was sollte ich tun, um zu beheben?

Antwort

0

Schiebefenster sind eine Krücke. Ersetzen Sie es durch einfache Logik.

class Pred { 
    Integer pred; 
} 

rule procInt1 
when 
    $p: Pred(pred == null) 
    $i: Integer() 
then 
    modify($p){ setPred($i); } 
end 

rule procInt 
when 
    $p: Pred($i1: pred != null) 
    $i2: Integer() 
then 
    System.out.println($i1 + $i2); 
    modify($p){ setPred($i2); } 
end 

Die Tatsache, dass Sie zwei Threads haben, bedeutet nicht, dass Sie nicht Rennbedingungen haben. Die Ereignisse zum Einfügen von Threads werden nicht angehalten und alles ist möglich.

+0

Danke für den Vorschlag. Was ich aber versuche, ist zu versuchen, gleitende Fenster (und ihre Begrenzungen) zu verstehen. Derzeit weiß ich nicht, warum ich die Ergebnisse bekomme, die ich habe. Wenn die Ergebnisse davon abhängen, wie schnell Ereignisse in den Stream geschossen werden, scheinen sie sehr fehlerhaft zu sein. Irgendwelche Ideen, warum ich das Verhalten erhalte, das ich sehe? Wie werden diese Regeln intern ausgewertet? – IanB

+0

Alles, was die Drools-Engine tun kann, unterliegt der Thread-Planung von Java. Wenn du in einer einzigen Aufgabe 5 Ereignisse machst und nach den letzten beiden fragst: Was erwartest du? – laune

+0

Ich hatte erwartet, dass die Regeln bei jedem Einfügen ausgewertet werden. Dies ist eindeutig nicht der Fall, daher ist FireUtilHalt nicht sehr unsicher, da es möglich sein könnte, dass nicht alle Regeln korrekt ausgelöst werden, wenn Ereignisse ersetzt werden? – IanB

0

Ok, ich verstehe es endlich. Wenn fireUntilHalt in einem separaten Thread ausgeführt wird, bedeutet dies, dass die Regeln nur hin und wieder ausgewertet werden (nicht sicher, um welchen Zeitraum es sich handelt). Meine Annahme war, dass sie auf jedem insert ausgewertet werden würden. So werden bei jedem insert die Akkumulatorwerte aktualisiert, aber die ausgewerteten Regeln werden nicht ausgewertet. Weil meine Regeln schnell eingefügt werden (in ungefähr einer Sekunde), ist die erste und letzte Einfügung alles, was zu bewerten scheint.

Um dies zum Funktionieren zu bringen, so dass jeder Einsatz ausgewertet wird, entfernte ich die fireUntilHalt und machte nach jedem Einsatz eine separate fireAllRules.

Verwandte Themen