-
Notifications
You must be signed in to change notification settings - Fork 3.8k
fix: stabilize task queue and ingestion CI tests #20291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
d79b373
ed18502
6fffd7c
ee5d92b
c07901c
c88b84c
be79add
d54e6c1
6469442
a59f5f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -251,11 +251,11 @@ public void refresh(final Set<SegmentId> segmentsToRefresh, final Set<String> da | |
| final RowSignature rowSignature = buildDataSourceRowSignature(dataSource); | ||
| if (rowSignature == null) { | ||
| log.info("datasource [%s] no longer exists, all metadata removed.", dataSource); | ||
| tables.remove(dataSource); | ||
| emitMetric( | ||
| Metric.DATASOURCE_REMOVED, | ||
| 1, | ||
| ServiceMetricEvent.builder().setDimension(DruidMetrics.DATASOURCE, dataSource)); | ||
| // The last-segment callback may already have removed the table and emitted the metric while this refresh | ||
| // was in flight. Only emit if this refresh is the one that actually removed the table. | ||
| if (tables.remove(dataSource) != null) { | ||
| emitDataSourceRemoved(dataSource); | ||
| } | ||
| continue; | ||
| } | ||
|
|
||
|
|
@@ -264,12 +264,11 @@ public void refresh(final Set<SegmentId> segmentsToRefresh, final Set<String> da | |
| // and a new datasource is added | ||
| log.info("datasource [%s] schema has not been initialized yet, " | ||
| + "check coordinator logs if this message is persistent.", dataSource); | ||
| // this is a harmless call | ||
| tables.remove(dataSource); | ||
| emitMetric( | ||
| Metric.DATASOURCE_REMOVED, | ||
| 1, | ||
| ServiceMetricEvent.builder().setDimension(DruidMetrics.DATASOURCE, dataSource)); | ||
| // Usually there is no table to remove here. If there was one, a concurrent last-segment callback may have | ||
| // removed it and emitted the metric already, so only emit if this refresh actually removed the table. | ||
| if (tables.remove(dataSource) != null) { | ||
| emitDataSourceRemoved(dataSource); | ||
| } | ||
| continue; | ||
| } | ||
|
|
||
|
|
@@ -307,6 +306,22 @@ protected void removeSegmentAction(SegmentId segmentId) | |
| // noop, no additional action needed when segment is removed. | ||
| } | ||
|
|
||
| @Override | ||
| protected void removeDataSourceAction(String dataSource) | ||
| { | ||
| // The last-segment callback can remove the table without another schema refresh. | ||
| emitDataSourceRemoved(dataSource); | ||
| } | ||
|
|
||
| private void emitDataSourceRemoved(String dataSource) | ||
| { | ||
| emitMetric( | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P2] Avoid duplicate removal metrics during concurrent refresh This callback can race with BrokerSegmentMetadataCache.refresh(): refresh drains a datasource into its local dataSourcesToRebuild set and clears the guarded set before rebuilding outside the lock, then a concurrent last-segment callback emits DATASOURCE_REMOVED here. The in-flight refresh still processes that local datasource (and can emit DATASOURCE_REMOVED again when its row signature is null), so one removal can produce duplicate metrics. The synchronous regression test only verifies that a later refresh does not use stale state; please coordinate or re-check in-flight rebuilds before emitting/rebuilding. |
||
| Metric.DATASOURCE_REMOVED, | ||
| 1, | ||
| ServiceMetricEvent.builder().setDimension(DruidMetrics.DATASOURCE, dataSource) | ||
| ); | ||
| } | ||
|
|
||
| private Set<String> queryDataSources() | ||
| { | ||
| Set<String> dataSources = new HashSet<>(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P2] Prevent duplicate removal metrics from in-flight refresh
This clears only the shared
dataSourcesNeedingRebuildset. A cache refresh can already have copied that datasource into its localdataSourcesToRebuildset at the end ofBrokerSegmentMetadataCache.refreshbefore this callback removes the last segment. The callback then emitsDATASOURCE_REMOVED, but the same refresh still builds the now-empty datasource and emitsDATASOURCE_REMOVEDagain. Coordinate this cleanup with the in-flight refresh (or make the removal emission idempotent), and cover the callback/refresh interleaving so one removal is counted once.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 6469442. Rather than coordinating with the in-flight refresh, the metric emission is now idempotent: both
removeSegmentand the null-signature branch ofrefreshemitdataSource/removedonly when their owntables.remove(dataSource)returned a non-null value. Sincetablesis aConcurrentHashMap, exactly one of the two paths wins the remove and emits; the other seesnulland stays silent, in either interleaving. The callback still never touches the refresh thread's localdataSourcesToRebuildset, and no lock is held across metadata queries.Test coverage:
testLastSegmentRemovalClearsRebuildStatenow also runs a refresh that is handed the datasource explicitly after the last segment is gone (simulating a refresh that captured it before the removal) and asserts the metric count stays at 1. A newtestRefreshOfUnknownDatasourceDoesNotEmitRemovalMetriccovers a datasource that never had a table. Both fail on the previous revision (expected: <1> but was: <2>/expected: <0> but was: <1>) and pass now.The separate table-resurrection race (refresh re-inserting a table after the last segment was removed) is pre-existing on master and not addressed here; I will file it as a follow-up.