0

私は小さなdroolsプロジェクトで働いていますが、次の問題があります:

-knowledgeAgentを介してdroolsからknowledgepackagesを読み取ると、ロードに長い時間がかかります
( guvnorは非常に激しいです))

  • だから私はKnowledgeBaseをシステム上でローカルに配置されているファイルにシリアル化しようとしています
    -一方ではローカルファイルからのkBaseのロードがはるかに高速
    であるため-そしてもう一方ではKnowledgeBaseを他の目的で使用できるようにアプリケーション
    これに関する問題は、KnowledgeAgentを使用してKnowledgeBaseを最初にロードするときに、ベースがエージェントによって自動的に更新されること

    です。ただし、ベースが更新されている間、ローカルファイルも更新されない
    ので疑問に思います。ナレッジベースをシリアル化するメソッドを呼び出すことができるように、KnowledgeAgentからchangeNotificationを処理/取得する方法は?


    これはどういうわけか可能ですか?基本的に、誰かがガバナーでルールを編集するたびに、ローカルナレッジベースファイルを更新したいので、ローカルファイルは常に最新の状態になります。


    それが不可能な場合、またはそもそも本当に悪い解決策である場合、それを実行するための推奨/最良の方法は何ですか?


    私の英語と質問自体に耐えてください。私が達成したいことを本当に理解できない場合、または私の要求が実際に良い解決策ではない場合、または質問自体が冗長である場合は、Javaにかなり慣れておらず、まったく新しいです。よだれ。

以下はコードです:

パブリッククラスDroolsConnection{

private static KnowledgeAgent kAgent;
private static KnowledgeBase  kAgentBase;

public DroolsConnection(){
     ResourceFactory.getResourceChangeNotifierService().start();
     ResourceFactory.getResourceChangeScannerService() .start();

} 

public KnowledgeBase readKnowledgeBase( ) throws Exception {

     kAgent     = KnowledgeAgentFactory.newKnowledgeAgent("guvnorAgent");
     kAgent      .applyChangeSet( ResourceFactory.newFileResource(CHANGESET_PATH));
     kAgent.monitorResourceChangeEvents(true);

     kAgentBase = kAgent.getKnowledgeBase();
     serializeKnowledgeBase(kAgentBase);
     return kAgentBase;

   }


 public List<EvaluationObject> runAgainstRules( List<EvaluationObject> objectsToEvaluate,
                                                KnowledgeBase kBase ) throws Exception{

    StatefulKnowledgeSession knowSession = kBase.newStatefulKnowledgeSession();
    KnowledgeRuntimeLogger knowLogger    = KnowledgeRuntimeLoggerFactory.newFileLogger(knowSession, "logger");

    for ( EvaluationObject o : objectsToEvaluate ){
        knowSession.insert( o );
    }

    knowSession.fireAllRules();
    knowLogger .close();
    knowSession.dispose();
    return objectsToEvaluate;
 }


 public KnowledgeBase serializeKnowledgeBase(KnowledgeBase kBase) throws IOException{

        OutputStream outStream = new FileOutputStream( SERIALIZE_BASE_PATH );
        ObjectOutputStream oos = new ObjectOutputStream( outStream );
        oos.writeObject        ( kBase );
        oos.close();
        return kBase;
 }


 public KnowledgeBase loadFromSerializedKnowledgeBase() throws Exception {

        KnowledgeBase kBase   = KnowledgeBaseFactory.newKnowledgeBase(); 
        InputStream is        = new FileInputStream( SERIALIZE_BASE_PATH );
        ObjectInputStream ois = new ObjectInputStream( is );
        kBase                 = (KnowledgeBase) ois.readObject();
        ois.close();
        return kBase;
 }

}


よろしくお願いします!
よろしく、
マレンコ

4

1 に答える 1

0

ローカルkbaseを最新の状態に保つために、KnowledgeAgentEventListenerを使用して、内部kbaseがいつ更新されるかを知ることができます。

    kagent.addEventListener( new KnowledgeAgentEventListener() {

        public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {
        }

        public synchronized void afterChangeSetApplied(AfterChangeSetAppliedEvent event) {
        }

        public void beforeChangeSetProcessed(BeforeChangeSetProcessedEvent event) {
        }

        public void afterChangeSetProcessed(AfterChangeSetProcessedEvent event) {
        }

        public void beforeResourceProcessed(BeforeResourceProcessedEvent event) {
        }

        public void afterResourceProcessed(AfterResourceProcessedEvent event) {
        }

        public void knowledgeBaseUpdated(KnowledgeBaseUpdatedEvent event) {
            //THIS IS THE EVENT YOU ARE INTERESTED IN 
        }

        public void resourceCompilationFailed(ResourceCompilationFailedEvent event) {               
        }
    } );

ただし、ローカルkbaseでの同時アクセスを処理する必要があります。

ちなみに、「newInstance」構成オプションを使用していないため、変更セットが適用されるたびに、エージェントはkbaseの新しいインスタンスを作成します。そのため、アプリにある参照ではなく、kagentの内部kbase(kagent.getKnowledgeBase())をシリアル化するようにしてください。

それが役に立てば幸い、

于 2013-02-09T11:01:57.590 に答える