Skip to content

refactor: Make shard spec collector an interface for extensibility#19689

Open
abhishekrb19 wants to merge 5 commits into
apache:masterfrom
abhishekrb19:streaming-shardspec-collector-interface-refactor
Open

refactor: Make shard spec collector an interface for extensibility#19689
abhishekrb19 wants to merge 5 commits into
apache:masterfrom
abhishekrb19:streaming-shardspec-collector-interface-refactor

Conversation

@abhishekrb19

Copy link
Copy Markdown
Contributor

This is a follow-up to #19571. This patch addresses this review comment #19571 (comment) by refactoring the logic into an interface so it's extensible and maintainable. No other functional change.

New abstractions (2 interfaces + 2 impls)

  • StreamingPartitionsSpec — was a concrete class, now a polymorphic Jackson interface (@JsonTypeInfo with type property, defaultImpl = DimensionValueSetPartitionsSpec). Its only method is createCollector() for now.
  • DimensionValueSetPartitionsSpec (type: "dim_value_set") — the built-in impl holding the old fields (partitionDimensions, maxValuesPerDimension, validation, equals/hashCode/toString). createCollector() returns null when there are no
    dimensions (disabled by default), otherwise a DimensionValueSetCollector.
  • StreamingShardSpecCollector — new interface defining the per-task lifecycle required for stamping the shard specs: collect(segmentId, row) (run-loop, per row), onSegmentsRestored(segmentIds) (startup, disables pruning for restart-spanned segments), annotate(segment) (publish-time stamping), onSegmentPublished(segmentId).
  • DimensionValueSetCollector — the concrete collector holding the state that used to live in the runner (observedPartitionDimValuesBySegment ConcurrentHashMap, restartSpannedSegments set) and all the value-recording, capping, sorting, null-handling, and stamping logic.

This PR has:

  • been self-reviewed.
  • added documentation for new or modified features or behaviors.
  • a release note entry in the PR description.
  • added Javadocs for most classes and all non-trivial methods. Linked related entities via Javadoc links.
  • added comments explaining the "why" and the intent of the code wherever would not be obvious for an unfamiliar reader.
  • added unit tests or modified existing tests to cover new code paths, ensuring the threshold for code coverage is met.
  • been tested in a test Druid cluster.

@jtuglu1

jtuglu1 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Should this go in v38?

@jtuglu1 jtuglu1 added this to the 38.0.0 milestone Jul 15, 2026
@jtuglu1
jtuglu1 self-requested a review July 15, 2026 15:36
// Over-cap: omit this dim from the stamped filter map (still a DimensionValueSetShardSpec for
// class-uniformity; possibleInDomain treats an absent dim as unconstrained, so pruning is disabled
// for it on this segment).
if (maxValuesPerDimension != null && vals.size() > maxValuesPerDimension) {

@jtuglu1 jtuglu1 Jul 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

future: I wonder if it's worth somehow making this exclusion condition dependent on the frequency of the column values? For example, keeping the best – those which have highest chance of reducing read amplification – pruning column values in the shard spec?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it's worth somehow making this exclusion condition dependent on the frequency of the column values?

Yes, frequency-based should be possible. I think it'd either require introducing a mode into this existing shard type or adding a new shard spec altogether (that resembles a bloom value set use case).

@FrankChen021 FrankChen021 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity Findings
P0 0
P1 0
P2 1
P3 0
Total 1
Severity Findings
P0 0
P1 0
P2 1
P3 0
Total 1

Reviewed 10 of 10 changed files.

Found one polymorphic-deserialization issue: an explicit unknown streaming partition type silently falls back to the built-in strategy instead of failing.


This is an automated review by Codex GPT-5.6-Sol

@FrankChen021 FrankChen021 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reviewed the updated code for correctness, edge cases, concurrency, and integration risks; no issues found. The incremental fix rejects explicit unknown type IDs while preserving the omitted-type default.

Reviewed 10 of 10 changed files.


This is an automated review by Codex GPT-5.6-Sol

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants