Repository navigation
Conversation
CometExecIterator looked up TaskContext.get() on every batch. A consumer that reads a partition's iterator on a thread of its own, such as the ClickHouse RowBinary writer that streams rows from its client's thread, saw a null context there and failed with a NullPointerException on the first batch. The ClickHouse client dropped that failure, so every insert of a Comet plan's output wrote no rows. Capture the task's context when the iterator is built, on the task thread, and use it for every batch. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
CometExecIterator.getNextBatchcalledTaskContext.get()on every batch. When a consumer reads a partition's iterator on its own thread,TaskContext.get()returns null there, and the first batch fails with aNullPointerExceptioninCometTaskContextShim.killTaskIfInterrupted.The datasci ClickHouse RowBinary writer is one such consumer:
insertRowsRowBinaryreads the rows insideClickHouseWriter.write, and the ClickHouse client calls that on its own thread. The client swallowed the NPE, so each insert wrote 0 rows while the Spark task still succeeded. This happened to platform.app-performance and platform.published_product_current on the night of 2026-10-15 (joom-1.1-10):Expected count is 1309796, actual 0. The job that counted partition sizes read every row because it ran on the task thread. The shuffle blocks were fetched (fetching starts incompute, on the task thread), but 0 records were decoded.Vanilla Spark handles this case. apache/main has the same per-batch
TaskContext.get().Fix
Capture the task's
TaskContextonce, in the iterator's constructor, which always runs on the task thread. Use that captured context everywhere the iterator needs one:getNextBatch, the kill watch, the completion listener andcreatePlan.Tests
CometOffTaskThreadSuite(added to the exec CI group). It covers a reused native or JVM Comet shuffle with AQE on and off, using the same pattern as the ClickHouse writer:repartitionByRange→.rdd→ a sizes job →runJobon single partitions from a thread pool, with each partition's iterator read on a new thread. It also covers a native scan read on a foreign thread. Without the fix all 5 tests fail with the NPE; with the fix all 5 pass.🤖 Generated with Claude Code