zsxwing opened a new pull request, #59265:
URL: https://github.com/apache/spark/pull/59265
### What changes were proposed in this pull request?
The Download button on the executor thread dump page inlines the whole dump
into a `data:` URI `href`:
```scala
href={"data:text/plain;charset=utf-8," + threadDump.map(_.toString).mkString}
```
This PR stops putting the dump in a URL. Like the SQL plan Download button
(`downloadPlanBlob` in `spark-sql-viz.js`), the button now builds the file in
the browser:
- `ExecutorThreadDumpPage` renders the Download link without an `href`
(`data-action="downloadThreadDump"`, `data-filename=...`) and embeds the dump,
unchanged, in a hidden `<pre id="thread-dump-text" class="d-none">`.
- `table.js` gets a `downloadThreadDump` function that builds a `Blob` from
that element and downloads it, wired through the same delegated `data-action`
listeners as Expand All / Collapse All.
A new internal config, `spark.ui.threadDump.downloadInBrowser.enabled`
(default `true`), is a kill switch. When it is `false`, the page renders the
original `data:` URI link.
### Why are the changes needed?
When a browser materializes a `data:` URI download, it excludes the URL
fragment (everything from the first `#`) before decoding the body. See step 2
of the WHATWG "data: URL processor":
https://url.spec.whatwg.org/#data-url-processor. Chromium
(`GURL::GetContentPiece`) and Firefox (`nsDataHandler::ParseURI`) both
implement this.
Since https://github.com/apache/spark/pull/53634 (SPARK-54861), idle task
threads are named `Executor task idle worker#<threadId>`, so nearly every
executor thread dump contains a `#`. The downloaded file is silently truncated
at the first such thread, losing it and every thread after it.
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
No automated test: the download is a browser-side `Blob` click, which the
HtmlUnit driver used by `UISeleniumSuite` cannot run, and
`ChromeUISeleniumSuite` is `@Ignore`d.
Manual test:
1. Start `bin/spark-shell --master 'local-cluster[2,1,1024]'`.
2. Run `spark.range(10).repartition(20).show()` so the executors have idle
task threads (`Executor task idle worker#N`).
3. Open the Executors tab, click Thread Dump for an executor, then click
Download.
4. The saved `threaddump_<executorId>.txt` contains every thread on the
page, including the `Executor task idle worker#N` threads and their stack
traces.
5. Set `spark.ui.threadDump.downloadInBrowser.enabled=false` and repeat: the
old `data:` link is rendered.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Claude Opus 5.5)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]