Flink 自定义Trigger实现带超时时间的计数窗口

// 时间推进是必然发生的, 而数量是可能积攒不够的, 所以用数量约束时间窗口
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
  }
}

你可能感兴趣的:(flink,trigger)