5

Droolsのドキュメントdate-effectiveには、ルールはやのような属性を使用date-expiresして絶対ルールの有効期間を指定できることが記載されています。

例えば

rule "Date-restricted rule"
    date-effective "20.2.2013 8:00"      # 8 AM
    date-expires   "20.2.2013 16:00"     # 4 PM
    when
    then
end

timer(int:)Drools は、interval asおよび cron as を使用して定期的に繰り返されるルールもサポートしていますtimer(cron:)が、これはルールがそのようなポイントで起動されることを意味します。

質問:

時間制限のある定期的に利用可能な (起動されない) ルールを指定する方法があるかどうかに興味があります。たとえば、ある会社の営業時間をイメージしてみましょう。業務は正式な勤務時間中にのみ実行でき、時間外は実行できません。

このようなものが欲しいのですが、それは Drools の有効なルールではありません

rule "Time-restricted rule"
    time-effective "8:00"      # 8 AM
    time-expires   "16:00"     # 4 PM
    when
    then
end

このようなルールを、月曜日から金曜日の午前 8 時から午後 4 時までのみ有効になるように拡張することは可能でしょうか?


解決策 (Esteban Aliverti による):

Drools は時間ベースのキーワードを直接サポートしていませんが、Quartzライブラリを使用してより強力なカレンダー メカニズムを提供します。StatefulSessionまたはWorkingMemoryによって作成されたStatelessSessionこれらのカレンダーを定義するメソッドがあり、ルールを実行できる日時を制限できます。

例: ルール定義

rule "Business hours only"
    calendars "business-hours"
    when
        SomeAttachedClass()
    then
        System.out.println("Rule is fired");
end

カレンダーの定義

import org.quartz.impl.calendar.DailyCalendar;

// stateless session and working memory or directly stateful session
StatefulKnowledgeSession memory = session.newWorkingMemory(); 
// interested time range is 8-16, also there is many Calendar implementation, not just Daily
DailyCalendar businessHours = new DailyCalendar( 8, 0, 0, 0, 16, 0, 0, 0 );
// by default, defined time is EXCLUDED, the inversion makes it INCLUDED and excludes the rest
businessHours.setInvertTimeRange( true );
//convert the calendar into a org.drools.time.Calendar
org.drools.time.Calendar businessHoursCalendar = QuartzHelper.quartzCalendarAdapter( businessHours );
//Register the calendar in the session with a name. You must use this name in your rules.
memory.getCalendars().set( "business-hours", businessHoursCalendar );
4

3 に答える 3

6

より良いアプローチは、calendarの代わりに使用することですtimer(cron:)。次の手順に従って、探しているものと同様のことを行うことができました。

セッションを作成するときは、Quartz カレンダーを作成して構成する必要があります。

//in this case I'm using a DailyCalendar but you can use whatever implementation of Calendar you want
org.quartz.impl.calendar.DailyCalendar businessHours = new org.quartz.impl.calendar.DailyCalendar("business-hours", 8, 0, 0, 0, 16, 0, 0, 0);
businessHours.setInvertTimeRange(true);

//convert the calendar into a org.drools.time.Calendar
org.drools.time.Calendar businessHoursCalendar = QuartzHelper.quartzCalendarAdapter(businessHours);

//Register the calendar in the session with a name. You must use this name in your rules.
ksession.getCalendars().set( "business-hours", businessHoursCalendar );

次に、ルールで次のように記述する必要があります。

rule "Rule X"
    calendars "business-hours"
when
    ...
then
    ...
end

それが役に立てば幸い、

于 2013-02-12T11:16:51.250 に答える
1

ここに別の解決策があります。ちょっとハックかもしれませんが、うまくいきます:

現在の時刻をカプセル化する単純な Java クラスを作成し、このクラスのインスタンスを作業メモリに追加できます。このクラスは と呼び、 、 、 などのメソッドTimeFactを持っています。このファクトは、次のようにルールの一部で使用できます。update(long time): voidgetDay(): StringgetTime(): Stringwhen

rule "Foo"
when
    TimeFact(day in ("Monday", "Thursday"), time > "16:00:00" && < "17:00:00")
    [more conditions]
then
    [do stuff]
end

TimeFactルールを実行する前に、 を更新する(そしてこの更新をルール エンジンに通知する)必要があります。それでも、多数の を定義する必要なく、ルールのアクティブ化時間をルール自体に記述できるという利点があるcalendarsため、このアプローチはより柔軟になります。

もちろん、「営業時間」など、そのような時間条件がいくつかしかない場合は、 を使用したソリューションcalendarsが望ましいです。

于 2013-02-13T12:53:20.013 に答える