This is an automated email from the ASF dual-hosted git repository.
csy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/auron.git
The following commit(s) were added to refs/heads/master by this push:
new 04b48c31 [AURON #2011] History Server fails when BuildInfo event is
missing. (#2012)
04b48c31 is described below
commit 04b48c31371d795763bc436c6e83d2a0e44ab49c
Author: slfan1989 <[email protected]>
AuthorDate: Tue Mar 3 14:31:48 2026 +0800
[AURON #2011] History Server fails when BuildInfo event is missing. (#2012)
### Which issue does this PR close?
Closes #2011
### Rationale for this change
The History Server plugin currently crashes during initialization when
the `AuronBuildInfoUIData` record is missing from the KVStore. This
causes applications without BuildInfo events to either fail plugin
initialization or show no Auron tab.
### What changes are included in this PR?
1. **AuronSQLAppStatusStore**: Changed `buildInfo()` to return
`Option[AuronBuildInfoUIData]`, catching `NoSuchElementException` and
other exceptions to return `None` instead of throwing
2. **AuronSQLHistoryServerPlugin**: Removed the null check and always
create the Auron tab, letting the UI handle empty state
3. **AuronAllExecutionsPage**: Added `buildInfoSummary()` method to
handle `Option[AuronBuildInfoUIData]`:
- `Some`: displays BuildInfo table as before
- `None`: shows user-friendly message "Auron build information is not
available for this application."
### Are there any user-facing changes?
Yes. When BuildInfo is not available:
- Before: Plugin initialization fails or no Auron tab appears
- After: Auron tab displays with a clear warning message explaining
BuildInfo is unavailable
### How was this patch tested?
- Existing unit tests pass
Signed-off-by: slfan1989 <[email protected]>
---
.../sql/execution/ui/AuronAllExecutionsPage.scala | 74 ++++++++++------------
.../sql/execution/ui/AuronSQLAppStatusStore.scala | 17 ++++-
.../execution/ui/AuronSQLHistoryServerPlugin.scala | 4 +-
3 files changed, 47 insertions(+), 48 deletions(-)
diff --git
a/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronAllExecutionsPage.scala
b/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronAllExecutionsPage.scala
index 56f96d95..840abca6 100644
---
a/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronAllExecutionsPage.scala
+++
b/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronAllExecutionsPage.scala
@@ -29,52 +29,12 @@ private[ui] class AuronAllExecutionsPage(parent:
AuronSQLTab) extends WebUIPage(
@sparkver("3.0 / 3.1 / 3.2 / 3.3 / 3.4 / 3.5")
override def render(request: javax.servlet.http.HttpServletRequest):
Seq[Node] = {
- val buildInfo = sqlStore.buildInfo()
- val infos =
- UIUtils.listingTable(propertyHeader, propertyRow, buildInfo.info,
fixedWidth = true)
- val summary: NodeSeq =
- <div>
- <div>
- <span class="collapse-sql-properties collapse-table"
- onClick="collapseTable('collapse-sql-properties',
'sql-properties')">
- <h4>
- <span class="collapse-table-arrow arrow-open"></span>
- <a>Auron Build Information</a>
- </h4>
- </span>
- <div class="sql-properties collapsible-table">
- {infos}
- </div>
- </div>
- <br/>
- </div>
-
- UIUtils.headerSparkPage(request, "Auron", summary, parent)
+ UIUtils.headerSparkPage(request, "Auron",
buildInfoSummary(sqlStore.buildInfo()), parent)
}
@sparkver("4.0 / 4.1")
override def render(request: jakarta.servlet.http.HttpServletRequest):
Seq[Node] = {
- val buildInfo = sqlStore.buildInfo()
- val infos =
- UIUtils.listingTable(propertyHeader, propertyRow, buildInfo.info,
fixedWidth = true)
- val summary: NodeSeq =
- <div>
- <div>
- <span class="collapse-sql-properties collapse-table"
- onClick="collapseTable('collapse-sql-properties',
'sql-properties')">
- <h4>
- <span class="collapse-table-arrow arrow-open"></span>
- <a>Auron Build Information</a>
- </h4>
- </span>
- <div class="sql-properties collapsible-table">
- {infos}
- </div>
- </div>
- <br/>
- </div>
-
- UIUtils.headerSparkPage(request, "Auron", summary, parent)
+ UIUtils.headerSparkPage(request, "Auron",
buildInfoSummary(sqlStore.buildInfo()), parent)
}
private def propertyHeader = Seq("Name", "Value")
@@ -87,4 +47,34 @@ private[ui] class AuronAllExecutionsPage(parent:
AuronSQLTab) extends WebUIPage(
</td>
</tr>
+ private def buildInfoSummary(buildInfoOpt: Option[AuronBuildInfoUIData]):
NodeSeq = {
+ buildInfoOpt match {
+ case Some(buildInfo) =>
+ val infos =
+ UIUtils.listingTable(propertyHeader, propertyRow, buildInfo.info,
fixedWidth = true)
+ <div>
+ <div>
+ <span class="collapse-sql-properties collapse-table"
+ onClick="collapseTable('collapse-sql-properties',
'sql-properties')">
+ <h4>
+ <span class="collapse-table-arrow arrow-open"></span>
+ <a>Auron Build Information</a>
+ </h4>
+ </span>
+ <div class="sql-properties collapsible-table">
+ {infos}
+ </div>
+ </div>
+ <br/>
+ </div>
+ case None =>
+ // Show a friendly empty state instead of failing or rendering a blank
page.
+ <div>
+ <div class="alert alert-warning">
+ Auron build information is not available for this application.
+ </div>
+ </div>
+ }
+ }
+
}
diff --git
a/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronSQLAppStatusStore.scala
b/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronSQLAppStatusStore.scala
index 3fc4beb6..0c44644f 100644
---
a/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronSQLAppStatusStore.scala
+++
b/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronSQLAppStatusStore.scala
@@ -16,14 +16,25 @@
*/
package org.apache.spark.sql.execution.ui
+import scala.util.control.NonFatal
+
import com.fasterxml.jackson.annotation.JsonIgnore
+import org.apache.spark.internal.Logging
import org.apache.spark.util.kvstore.{KVIndex, KVStore}
-class AuronSQLAppStatusStore(store: KVStore) {
+class AuronSQLAppStatusStore(store: KVStore) extends Logging {
- def buildInfo(): AuronBuildInfoUIData = {
+ def buildInfo(): Option[AuronBuildInfoUIData] = {
val kClass = classOf[AuronBuildInfoUIData]
- store.read(kClass, kClass.getName)
+ // KVStore throws when the record doesn't exist; treat missing data as "no
build info".
+ try {
+ Option(store.read(kClass, kClass.getName))
+ } catch {
+ case _: NoSuchElementException => None
+ case NonFatal(e) =>
+ logWarning("Failed to read BuildInfo from KVStore", e)
+ None
+ }
}
}
diff --git
a/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronSQLHistoryServerPlugin.scala
b/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronSQLHistoryServerPlugin.scala
index 3ea7b5ad..5628d9c4 100644
---
a/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronSQLHistoryServerPlugin.scala
+++
b/auron-spark-ui/src/main/scala/org/apache/spark/sql/execution/ui/AuronSQLHistoryServerPlugin.scala
@@ -31,9 +31,7 @@ class AuronSQLHistoryServerPlugin extends
AppHistoryServerPlugin {
override def setupUI(ui: SparkUI): Unit = {
val sqlStatusStore = new AuronSQLAppStatusStore(ui.store.store)
- if (sqlStatusStore.buildInfo() != null) {
- new AuronSQLTab(sqlStatusStore, ui)
- }
+ new AuronSQLTab(sqlStatusStore, ui)
}
override def displayOrder: Int = 0