我有这种情况:用户收集订单作为订单行。我用包含顺序更改事件的Kafka主题实现了这一点,这些事件被合并,存储在本地键值存储中,并作为具有订单版本的第二个主题进行广播。
我需要以某种方式对已放弃的订单做出反应-已下达的订单至少在过去x个小时内没有任何变化。
简单的解决方案是每隔y分钟扫描一次本地存储,然后将订单状态更改事件发布为“放弃”。似乎我不能从处理器访问存储...但是它也不是很优雅的编码。欢迎任何建议。
-编辑
我不能只将动词添加到合并/验证转换器中,因为它的输出是不同的,并且应该路由到其他位置,例如此图像(单个kafka流应用程序):
因此,“废弃的订单处理器/变压器”将成为其输入的无操作(此处唯一的触发是时间)。另一件事是,在这种情况下(如上图所示),我的转换器在初始化时获取了ForwardingDisabledProcessorContext,因此我无法在标点符号中发出任何消息。我可以在那里传递kafkaTemplate bean并产生新消息,但是整个处理器/变压器只是空壳,只能访问本地存储...
这是我使用的代码段:
public class AbandonedOrdersTransformer implements ValueTransformer<OrderEvent, OrderEvent> {
@Override
public void init(ProcessorContext processorContext) {
this.context = processorContext;
stateStore = (KeyValueStore)processorContext.getStateStore(KafkaConfig.OPENED_ORDERS_STORE);
//main scheduler
this.context.schedule(TimeUnit.MINUTES.toMillis(5), PunctuationType.WALL_CLOCK_TIME, (timestamp) -> {
KeyValueIterator<String, Order> iter = this.stateStore.all();
while (iter.hasNext()) {
KeyValue<String, Order> entry = iter.next();
if(OrderStatuses.NEW.equals(entry.value.getStatus()) &&
(timestamp - entry.value.getLastChanged().getTime()) > TimeUnit.HOURS.toMillis(4)) {
//SEND ABANDON EVENT "event"
context.forward(entry.key, event);
}
}
iter.close();
context.commit();
});
}
@Override
public OrderEvent transform(OrderEvent orderEvent) {
//do nothing
return null;
}
@Override
public void close() {
//do nothing
}
}