drools - 如何让规则只触发一次?
问题描述
假设以下规则侦听具有特定标识符的事件。每个标识符只应处理一个事件。
rule "SampleRule"
dialect "mvel"
no-loop true
when
Event( $identifier : identifier)
not(EventHandler( identifier == $identifier ))
then
EventHandler $h = new EventHandler();
$h.setIdentifier( $identifier );
insert( $h );
end
活动类别:
...
@javax.persistence.Entity
@org.kie.api.definition.type.Role(org.kie.api.definition.type.
Role.Type.EVENT) // line break just for SO
public class Event implements java.io.Serializable {
static final long serialVersionUID = 1L;
@javax.persistence.GeneratedValue(generator = "STATUSNOTIFICATION_ID_GENERATOR", strategy = javax.persistence.GenerationType.AUTO)
@javax.persistence.SequenceGenerator(name = "STATUSNOTIFICATION_ID_GENERATOR", sequenceName = "STATUSNOTIFICATION_ID_SEQ")
private java.lang.Long id;
private java.lang.String identifier;
public Event() {
}
public java.lang.String getIdentifier() {
return this.identifier;
}
public void setIdentifier(java.lang.String identifier) {
this.identifier = identifier;
}
}
事件类是通过 Drools Workbench 配置的。除了将课程声明为 EVENT 之外,我没有更改任何其他内容。
事件插入规则引擎的方式:
KieServicesConfiguration conf = KieServicesFactory.newRestConfiguration(
url, user, pass);
conf.setMarshallingFormat(FORMAT);
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(conf);
RuleServicesClient rulesClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
KieCommands commandsFactory = KieServices.Factory.get().getCommands();
while (hasEvent) {
String identifier = ... // get the identifier of the event, events with same identifier possible, sometimes within same seconds, sometimes several minutes/hours in between
Event event = new Event();
event.setIdentifier(identifier);
Command<?> insert = commandsFactory.newInsert(event, "notificationIdentifier");
Command<?> fireAllRules = commandsFactory.newFireAllRules();
Command<?> batchCommand = commandsFactory.newBatchExecution(Arrays.asList(insert, fireAllRules));
ServiceResponse<ExecutionResults> executeResponse = rulesClient.executeCommandsWithResults("name_of_rules_package_incl_version", batchCommand);
if (executeResponse.getType() == ResponseType.SUCCESS) {
...
} else {
...
}
}
除了上面的“SampleRule”规则之外,我还启用了另一个规则,如果每个标识符的 EventHandler 存在,则从工作内存中收回事件:
rule "SampleRuleClear"
dialect "mvel"
no-loop true
when
$E : Event( $identifier : identifier)
EventHandler( identifier == $identifier )
then
retract( $E );
end
实际上,不应该要求“SampleRuleClear”规则来防止重复。我只是在这里提到它的完整性。
我希望“SampleRule”规则每个标识符每个事件只触发一次。不幸的是,即使事件间隔很远,它也会触发多次。
解决方案
推荐阅读
- powershell - 从 AD OU 获取有关域计算机的特定信息
- javascript - 单击按钮时向地图添加标记?
- javascript - 如何将数组对象中的值设置为 ReactJS 中的动态行?
- javascript - 根据对象的值删除对象
- javascript - 如何防止 Ctrl + c 杀死我的节点进程?
- google-data-studio - 无法在 Google Data Studio CASE 中连接
- php - CONNECT后来自代理的PHP cURL代码502,但它适用于其他网站
- c++ - 迪杰斯特拉计划
- python - 稀疏矩阵行和列表之间的逐元素布尔运算
- authentication - 如何在 Blazor WebAssembly 中实现 OIDC 身份验证?