我正在为自己的应用程序使用具有自定义Trigger
的GlobalWindow。根据要求,在“触发”功能中,我只需要在窗口的第一个元素上启动一个处理时间计时器。
我尝试使用变量firstEventflag
实现它。像这样。
.window(GlobalWindows.create())
.trigger(new Trigger<ImpactEventObject, GlobalWindow>() {
Boolean firstEventflag = false;
@Override
public TriggerResult onElement(ImpactEventObject impactEventObject, long l, GlobalWindow globalWindow, TriggerContext triggerContext) throws Exception {
if (!firstEventflag) {
firstEventflag = true;
triggerContext.registerProcessingTimeTimer(
triggerContext.getCurrentProcessingTime() + 20000);
}
return TriggerResult.CONTINUE;
}
@Override
public TriggerResult onProcessingTime(long l, GlobalWindow globalWindow, TriggerContext triggerContext) throws Exception {
return TriggerResult.FIRE;
}
但这失败了,因为今天我发现变量firstEventflag
并非在每次创建新窗口时都初始化,它取决于正在处理该窗口的子任务,这意味着不同的窗口可以共享相同的变量{{ 1}}有效地使这种逻辑无用。有了这个,我该如何解决我的问题?
答案 0 :(得分:1)
通过查看CountTrigger
here的源代码来找出实现此目的的方法。
我们可以用GlobalWindow
来保存ReducingStateDescriptor
中元素的数量。并在此计数为1时启动计时器,这意味着-仅在第一个元素上启动计时器。
public class CustomTrigger extends Trigger<GenericObject, GlobalWindow> {
private final ReducingStateDescriptor<Long> stateDesc = new ReducingStateDescriptor<>("count", new Sum(), LongSerializer.INSTANCE);
@Override
public TriggerResult onElement(ImpactEventObject impactEventObject, long l, GlobalWindow globalWindow, TriggerContext triggerContext) throws Exception {
ReducingState<Long> count = triggerContext.getPartitionedState(stateDesc);
count.add(1L);
if (count.get() == 1) {
triggerContext.registerProcessingTimeTimer(
triggerContext.getCurrentProcessingTime() + 20000);
}
return TriggerResult.CONTINUE;
}
@Override
public TriggerResult onProcessingTime(long l, GlobalWindow globalWindow, TriggerContext triggerContext) throws Exception {
return TriggerResult.FIRE;
}
@Override
public TriggerResult onEventTime(long l, GlobalWindow globalWindow, TriggerContext triggerContext) throws Exception {
return null;
}
@Override
public void clear(GlobalWindow globalWindow, TriggerContext triggerContext) throws Exception {
triggerContext.deleteProcessingTimeTimer(triggerContext.getCurrentProcessingTime());
}
private static class Sum implements ReduceFunction<Long> {
private static final long serialVersionUID = 1L;
@Override
public Long reduce(Long value1, Long value2) throws Exception {
return value1 + value2;
}
}
}