2

チャオ、私はいくつかの方法でテストしましたが、それでもDrools Fusionのイベント有効期限メカニズムをテストして検証することができないので、ちょっとしたガイダンスを探していますか?

マニュアルを読み、この機能に興味があります。

つまり、イベントが作業メモリーに挿入されると、エンジンは、イベントが他のファクトと一致しなくなったことを検出し、自動的に撤回して、関連するリソースを解放することができます。

Eclipse、5.4.0.FinalでDrools IDEを使用しており、「新しいDroolsプロジェクト」ウィザードで作成されたテンプレートコードを変更して、イベントの有効期限をテストおよび確認しました。

以下のコード。「ライフサイクル」を正しく機能させるために私が理解した方法は次のとおりです。

  • KBaseをSTREAMモードでセットアップする必要があります-チェック
  • イベントを時間順に挿入する必要があります-チェック
  • イベント間の時間的制約を定義する必要があります-私の場合は最後のMessage()を確認してください

ただし、最後にEventFactHandleを検査すると、Event()の有効期限が切れていません。ご協力いただきありがとうございます。

Java:

public class DroolsTest {

    public static final void main(String[] args) {
        try {
            KnowledgeBase kbase = readKnowledgeBase();
            // I do want the pseudo clock
            KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
            conf.setOption(ClockTypeOption.get("pseudo"));
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(conf, null);
            SessionPseudoClock clock = ksession.getSessionClock();
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            // Insert of 2 Event:
            Message message = new Message();
            message.setMessage("Message 1");
            message.setStatus(Message.HELLO);
            ksession.insert(message);
            ksession.fireAllRules();
            clock.advanceTime(1, TimeUnit.DAYS);
            Message message2 = new Message();
            message2.setMessage("Message 2");
            message2.setStatus(Message.HELLO);
            ksession.insert(message2);
            ksession.fireAllRules();
            clock.advanceTime(1, TimeUnit.DAYS);
            ksession.fireAllRules();
            // Now I do check what I have in the working memory and if EventFactHandle if it's expired or not:
            for (FactHandle f : ksession.getFactHandles()) {
                if (f instanceof EventFactHandle) {
                    System.out.println(((EventFactHandle)f)+" "+((EventFactHandle)f).isExpired());
                } else {
                    System.out.println("not an Event: "+f);
                }
            }
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), ResourceType.DRL);
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        // following 2 lines is the template code modified for STREAM configuration
        KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
        config.setOption( EventProcessingOption.STREAM );
        return kbase;
    }

    /*
     * This is OK from template, as from the doc:
     * By default, the timestamp for a given event is read from the Session Clock and assigned to the event at the time the event is inserted into the working memory.
     */
    public static class Message {

        public static final int HELLO = 0;
        public static final int GOODBYE = 1;

        private String message;

        private int status;

        public String getMessage() {
            return this.message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public int getStatus() {
            return this.status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

    }

}

よだれ:

package com.sample

import com.sample.DroolsTest.Message;

declare Message
@role(event)
end

declare window LastMessageWindow
    Message() over window:length(1)
end

rule "Hello World"
    when
       accumulate( $m : Message(status==Message.HELLO) from window LastMessageWindow,
                $messages : collectList( $m ) )
    then
        System.out.println( ((Message)$messages.get(0)).getMessage() );
end

注意:メッセージイベントに1秒の有効期限を追加しても、

@expires(1s)

最初のメッセージイベントが挿入されたという期待どおりの結果がまだ得られません。期待していたはずの結果が期限切れになりましたか?ご協力いただきありがとうございます。

4

1 に答える 1

3

解決策が見つかりました!明らかに、私は愚かで、5.2.0.Finalの古いドキュメントを参照しながら、Drools5.4.0.Finalを使用していることに気づいていませんでした。Drools Fusion 5.4.0.Finalの更新されたドキュメントでは、このボックスは2.6.2用に追加されています。スライド式の長さの窓

長さベースのウィンドウは、セッションからのイベントの有効期限の時間的制約を定義せず、エンジンはそれらを考慮しないことに注意してください。イベントに時間的制約を定義する他のルールがなく、明示的な有効期限ポリシーがない場合、エンジンはそれらを無期限にセッションに保持します。

したがって、Drools5.4.0のSlidingLength Windowを理解したので、最初に「イベント間の時間的制約を定義する必要がある」という3番目の要件は明らかに満たされていません。

Message() over window:length(1)

実際、セッションからのイベントの有効期限の時間的制約の定義ではありません。

この回答を更新すると、誰かが役立つと思います。また、ご存知のとおり、私は実際にドキュメントにアクセスするためにグーグルに頼ることに愚かであり、時には現在のリリースのドキュメントにリダイレクトされないので、それは...

于 2012-09-20T16:49:57.263 に答える