这是第二后 一系列更新的Kogito主动性和我们的努力,使Drools的云。 在这篇文章中,我们将深入研究规则单元的细节,并向您展示为什么我们对它们感到兴奋。
规则的全包执行模型
如果您一直在仔细检查Drools手册,以在每个最新发行版中寻找新功能,则您可能已经注意到,该术语
统治部队已经坐在那里一段时间,这是一项极为实验性的功能 。 简而言之,规则单元既是规则的模块又是执行的单元 —之所以不称其为模块是为了避免与JVM模块混淆。 在Kogito,我们正在重新研究并扩展我们的原始原型。
规则单元收集一组规则以及对该规则所作用的工作存储器的描述。 工作存储器的描述被编写为带有DataSource字段的常规Java类。 每个数据源代表工作存储器的类型分区 ,并且存在具有不同功能的不同类型的数据源。 例如,在下面的示例中,我们使用了仅附加数据源,称为
数据流。
public class MonitoringService implements RuleUnitMemory {private final DataStream<Event> events = DataSource.createStream();private final DataStream<Alert> alerts = DataSource.createStream();
}
给定规则单元的规则与单元声明一起收集在DRL文件中
package org.kie.kogito.rules.alerting
unit MonitoringService
rule IncomingEvent when// matches when a temperature higher than 30 °C is registered (OOPath syntax)$e : /events # Temperature[ value >= 30 ] // Temperature is an Event subclass
thenSystem.out.println("incoming event: "+ $e.getMessage());alerts.append( new WarningHighTemperature($e) );
end
单位中的每个规则对相应类中已声明的所有数据源具有可见性。 实际上,一个单元的类和DRL文件的集合构成一个整体 :您可以将这样的整体视为
一个单一的 类 ,其中字段是全局范围内的全局变量 , 方法是规则 。 实际上,字段的使用取代了DRL全局变量的使用。
规则单元被提交给调度程序执行。 规则单元可以决定产生其执行给其他单位的规则,有效地将其付诸实施。 例如:
rule IncomingEvent when// matches when a temperature higher than 30 °C is registered (OOPath syntax)$e : /events # Temperature[ value >= 30 ] // Temperature is an Event subclass
then// Suspend execution of this unit, yield to the HighTemperatureUnitHighTemperatureUnit.createInstance(events).run();
end
但是规则单元也可能处于长期运行状态 。 在这种情况下,
其他规则单元可以同时在同一时间运行; 由于可以跨单元共享数据源,因此可以通过交换消息来协调单元。
考虑以下示例:
package org.kie.kogito.rules.alerting
unit MonitoringService
rule IncomingEvent when// matches when a temperature higher than 30 °C is registered (OOPath syntax)$e : /events # Temperature[ value >= 30 ] // Temperature is an Event subclass
thenSystem.out.println("incoming event: "+ $e.getMessage());alerts.append( new WarningHighTemperature($e) );
end
规则单元以某种方式充当交换消息的“参与者” 。 但是,以一种非常独特的方式,规则单元允许执行更复杂的执行链,这适合基于规则的推理。 例如,
考虑一下Akka手册中的示例 :
override def receive: Receive = {case RecordTemperature(id, value) =>log.info("Recorded temperature reading {} with {}", value, id)lastTemperatureReading = Some(value)sender() ! TemperatureRecorded(id)case ReadTemperature(id) =>sender() ! RespondTemperature(id, lastTemperatureReading)}
如您所见,Akka中的模式匹配严格只针对单个消息 。 这并不奇怪,因为参与者一次处理一条消息。 在规则引擎中,我们可以编写几条规则,在执行时对工作内存的整个状态做出反应:这明显不同于纯粹的参与者模型设计,但同时在创建时提供了很大的灵活性。您可以编写应用程序的业务逻辑的方式。
数据源
值得在数据源上花一些时间。 数据源构造可以看作是对传统工作内存的分区和抽象 。 将提供不同种类的数据源:功能齐全的数据存储区可能支持添加,删除和更新值,从而允许在工作内存上进行更传统的操作; 而受更严格限制的仅追加数据流将更易于与外部数据源和数据接收器(例如Camel连接器)集成。 这样的约束对于启用更高级的用例(例如并行,线程安全的执行和
在OpenShift集群的各个节点之间持久共享通道 (例如:Kafka),实现了完全分布式的规则引擎。
Kogito:ergo Cloud
并行和分布式用例很有趣 ,但是我们需要一步步走到那里。 但是,这并不意味着第一步不会像以自己的方式那样令人兴奋。
对于Kogito,我们要强调云原生的无状态用例,其中
控制流程使用流程进行了外部 化,并借助
Quarkus我们可以将其编译为超快速的本机二进制文件。 因此,我们将在接下来的几周内完成并发布规则单元 自动化REST服务实施 。
在此用例中, 规则单元的基于Java的类型化声明为
自动映射到REST端点的签名。 POST到端点意味着实例化该单元,将数据插入数据源,触发规则,返回响应有效负载。 使用用户提供的查询来计算响应。 例如,考虑以下示例:
package org.kie.kogito.rules.alerting
unit MonitoringService
query Alerts(Alert alert) alert := /alerts # Warning // select all sub-type Warning
end
用户可以使用自动生成的/ monitoring-service端点发布事件。回复将是查询的结果。 在我们的情况下:
{"events": [ { "type": "WarningHighTemperature", "value": 40, "timestamp": "2019-07-12T18:25:45.000Z" }]
}
答复将是查询的结果。 在我们的情况下:
{"events": [ { "type": "Temperature", "value": 10, "timestamp": "2019-07-12T18:25:43.000Z" },{ "type": "Temperature", "value": 25, "timestamp": "2019-07-12T18:25:44.000Z" },{ "type": "Temperature", "value": 40, "timestamp": "2019-07-12T18:25:45.000Z" }]
}
多云,有规则
我们已经提出了我们在Kogito以及以后的下一代规则引擎的愿景。 无状态用例只是迈向迈向规则引擎真正创新之举的第一步。 在接下来的几个月中,我们将努力为并行(本地)和分布式(在Openshift上)分布式单元的调度和部署提供更好的支持,敬请期待。 同时,我们确实希望听到您关于我们正在采取的方向的信息。
翻译自: https://www.javacodegeeks.com/2019/08/kogito-ergo-rules-encompassing-execution-model.html