stream.timeWindowAll(Time.seconds(10L))
.trigger(CountTimeoutTrigger(100L,TimeCharacteristic.ProcessingTime))
import org.apache.flink.api.common.functions.ReduceFunction
import org.apache.flink.api.common.state.ReducingStateDescriptor
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.windowing.triggers.{Trigger, TriggerResult}
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
case class CountTimeoutTrigger[W <: TimeWindow](maxSize: Long, timeType: TimeCharacteristic) extends Trigger[AnyRef, W] {
val timeDescriptor = new ReducingStateDescriptor("max-size", new Sum(), classOf[Long])
override def onEventTime(time: Long, window: W, ctx: Trigger.TriggerContext): TriggerResult = {
if (timeType == TimeCharacteristic.EventTime) {
if (window.getEnd >= time) {
fireAndPurge(window, ctx)
} else {
TriggerResult.CONTINUE
}
} else TriggerResult.CONTINUE
}
override def onProcessingTime(time: Long, window: W, ctx: Trigger.TriggerContext): TriggerResult = {
if (timeType == TimeCharacteristic.ProcessingTime) {
if (window.getEnd >= time) {
fireAndPurge(window, ctx)
} else {
TriggerResult.CONTINUE
}
} else TriggerResult.CONTINUE
}
override def onElement(element: AnyRef, timestamp: Long, window: W, ctx: Trigger.TriggerContext): TriggerResult = {
val timeState = ctx.getPartitionedState(timeDescriptor)
timeState.add(1L)
if (timeState.get() >= maxSize) {
fireAndPurge(window, ctx)
} else {
TriggerResult.CONTINUE
}
}
def fireAndPurge(window: W, ctx: Trigger.TriggerContext): TriggerResult = {
clear(window, ctx)
TriggerResult.FIRE_AND_PURGE
}
override def clear(window: W, ctx: Trigger.TriggerContext): Unit = {
ctx.getPartitionedState(timeDescriptor).clear()
}
class Sum extends ReduceFunction[Long] {
override def reduce(value1: Long, value2: Long): Long = value1 + value2
}
}