当前位置: 首页 > 知识库问答 >
问题:

口水:时间限制规则

魏彦
2023-03-14

Drools文档提到,规则可以使用诸如生效日期和过期日期之类的属性来指定绝对规则有效期。

例如

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还支持周期性重复的规则,间隔为计时器(int:),cron为计时器(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库提供了更强大的日历机制<由无状态会话创建的code>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 );

共有3个答案

岳和泽
2023-03-14

根据文档,您可以使用cron表达式作为计时器。因此,您可能可以使用以下内容:

timer(cron: * 8-16 * * 1-5 *) 

免责声明:我没有测试这个!

希望有帮助,

朱越
2023-03-14

这是另一个解决方案。也许有点像黑客,但它是有效的:

您可以创建一个封装当前时间的简单Java类,并将该类的一个实例添加到工作内存中。这个类称为TimeFact,它有如下方法:void、getDay():String和getTime():String。然后,当规则的一部分出现时,可以使用此事实,如下所示:

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

在触发规则之前,您需要更新TimeFact(并将此更新通知规则引擎)。尽管如此,它的优点是可以在规则本身中描述规则激活时间,而无需定义可能大量的日历,从而使这种方法更加灵活。

当然,如果您只有几个这样的定时条件,例如“办公时间”,那么使用日历的解决方案更可取。

凌展
2023-03-14

更好的方法是使用日历而不是计时器(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日期对象来表示事件发生的时间,但是我们不确定如何在流口水的LHS中表示我们希望该日期对象在上周发生。重要的是,一周的时间是任意的。它可以随时更改为月或年。最后,请记住,我们的会议是有状态的。 我在这里找到了一个相关的问题:在规则的LHS中使用java.util.Date。我将从以下答案中引用最相关的摘

  • 我不太会流口水和咕噜。 我有一个关于规则流的基本问题。 我在guvnor插件上使用引导编辑器创建了3条规则。现在我想根据第一条规则的结果调用第二条或第三条规则。 e、 g.如果患者年龄小于18岁,则进行第二条规则的小检查,否则请调用第三条规则由高级医生进行检查。 那么,这可以通过使用规则流来实现吗?如果是,如何?是否有任何示例链接和文档来演示它?非常感谢您的帮助。 谢啦

  • 我有一个drl文件,它在两个规则流组中包含规则:“第一个规则流组”和“第二个规则流组”。这些组的激活取决于“规则A”和“规则B”。是否有任何方法可以停用规则B,以便在规则A条件匹配时触发,从而仅将焦点设置为“第一个规则流组”?

  • 我刚开始流口水,遇到了一个问题。 我简化了规则以显示问题: 基本上,我想计算特定路段上发生的事件(路段是道路的一部分)。当同一链接上发生3个事件时,我希望触发规则。 上面的规则几乎起作用了,但是当它发射时,它发射了3次,每个事件发射一次。我只希望它发射一次。 我错过了什么? 非常感谢。

  • 我有很长时间使用JBOSS Drools的经验。我正在处理的当前项目使用Drools 4。 这是我在项目中的一条规则 想法是从没有关联目标对象的工作内存中收回此类项目。我正在使用工作内存中的这些对象对其进行测试: 项目{itemId=7305,itemTYpeId=Item\u TYPE\u A,targetId=-1023}目标{targetId=-1023} 在这种情况下,规则不应该开火,但它

  • 问题内容: 假设我有一个代码,要求用户提供一些输入,例如: 但是我想给用户60秒的时间限制,然后抛出一个异常(在这种情况下,我认为是)。我怎么做? 问题答案: