当前位置: 首页 > 知识库问答 >
问题:

Drools融合会话伪时钟未按预期工作

聂煜
2023-03-14

在运行规则之前,我正在尝试将KieSessiondate设置为与我对象中的日期变量相同的日期。我使用此配置来创建我的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));

这导致使用滑动窗口的规则出现错误。比如说,检查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,
    ...
  }
]

我有一条规则,检查在1小时内是否有超过2个对象具有相同的客户ID。

$object : Object($clientId : clientId)
List( size > 2 ) from collect ( Object( this before $object, clientId == $clientId ) over window:time(1h))

当我用这些值传递对象时。上面的规则返回true,但我们显然没有任何日期在最后一个小时内的对象。

  { clientId: "id", date: 2021-02-10T14:00:38.249Z, ... }

我相信这是因为它以前工作的新配置而损坏的(当我没有尝试更改会话时钟时),但我希望会话日期等于对象日期。任何人都知道这里有什么问题以及如何解决它?

共有1个答案

充煌
2023-03-14

正如冷冻豌豆的Roddy所说,您需要在每次插入事件之间操纵SessionPseudoClock。我将执行一个新的命令,扩展插入元素命令和覆盖它的执行方法:

    @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));

 类似资料:
  • Flink中的会话窗口在prod env上没有按预期工作(相同的逻辑在本地env上工作)。这个想法是为特定的用户ID发出“sample_event_two”的计数 尽管集合中存在sample_event_one(通过验证日志消息“已接收sample_event_one”是否存在来确认)并且计数计算正确,但我没有看到任何输出事件被创建。我看到日志消息“未找到 sampleOneEvent 事件,而不

  • 结束 当我通过ksession.insert(Object)将一些人插入工作记忆时,只计算第一个人,忽略其他的人。我对Drools激活组的理解是,如果我有X个规则,这些规则属于同一个激活组,具有不同的显着性值,那么每个人都将被规则处理,显着性最高的将被激发,其余的将被忽略。一旦完成,下一个人将通过并重复这个过程。我所经历的是,第一个触发该激活组中任何规则的人将禁用整个激活组,不再处理其他人员。有什

  • 例如,当我进入登录页面时...sessionCreated-将一个会话添加到计数器:1 然后,当我点击log out按钮时,会话计数减少了1(这很好),但紧接着会话计数增加了1(不是预期的)。 例如,当我按下注销按钮时...sessionDestroyed-从计数器0中扣除一个会话sessionCreated-将一个会话添加到计数器1中 我再次需要帮助来理解请。 这是我的Spring安全设置...

  • 我正在使用spring Roo并希望访问Controller类中的一个bean,该类在ApplicationContext.xml中具有以下配置: 配置类本身是: 在我的Controller中,我认为一个简单的Autowired注释应该可以完成这项工作 在启动过程中,spring在setSkipWeeks方法中打印消息。不幸的是,每当我在控制器中调用config.getSkipWeeks()时,它

  • 当我运行以下程序时,它只打印 然而,从Java 8的equalsIgnoreCase文档中我们发现: 如果以下至少一项为真,则两个字符c1和c2被视为相同的忽略情况: •对每个字符应用java.lang.character.ToUpperCase(char)方法会产生相同的结果 所以我的问题是为什么这个程序不打印 在这两种操作中,都使用了大写字符。

  • 我试图使用来传输我根据前面的问题设置的自定义标头。 我在文件中读到... 我的属性包括: