我正在将类似pojo的对象/事实插入KieSession,并具有与这些对象交互的规则。在触发所有规则之后,我希望能够检查规则访问了哪些对象及其方法。在概念上,这类似于嘲弄。
我尝试使用Mockito并将模拟对象插入kieSession。我能够得到一个被调用的方法列表,但并不是所有的交互都显示出来。不确定这是Mockito的局限性,还是Drools管理事实和生命周期的方式打破了Mockito。
也许有更好的方法来实现这一点?
更新:推理-我们有一个执行各种规则集的应用程序。应用程序提供了所有数据,但每个规则集只需要一些数据子集。在某些监控需求中,我们希望确切地看到给定规则集访问了哪些数据(getter调用了事实对象)。
这部分问题表明,您(或更有可能是您的管理层)根本不了解Drools的基本生命周期:
推理-我们有一个执行各种规则集的应用程序。应用程序提供了所有数据,但每个规则集只需要一些数据子集。在某些监控需求中,我们希望确切地看到给定规则集访问了哪些数据(getter调用了事实对象)。
下面是对其工作原理的一个非常简单的解释。更详细的解释将超过StackOverflow上应答字段的字符限制。
当您在Drools中调用fireAllRules时,规则引擎将进入一个称为“匹配”的阶段,即决定实际要运行哪些规则。首先,规则引擎根据您的特定规则集(通过显著性、自然顺序等)对规则进行排序,然后遍历此规则列表并执行左侧(LHS;又称“when子句”或“条件”),仅确定规则是否有效。在每个规则的LHS上,每个语句都按顺序执行,直到任何一条语句的计算结果都不为true。
Drools检查完所有规则的LH后,将进入“执行”阶段。在这一点上,所有它认为对射击有效的规则都被执行了。使用匹配阶段的相同顺序,它遍历每个规则,然后执行规则右侧的语句。
当您考虑Drools支持继承时,事情变得更加复杂,因此规则B可以扩展规则A,因此规则A的LHS中的语句将在匹配阶段执行两次——一次是在引擎评估是否可以触发规则B时,另一次是在引擎评估是否可以触发规则A时。
更为复杂的是,您可以通过使用规则右侧的特定关键字(RHS;又称“then子句”或“results”)从执行重新进入匹配阶段,特别是通过调用更新、插入、修改、收回、删除,等。其中一些关键字(如插入)将重新评估规则的子集,而另一些关键字(如更新)将在第二个匹配阶段重新评估所有单词。
我在这次讨论中关注了LHS,因为你的声明说:
有一些监控需求,我们希望准确查看访问了哪些数据(getter调用事实对象)......
除非你有一些真正的非标准规则,否则你的大多数getter应该在你的LHS上。这是您应该获取数据并进行比较/检查/决定是否应取消规则的地方。
希望这是有意义的,为什么知道哪些“get”调用被触发的请求没有真正意义——因为在匹配阶段,我们将触发大量“get”调用,然后忽略结果,因为LHS的其他部分没有评估为true。
我确实认为,我们这里可能存在通信问题,而实际需要的是了解执行中实际使用的数据(RHS)。在这种情况下,您应该像我在评论中建议的那样使用侦听器。如果您编写的侦听器挂接到Drools生命周期,特别是执行阶段(AgendaEventListener的afterMatchFired)。此时,您知道规则已匹配并实际执行,因此您可以记录或记录规则名称和详细信息。由于您知道每个规则所需和使用的确切数据,这将允许您跟踪实际使用的数据。
尽管如此,我还是根据我以前的经验发现了这部分:
应用程序提供所有数据,但每个规则集只需要数据的某些子集。
我工作的公司遵循这种方法——我们通过将所有数据添加到工作内存中,使所有规则都可以使用所有数据。其想法是,如果所有数据都可用,那么我们就能够编写规则,而无需更改支持代码,因为您将来可能需要的任何数据都已经在工作内存中可用。
当我们有小数据时,结果证明这是可以的,但随着公司和产品的增长,这些数据也在增长,我们的规则开始需要大量内存来支持工作内存(特别是当我们的调用量增加时,因为我们需要每个规则请求更大的堆分配)更糟糕的是,我们使用了性能极低的对象传递到工作内存,即HashMaps和扩展HashMap的对象。
有鉴于此,你应该强烈考虑重新思考你的战略。一旦我们修剪了传递到规则中的数据,减少了数据量,并将结构更改为性能POJO,我们不仅看到了资源使用量(主要是堆)的大幅减少,而且还看到了规则吞吐量更大方面的性能改进,因为规则引擎不需要继续处理和评估工作内存中大量低效的数据。
最后,关于在工作记忆中模拟对象的问题,我强烈警告不要尝试这样做。模拟库真的不应该在生产代码中使用。大多数模拟都是通过利用反射和字节码操作的组合来工作的。工作内存中的数据不能保证保持在传入时的初始状态--它会在进程中的不同点进行序列化和反序列化,因此,根据特定模拟库的实现方式,您可能会失去对特定模拟实例的“访问”,相反,您的规则将针对该序列化/反序列化过程中的功能等效副本。
虽然我从来没有在这种情况下尝试过,但是如果你真的想检测你的getter方法,你可以使用方面。但是,你有不可忽视的机会在那里遇到同样的问题。
问题内容: 我正在为一个日志分析器系统工作,该系统读取tomcat的日志并通过网页中的图表/表格显示它们。(我知道有一些现成的日志分析器系统,我正在重新创建轮子。但这是我的工作,我的老板想要。) 我们的tomcat日志按天保存。例如: 以下是我将日志导出到db并读取它们的方式: 1数据库结构 我有三个表:1)log_current:保存今天生成的日志。 2)log_past:保存今天之前生成的日志
我对微服务还是一个新手,有一些基本的架构问题现在还无法解决。我使用Quarkus框架和标准扩展(如quarkus-resteasy和quarkus-rest-client)来实现。 这两个服务都是作为Maven项目创建的。根据教程,我发现正确的方法是在项目中声明一个接口(这里称为),如下所示 然后通过@inject将此接口集成到服务中,这导致了以下示例性服务。 我使在端口8181上本地运行,并在项
问题内容: 任务是编写一个程序,该程序接受来自用户的两组单词,然后如果两个单词都是字谜(或者至少如果一个字母的所有字母都存在于另一个字母中),则打印“ True”语句,然后显示“ False”声明是否。 作为一个整体编程人员,我不知道该如何超越索引一个字符串并将一个字符串的所有片段相互比较的方法。我强调我是一个初学者;我读过许多其他标有Python和Anagram的帖子,它们始终排在我的头上,并引
问题内容: 我正在寻找一个开放源代码Java拼写检查库,该库至少具有以下语言的字典:法语,德语,西班牙语和捷克语。有什么建议吗? 问题答案: 您应该检查一下Jazzy在某些高端Java应用程序中使用的Jazzy。它有两个问题: 自2005年以来未进行过更新。 他们的SourceForge页上只有英语词典。 周围有一些第三方词典。我上过法语,上一次我用爵士乐。
引用CheckMutex.nsi的内容: /************************ CheckMutex.nsi ************************/ ;NSIS 安装程序与卸载程序互相检查互斥的例子 ;编写:zhfi ;邮箱: ;主页:http://hi.baidu.com/zhfi1022/ #定义自己的互斥名称:# #注意安:装程序不能与卸载程序相同!
本文向大家介绍Android AIDL实现与服务相互调用方式,包括了Android AIDL实现与服务相互调用方式的使用技巧和注意事项,需要的朋友参考一下 通过AIDL接口在进程间传递数据,记录在开发中遇到的一写问题 AIDL支持数据类型如下: 1. Java 的原生类型 2. String 和CharSequence 3. List 和 Map ,List和Map 对象的元素必须是AIDL支持的