通过 Java API Drools 定时规则执行

Drools timed rule execution via Java API

我想创建一个每 5 分钟触发一次的基于时间的规则,Drools 文档指出:

Conversely when the Drools engine runs in passive mode (i.e.: using fireAllRules instead of fireUntilHalt) by default it doesn’t fire consequences of timed rules unless fireAllRules isn’t invoked again. However it is possible to change this default behavior by configuring the KieSession with a TimedRuleExecutionOption as shown in the following example

KieSessionConfiguration ksconf = KieServices.Factory.get().newKieSessionConfiguration();
ksconf.setOption( TimedRuleExecutionOption.YES );
KSession ksession = kbase.newKieSession(ksconf, null);

但是,我没有直接访问 KieSession 对象,因为我正在使用 Java REST API 像这样将请求发送到部署在 KieExecution 服务器上的 Drools 项目(示例直接取自Drools 文档):

public class MyConfigurationObject {

  private static final String URL = "http://localhost:8080/kie-server/services/rest/server";
  private static final String USER = "baAdmin";
  private static final String PASSWORD = "password@1";

  private static final MarshallingFormat FORMAT = MarshallingFormat.JSON;

  private static KieServicesConfiguration conf;
  private static KieServicesClient kieServicesClient;

  public static void initializeKieServerClient() {
        conf = KieServicesFactory.newRestConfiguration(URL, USER, PASSWORD);
        conf.setMarshallingFormat(FORMAT);
        kieServicesClient = KieServicesFactory.newKieServicesClient(conf);
    }

  public void executeCommands() {

    String containerId = "hello";
    System.out.println("== Sending commands to the server ==");
    RuleServicesClient rulesClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
    KieCommands commandsFactory = KieServices.Factory.get().getCommands();

    Command<?> insert = commandsFactory.newInsert("Some String OBJ");
    Command<?> fireAllRules = commandsFactory.newFireAllRules();
    Command<?> batchCommand = commandsFactory.newBatchExecution(Arrays.asList(insert, fireAllRules));

    ServiceResponse<ExecutionResults> executeResponse = rulesClient.executeCommandsWithResults(containerId, batchCommand);

    if(executeResponse.getType() == ResponseType.SUCCESS) {
      System.out.println("Commands executed with success! Response: ");
      System.out.println(executeResponse.getResult());
    } else {
      System.out.println("Error executing rules. Message: ");
      System.out.println(executeResponse.getMsg());
    }
  }
}

所以我对如何将此 TimedRuleExecutionOption 传递给会话感到有点困惑?

我已经通过定期发送 FireAllRules 命令找到了解决方法,但我想知道我是否可以配置此会话选项,这样我就不必为我想要的每个定时事件添加定期触发创建。

此外,我尝试使用 FireUntilHalt 而不是 FireAllRules,但据我了解,该命令会阻止服务器上的执行线程,我必须在某个时候发送 HaltCommand,所有这些我都想避免,因为我有一个将事件发送到服务器的多线程客户端。

您可以使用 drools 的 cron 功能。它充当计时器并根据 cron 表达式调用规则。每 5 分钟执行一次规则的示例:

rule "Send SMS every 5 minutes"
    timer (cron:* 0/5 * * * ?)
when
    $a : Event( )
then

end

你可以找到解释here

在启动部署了 kie-server.war 的服务器实例时传递“-Ddrools.timedRuleExecution=true”。