[英]Drools: Time restricted rule
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
Drools还支持定期重复的规则,其中interval为timer(int:)
,cron为timer(cron:)
但这意味着规则在这些点被触发。
如果有任何选项如何指定具有时间限制的定期可用(未触发)规则,我感兴趣。 例如,让我们想象某个公司的营业时间 - 只能在正式工作期间而不是在工作时间之后执行操作。
我想要这样的东西,但这不是Drools的有效规则
rule "Time-restricted rule"
time-effective "8:00" # 8 AM
time-expires "16:00" # 4 PM
when
then
end
是否可以将此规则延长至周一至周五上午8点至下午4点?
Drools没有直接支持基于时间的关键字,但它们使用Quartz库提供了更强大的日历机制。 StatelessSession
创建的StatefulSession
或WorkingMemory
具有定义这些日历的方法,这些日历可以限制可以触发规则的日期和时间。
示例:规则定义
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 );
更好的方法是使用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
希望能帮助到你,
这是另一种解决方案。 也许有点黑客,但它有效:
您可以创建一个封装当前时间的简单Java类,并将此类的实例添加到工作内存中。 这个类称为TimeFact
,它有像update(long time): void
这样的方法update(long time): void
, getDay(): String
和getTime(): String
。 然后可以在规则的when
部分使用此事实,如下所示:
rule "Foo"
when
TimeFact(day in ("Monday", "Thursday"), time > "16:00:00" && < "17:00:00")
[more conditions]
then
[do stuff]
end
在触发规则之前,您需要更新TimeFact
(并通知此更新的规则引擎)。 尽管如此,它的优点是规则激活时间可以在规则本身中描述,而不必定义可能大量的calendars
,从而使这种方法更加灵活。
当然,如果你只有几个这样的时间条件,比如“办公时间”,那么使用calendars
的解决方案更可取。
根据文档,您可以使用cron表达式作为计时器。 所以,你可以使用这样的东西:
timer(cron: * 8-16 * * 1-5 *)
免责声明:我没有测试过这个!
希望能帮助到你,
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.