All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.flink.streaming.api.windowing.triggers.ProcessingTimeoutTrigger Maven / Gradle / Ivy

There is a newer version: 1.14.6
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.flink.streaming.api.windowing.triggers;

import org.apache.flink.annotation.PublicEvolving;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.common.typeutils.base.LongSerializer;
import org.apache.flink.streaming.api.windowing.windows.Window;

import java.time.Duration;

/**
 * A {@link Trigger} that can turn any {@link Trigger} into a timeout {@code Trigger}.
 *
 * 

On the first arriving element a configurable processing-time timeout will be set. Using {@link * #of(Trigger, Duration, boolean, boolean)}, you can also re-new the timer for each arriving * element by specifying {@code resetTimerOnNewRecord} and you can specify whether {@link * Trigger#clear(Window, TriggerContext)} should be called on timout via {@code * shouldClearOnTimeout}. * * @param The type of elements on which this trigger can operate. * @param The type of {@link Window} on which this trigger can operate. */ @PublicEvolving public class ProcessingTimeoutTrigger extends Trigger { private static final long serialVersionUID = 1L; private final Trigger nestedTrigger; private final long interval; private final boolean resetTimerOnNewRecord; private final boolean shouldClearOnTimeout; private final ValueStateDescriptor timeoutStateDesc; private ProcessingTimeoutTrigger( Trigger nestedTrigger, long interval, boolean resetTimerOnNewRecord, boolean shouldClearOnTimeout) { this.nestedTrigger = nestedTrigger; this.interval = interval; this.resetTimerOnNewRecord = resetTimerOnNewRecord; this.shouldClearOnTimeout = shouldClearOnTimeout; this.timeoutStateDesc = new ValueStateDescriptor<>("timeout", LongSerializer.INSTANCE); } @Override public TriggerResult onElement(T element, long timestamp, W window, TriggerContext ctx) throws Exception { TriggerResult triggerResult = this.nestedTrigger.onElement(element, timestamp, window, ctx); if (triggerResult.isFire()) { this.clear(window, ctx); return triggerResult; } ValueState timeoutState = ctx.getPartitionedState(this.timeoutStateDesc); long nextFireTimestamp = ctx.getCurrentProcessingTime() + this.interval; Long timeoutTimestamp = timeoutState.value(); if (timeoutTimestamp != null && resetTimerOnNewRecord) { ctx.deleteProcessingTimeTimer(timeoutTimestamp); timeoutState.clear(); timeoutTimestamp = null; } if (timeoutTimestamp == null) { timeoutState.update(nextFireTimestamp); ctx.registerProcessingTimeTimer(nextFireTimestamp); } return triggerResult; } @Override public TriggerResult onProcessingTime(long timestamp, W window, TriggerContext ctx) throws Exception { TriggerResult triggerResult = this.nestedTrigger.onProcessingTime(timestamp, window, ctx); if (shouldClearOnTimeout) { this.clear(window, ctx); } return triggerResult.isPurge() ? TriggerResult.FIRE_AND_PURGE : TriggerResult.FIRE; } @Override public TriggerResult onEventTime(long timestamp, W window, TriggerContext ctx) throws Exception { TriggerResult triggerResult = this.nestedTrigger.onEventTime(timestamp, window, ctx); if (shouldClearOnTimeout) { this.clear(window, ctx); } return triggerResult.isPurge() ? TriggerResult.FIRE_AND_PURGE : TriggerResult.FIRE; } @Override public void clear(W window, TriggerContext ctx) throws Exception { ValueState timeoutTimestampState = ctx.getPartitionedState(this.timeoutStateDesc); Long timeoutTimestamp = timeoutTimestampState.value(); if (timeoutTimestamp != null) { ctx.deleteProcessingTimeTimer(timeoutTimestamp); timeoutTimestampState.clear(); } this.nestedTrigger.clear(window, ctx); } @Override public String toString() { return "TimeoutTrigger(" + this.nestedTrigger.toString() + ")"; } /** * Creates a new {@link ProcessingTimeoutTrigger} that fires when the inner trigger is fired or * when the timeout timer fires. * *

For example: {@code ProcessingTimeoutTrigger.of(CountTrigger.of(3), 100)}, will create a * CountTrigger with timeout of 100 millis. So, if the first record arrives at time {@code t}, * and the second record arrives at time {@code t+50 }, the trigger will fire when the third * record arrives or when the time is {code t+100} (timeout). * * @param nestedTrigger the nested {@link Trigger} * @param timeout the timeout interval * @return {@link ProcessingTimeoutTrigger} with the above configuration. */ public static ProcessingTimeoutTrigger of( Trigger nestedTrigger, Duration timeout) { return new ProcessingTimeoutTrigger<>(nestedTrigger, timeout.toMillis(), false, true); } /** * Creates a new {@link ProcessingTimeoutTrigger} that fires when the inner trigger is fired or * when the timeout timer fires. * *

For example: {@code ProcessingTimeoutTrigger.of(CountTrigger.of(3), 100, false, true)}, * will create a CountTrigger with timeout of 100 millis. So, if the first record arrives at * time {@code t}, and the second record arrives at time {@code t+50 }, the trigger will fire * when the third record arrives or when the time is {code t+100} (timeout). * * @param nestedTrigger the nested {@link Trigger} * @param timeout the timeout interval * @param resetTimerOnNewRecord each time a new element arrives, reset the timer and start a new * one * @param shouldClearOnTimeout whether to call {@link Trigger#clear(Window, TriggerContext)} * when the processing-time timer fires * @param The type of the element. * @param The type of {@link Window Windows} on which this trigger can operate. * @return {@link ProcessingTimeoutTrigger} with the above configuration. */ public static ProcessingTimeoutTrigger of( Trigger nestedTrigger, Duration timeout, boolean resetTimerOnNewRecord, boolean shouldClearOnTimeout) { return new ProcessingTimeoutTrigger<>( nestedTrigger, timeout.toMillis(), resetTimerOnNewRecord, shouldClearOnTimeout); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy