使用SequenceBarrier进行LMAX干扰依赖图/门控

时间:2017-05-02 18:03:14

标签: java disruptor-pattern lmax

目标

我正在尝试在处理程序之间创建一个有点循环的依赖关系,而我无法弄清楚如何正确处理它。我想要实现的是producer -> [handlers 1-3] -> handler 4的变体。

所以,disruptor.handleEventsWith(h1, h2, h3).then(h4);。但我还有其他要求

  1. 虽然处理程序1-3会并行处理消息,但在完成上一条消息之前,它们都没有开始处理下一条消息。
  2. 在第一条消息之后,处理程序1-3在处理下一条消息之前等待处理程序4完成最新消息。
  3. 使用单个事件处理程序的等效执行逻辑可以是:

    disruptor.handleEventsWith((event, sequence, endOfBatch) -> {
      Arrays.asList(h1, h2, h3).parallelStream()
            .forEach(h -> h.onEvent(event, sequence, endOfBatch));
      h4.onEvent(event, sequence, endOfBatch);
    });
    

    上下文

    设计上下文是处理程序1-3每个都根据消息更新它们自己的状态,并且在三个处理消息之后它们处于一致状态。然后,处理程序4基于处理程序1-3更新的状态运行一些逻辑。因此,处理程序4应该只能看到由1-3维护的数据结构的一致状态,这意味着处理程序1-3在处理程序4完成之前不应处理下一条消息。

    (虽然目标绝对是使用Disruptor来管理并发,而不是java.util.Stream。)

    不确定是否重要,但也可以将处理程序4的逻辑分成两部分,一部分要求处理程序1-3没有被更新,而下一部分只要求处理程序4的第一部分有完了。因此处理程序1-3可以在处理程序4的第二部分仍在执行时处理消息。

    有没有办法实现这个目标?或许我的设计有缺陷?我觉得应该有办法通过SequenceBarrier来做到这一点,但我不太明白如何实现这个自定义障碍。对于处理程序1-3,我想我想用逻辑handlers[1:3].lastProcessedSequence() == handlers[4].lastProcessedSequence()制作一个障碍,但我不确定在哪里放这个逻辑。

    谢谢!

1 个答案:

答案 0 :(得分:0)

我会考虑让处理程序无状态,并使用它们处理的消息来包含系统的状态。这样,您根本不需要同步处理程序。