我有一个带有状态存储的 Transformer,它使用 punctuate 对所述状态存储进行操作。 经过几次 punctuate 迭代后,操作可能已经完成,所以我想取消 punctuate —— 但仅限于实际完成对分区各自状态存储的操作的 Task。尚未完成的任务的标点操作应继续运行。为此,我的转换器保留了对 schedule() 返回的 Cancelable 的引用。
据我所知,每个 Task 总是有自己独立的 Transformer 实例,每个 Task 在该实例中都有自己独立的调度 punctuate() (?)
然而,由于这是有效的状态,而不是在 stateStore 内,我不确定这有多安全。例如,在某些情况下,是否可以跨任务共享一个转换器实例(因此绝对没有状态必须保留在 StateStore 之外)?
public class CoolTransformer implements Transformer {
private KeyValueStore stateStore;
private Cancellable taskPunctuate; // <----- Will this lead to conflicts between tasks?
public void init(ProcessorContext context) {
this.store = context.getStateStore(...);
this.taskPunctuate = context.schedule(Duration.ofMillis(...), PunctuationType.WALL_CLOCK_TIME, this::scheduledOperation);
}
private void scheduledOperation(long l) {
stateStore.get(...)
// do stuff...
if (done) {
this.taskPunctuate.cancel(); // <----- Will this lead to conflicts between tasks?
}
}
public KeyValue transform(key, value) {
// do stuff
stateStore.put(key, value)
}
public void close() {
taskPunctuate.cancel();
}
}
答案 0 :(得分:0)
您可能可以查看 TransformerSupplier,特别是 TransformSupplier#get()
,这将确保我们在应该保持独立的时候创建我们的新转换器。此外,转换器不应共享对象,因此请注意您的 Cancellable taskPunctuate
。如果违反其中任何一种情况,您应该会看到 org.apache.kafka.streams.errors.StreamsException: Current node is unknown
、ConcurrentModificationException
或 InstanceAlreadyExistsException
之类的错误。