Skip to content

[FLINK-40172][table-runtime] Support processing-time early fire on a row-time interval join - #5

Draft
weiqingy wants to merge 1 commit into
FLINK-36953-pr4-runtimefrom
FLINK-36953-pr5-proctime
Draft

[FLINK-40172][table-runtime] Support processing-time early fire on a row-time interval join#5
weiqingy wants to merge 1 commit into
FLINK-36953-pr4-runtimefrom
FLINK-36953-pr5-proctime

Conversation

@weiqingy

@weiqingy weiqingy commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Part of the FLIP-497 stack under umbrella FLINK-36953. Stacked on PR-4. Landing order: PR-1a → PR-1b → PR-2 → PR-3 → PR-4 → PR-5 (this) → PR-6 → PR-7.

What is the purpose of the change

Allows an event-time interval join to early-fire on processing time (time-mode='proctime'). This is the cross-domain combination: the join's window is event-time, but the speculative early-fire is driven by wall-clock timers. The PR removes the temporary "not yet supported" rejection added earlier in the stack.

Brief change log

  • Add a domain-aware processing-time early-fire timer path so an event-time join can register wall-clock early-fire timers; bookkeeping state distinguishes early fires from event-time cleanup.
  • Drop the StreamPhysicalIntervalJoinRule rejection of proctime triggering on a row-time join.

Verifying this change

This change added tests and can be verified as follows:

  • Added a processing-time replayability harness test (snapshot → restore → assert no duplicate/lost early fires) and extended RowTimeIntervalJoinTest; the IntervalJoinTest proctime-on-rowtime case now plans successfully.

Does this pull request potentially affect one of the following parts:

  • Dependencies (does it add or upgrade a dependency): no
  • The public API, i.e., is any changed class annotated with @Public(Evolving): no
  • The serializers: no
  • The runtime per-record code paths (performance sensitive): yes — interval join operator timer/record path (behavior gated on the hint; default off)
  • Anything that affects deployment or recovery: yes — the operator's early-fire bookkeeping state is snapshotted/restored (covered by the new replay test)
  • The S3 file system connector: no

Documentation

  • Does this pull request introduce a new feature? no (runtime for the FLIP-497 hint)
  • If yes, how is the feature documented? not applicable

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude Code (Anthropic)

@weiqingy
weiqingy force-pushed the FLINK-36953-pr5-proctime branch from 11edb43 to 8635ad0 Compare July 18, 2026 22:12
@weiqingy
weiqingy force-pushed the FLINK-36953-pr4-runtime branch from a56a787 to fcb8e67 Compare July 18, 2026 22:12
@weiqingy weiqingy changed the title [FLINK-36953][table-runtime] Support processing-time early fire on a row-time interval join [FLINK-40172][table-runtime] Support processing-time early fire on a row-time interval join Jul 18, 2026
@weiqingy
weiqingy force-pushed the FLINK-36953-pr4-runtime branch from fcb8e67 to 72e92e5 Compare July 21, 2026 02:17
@weiqingy
weiqingy force-pushed the FLINK-36953-pr5-proctime branch from 8635ad0 to 23aabdc Compare July 21, 2026 02:17
… interval join

Add the cross-domain timer combination the previous commit left out: an
event-time interval join with EARLY_FIRE('time_mode'='proctime') now fires its
speculative pads on the wall clock while keeping its event-time cleanup. The
temporary "not yet supported" rejection in the planner rule is removed; the
row-time-on-processing-time rejection is retained.

onTimer distinguishes the two timer kinds by OnTimerContext.timeDomain(): in
the cross-domain case early-fire timers are processing-time and cleanup timers
are event-time, so a processing-time firing runs early fire and returns while
an event-time firing runs cleanup only. The discrimination is gated on a new
cross-domain flag, so the natural pairings keep the previous timestamp - delay
recovery where early fire and cleanup share a domain.

A processing-time firing timestamp cannot be mapped back to an event-time cache
bucket arithmetically, so a per-side MapState<Long, List<Long>> keyed by firing
processing-time records the event-time bucket keys due to fire then. It is
allocated only in the cross-domain case and reuses the existing per-bucket emit
and positional fired bit, so the retract-and-correct path is shared. Every
scheduled firing time fires and removes its own entry, and a bucket already
cleaned by event-time expiry makes the firing a no-op, so nothing accumulates.

The schedule is value-typed and order-preserving and processing-time timers are
checkpointed, so a timer pending at snapshot fires after restore against the
restored schedule and fired bits and emits at most the not-yet-emitted pad.
Harness tests cover the wall-clock trigger without watermark advance, a snapshot
before the timer fires, and a snapshot after the pad is emitted.
@weiqingy
weiqingy force-pushed the FLINK-36953-pr4-runtime branch from 72e92e5 to ebe6e95 Compare July 21, 2026 04:43
@weiqingy
weiqingy force-pushed the FLINK-36953-pr5-proctime branch from 23aabdc to 67c13cc Compare July 21, 2026 04:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant