81.2. 有状态 KIE 会话
有状态 KIE 会话是一种会话,用于随着时间的推移对事实进行迭代更改。在有状态 KIE 会话中,来自之前调用 KIE 会话(之前会话状态)的数据会在会话调用之间保留,而在无状态 KIE 会话中,数据会被丢弃。
确保在运行有状态 KIE 会话后调用 dispose()
方法,以便在会话调用之间不会发生内存泄漏。
有状态 KIE 会话通常用于以下用例:
- 监控 (如监控库存市场并自动化购买流程)
- 诊断,如运行故障查找进程或医疗诊断流程
- 物流,如 parcel 跟踪和交付配置
- 确保合规性,如验证市场交易的合法性
例如,请考虑以下触发警报数据模型和示例 DRL 规则:
sprinklers 和触发警报的数据模型
public class Room { private String name; // Getter and setter methods } public class Sprinkler { private Room room; private boolean on; // Getter and setter methods } public class Fire { private Room room; // Getter and setter methods } public class Alarm { }
激活 sprinklers 和 alarm 设置的 DRL 规则示例
rule "When there is a fire turn on the sprinkler" when Fire($room : room) $sprinkler : Sprinkler(room == $room, on == false) then modify($sprinkler) { setOn(true) }; System.out.println("Turn on the sprinkler for room "+$room.getName()); end rule "Raise the alarm when we have one or more fires" when exists Fire() then insert( new Alarm() ); System.out.println( "Raise the alarm" ); end rule "Cancel the alarm when all the fires have gone" when not Fire() $alarm : Alarm() then delete( $alarm ); System.out.println( "Cancel the alarm" ); end rule "Status output when things are ok" when not Alarm() not Sprinkler( on == true ) then System.out.println( "Everything is ok" ); end
对于 当一个触发时,触发了 sprinkler
规则,在发生触发时,会为使用该房间创建 Fire
类的实例并插入到 KIE 会话中。该规则为 Fire
实例中匹配特定 空间
添加约束,以便只检查该空间的 sprinkler。执行此规则时,sprinkler 激活。其他示例规则决定了警报何时激活或相应地取消激活。
无状态 KIE 会话依赖于标准 Java 语法来修改字段,有状态 KIE 会话依赖于规则中的修改语句来通知更改的决策引擎。然后,决策引擎会超出变化的原因,并评估对后续规则执行的影响。这个过程是决策引擎使用差异和 真相维护 的一部分,在有状态 KIE 会话中至关重要。
在本例中,Red Hat Process Automation Manager 项目的 ~/resources
文件夹中的示例规则和所有其他文件都使用以下代码构建:
创建 KIE 容器
KieServices kieServices = KieServices.Factory.get(); KieContainer kContainer = kieServices.getKieClasspathContainer();
此代码编译类路径上找到的所有规则文件,并在 KieContainer
中添加了此编译结果(即 KieModule
对象)。
最后,KieSession
对象从 KieContainer
进行实例化,并针对指定数据执行:
实例化有状态 KIE 会话并输入数据
KieSession ksession = kContainer.newKieSession(); String[] names = new String[]{"kitchen", "bedroom", "office", "livingroom"}; Map<String,Room> name2room = new HashMap<String,Room>(); for( String name: names ){ Room room = new Room( name ); name2room.put( name, room ); ksession.insert( room ); Sprinkler sprinkler = new Sprinkler( room ); ksession.insert( sprinkler ); } ksession.fireAllRules();
控制台输出
> Everything is ok
添加数据后,决策引擎会完成所有模式匹配,但没有执行规则,因此会显示配置的验证消息。在新的数据触发规则条件时,决策引擎会执行规则来激活警报,然后取消已激活的警报:
输入新数据来触发规则
Fire kitchenFire = new Fire( name2room.get( "kitchen" ) ); Fire officeFire = new Fire( name2room.get( "office" ) ); FactHandle kitchenFireHandle = ksession.insert( kitchenFire ); FactHandle officeFireHandle = ksession.insert( officeFire ); ksession.fireAllRules();
控制台输出
> Raise the alarm > Turn on the sprinkler for room kitchen > Turn on the sprinkler for room office
ksession.delete( kitchenFireHandle ); ksession.delete( officeFireHandle ); ksession.fireAllRules();
控制台输出
> Cancel the alarm > Turn off the sprinkler for room office > Turn off the sprinkler for room kitchen > Everything is ok
在本例中,为返回的 factHandle
对象保留一个引用。事实句柄是插入的实例的内部引擎引用,让实例被调整或修改。
如示例所示,来自之前有状态 KIE 会话(激活的警报)的数据和结果会影响随后的会话(alarm 取消)的调用。