将Flux条目与上一个和地图组合

时间:2018-12-18 16:28:12

标签: java project-reactor

问题

使用助焊剂如何访问上一个元素?

背景

我有一个外部事件流,该流按顺序给出事件,该流的顺序是调度一个事件,然后立即调度另一个事件。但是,第二个事件的元数据在第一个事件中。

请注意,事件不一定总是偶数。

我想做的是将事件合并为事件流,以供下游消费。

Flux#zip看起来很有希望,但这将意味着返回外部事件类型的对象。

初始代码

到目前为止,我所能拥有的。

    BinaryLogClient client = new BinaryLogClient(host, port, username, password);
    Flux<Event> bridge = Flux.create(sink -> {
        EventListener fluxListener = event -> {
            sink.next(event);
        };

        client.registerEventListener(fluxListener);
    });

    bridge.subscribe(DemoApplication::printEvent);
    bridge.map(new EventPairMemorizer());


public class EventPair  {
    private final Event previous;
    private final Event current;

    public EventPair(Event previous, Event current) {
        this.previous = previous;
        this.current = current;
    }

    /**
     * @return `null` if no previous events.
     */
    public Event getPrevious() {
        return previous;
    }

    public Event getCurrent() {
        return current;
    }
}

/**
 * Not thread safe has to go on a single thread
 */
public class EventPairMemorizer implements Function<Event, EventPair> {
    Event previous = null;

    EventPair toPair(Event e) {
        EventPair pair = new EventPair(previous, e);
        previous = e;
        return pair;
    }

    @Override
    public EventPair apply(Event current) {
        return toPair(current);
    }
}

这部分是学习活动,部分是概念证明。

麻醉剂详细信息

我正在尝试使用mysql-binlog-connector-java获取有关数据库中发生的更改的流。

因此,如果我收到一个EXT_WRITE_ROWS事件,那么上一个事件就是一个TABLE_MAP事件。然后,我想在TABLE_MAP事件上进行列查找(使用jdbc)。然后转换为JSON友好的内部结构。

EXT_UPDATE_ROWS事件也是如此。

所以想法代码看起来像

  1. onExternalEvent推送到Flux
  2. 检查事件类型。如果匹配,请使用Mono在jdbc线程上调用jdbc
  3. 结合Mono和当前事件。
  4. 映射到内部类型。
  5. 发送到其他流。
  6. 利润

2 个答案:

答案 0 :(得分:1)

缓冲区重叠如何?

使用buffer(2, 1),您将为每个元素打开一个缓冲区,每个缓冲区将包含2个元素。

然后,您可以忽略感兴趣的事件不会结束的缓冲区,并获得您感兴趣的事件的先前值...

答案 1 :(得分:1)

您可以使用.scan()

Flux<EventPair> pairs = bridge.scan(new EventPair(null,null),(prevPair,newEvent)->
  new EventPair(prevPair.current,newEvent)
);