Drools Fusion SessionPseudoClock 未按预期工作
Drools Fusion SessionPseudoClock Not working as expected
我正在尝试将 KieSession
日期设置为与 运行 规则之前对象中的日期变量相同的日期。我使用此配置创建我的 KieSession
KieSessionConfiguration configuration = KieServices.Factory.get().newKieSessionConfiguration();
configuration.setOption(ClockTypeOption.get("pseudo"));
在 运行 规则之前,我使用 advanceTime()
将会话日期设置为所需日期。
final SessionPseudoClock clock = kSession.getSessionClock();
clock.advanceTime(object.getDate().getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
final List<Command<?>> commands = new ArrayList<>();
commands.add(CommandFactory.newInsertElements(objects)
commands.add(CommandFactory.newInsert(object, "object"));
final ExecutionResults results = kSession.execute(CommandFactory.newBatchExecution(commands));
这导致使用滑动 windows 的规则失灵。让我们说检查 1 小时内通过的对象,而我在过去一小时内没有任何对象。前一天我只有 3 个对象。这是对象的示例数据集。
objects: [
{
clientId: "id",
date: 2021-02-09T12:00:38.249Z,
...
}
{
clientId: "id",
date: 2021-02-09T13:00:38.249Z,
...
}
{
clientId: "id",
date: 2021-02-09T14:00:38.249Z,
...
}
]
我有一个规则,检查是否有超过 2 个对象在 1 小时内具有相同的 clientId
。
$object : Object($clientId : clientId)
List( size > 2 ) from collect ( Object( this before $object, clientId == $clientId ) over window:time(1h))
当我传递具有这些值的对象时。上面的规则 returns 正确,但我们显然没有任何日期在过去一小时内的对象。
{ clientId: "id", date: 2021-02-10T14:00:38.249Z, ... }
我相信这是因为新的配置而被破坏,因为它以前是工作的(当我没有尝试更改会话时钟时)但我希望会话日期等于对象日期。任何人都知道这里的问题是什么以及如何解决它?
正如 所说,您需要在每次插入事件之间操作 SessionPseudoClock
。我将实现一个新的 Command
,扩展 InsertElementsCommand
和 @Override
它是 execute
方法:
@Override
public Collection<FactHandle> execute(Context context) {
KieSession kSession = ((RegistryContext) context).lookup(KieSession.class);
List<FactHandle> handles = new ArrayList<>();
Object workingMemory = StringUtils.isEmpty(super.getEntryPoint()) ?
kSession :
kSession.getEntryPoint(super.getEntryPoint());
SessionPseudoClock clock = kSession.getSessionClock();
super.objects.forEach(event -> {
clock.advanceTime(((YourObject) event).getDate().getTime() - clock.getCurrentTime(), TimeUnit.MILLISECONDS);
handles.add(((EntryPoint) workingMemory).insert(event));
});
...
return handles;
}
而不是:
commands.add(CommandFactory.newInsertElements(objects));
我会:
commands.add(new YourInsertElementsCommand(objects));
我正在尝试将 KieSession
日期设置为与 运行 规则之前对象中的日期变量相同的日期。我使用此配置创建我的 KieSession
KieSessionConfiguration configuration = KieServices.Factory.get().newKieSessionConfiguration();
configuration.setOption(ClockTypeOption.get("pseudo"));
在 运行 规则之前,我使用 advanceTime()
将会话日期设置为所需日期。
final SessionPseudoClock clock = kSession.getSessionClock();
clock.advanceTime(object.getDate().getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
final List<Command<?>> commands = new ArrayList<>();
commands.add(CommandFactory.newInsertElements(objects)
commands.add(CommandFactory.newInsert(object, "object"));
final ExecutionResults results = kSession.execute(CommandFactory.newBatchExecution(commands));
这导致使用滑动 windows 的规则失灵。让我们说检查 1 小时内通过的对象,而我在过去一小时内没有任何对象。前一天我只有 3 个对象。这是对象的示例数据集。
objects: [
{
clientId: "id",
date: 2021-02-09T12:00:38.249Z,
...
}
{
clientId: "id",
date: 2021-02-09T13:00:38.249Z,
...
}
{
clientId: "id",
date: 2021-02-09T14:00:38.249Z,
...
}
]
我有一个规则,检查是否有超过 2 个对象在 1 小时内具有相同的 clientId
。
$object : Object($clientId : clientId)
List( size > 2 ) from collect ( Object( this before $object, clientId == $clientId ) over window:time(1h))
当我传递具有这些值的对象时。上面的规则 returns 正确,但我们显然没有任何日期在过去一小时内的对象。
{ clientId: "id", date: 2021-02-10T14:00:38.249Z, ... }
我相信这是因为新的配置而被破坏,因为它以前是工作的(当我没有尝试更改会话时钟时)但我希望会话日期等于对象日期。任何人都知道这里的问题是什么以及如何解决它?
正如 SessionPseudoClock
。我将实现一个新的 Command
,扩展 InsertElementsCommand
和 @Override
它是 execute
方法:
@Override
public Collection<FactHandle> execute(Context context) {
KieSession kSession = ((RegistryContext) context).lookup(KieSession.class);
List<FactHandle> handles = new ArrayList<>();
Object workingMemory = StringUtils.isEmpty(super.getEntryPoint()) ?
kSession :
kSession.getEntryPoint(super.getEntryPoint());
SessionPseudoClock clock = kSession.getSessionClock();
super.objects.forEach(event -> {
clock.advanceTime(((YourObject) event).getDate().getTime() - clock.getCurrentTime(), TimeUnit.MILLISECONDS);
handles.add(((EntryPoint) workingMemory).insert(event));
});
...
return handles;
}
而不是:
commands.add(CommandFactory.newInsertElements(objects));
我会:
commands.add(new YourInsertElementsCommand(objects));