aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorAndrew Or <andrew@databricks.com>2015-03-25 13:28:32 -0700
committerAndrew Or <andrew@databricks.com>2015-03-25 13:28:32 -0700
commitc1b74df6042b33b2b061cb07c2fbd82dba9074bb (patch)
treed35c54daae8f4592fd934990fc9207c377d3cf4a /core
parentacef51defb991bcdc99b76cf2a126afd6d60ec70 (diff)
downloadspark-c1b74df6042b33b2b061cb07c2fbd82dba9074bb.tar.gz
spark-c1b74df6042b33b2b061cb07c2fbd82dba9074bb.tar.bz2
spark-c1b74df6042b33b2b061cb07c2fbd82dba9074bb.zip
[SPARK-5771] Master UI inconsistently displays application cores
If the user calls `sc.stop()`, then the number of cores under "Completed Applications" will be 0. If the user does not call `sc.stop()`, then the number of cores will be however many cores were being used before the application exited. This PR makes both cases have the behavior of the latter. Note that there have been a series of PR that attempted to fix this. For the full discussion, please refer to #4841. The unregister event is necessary because of a subtle race condition explained in that PR. Tested this locally with and without calling `sc.stop()`. Author: Andrew Or <andrew@databricks.com> Closes #5177 from andrewor14/master-ui-cores and squashes the following commits: 62449d1 [Andrew Or] Freeze application state before finishing it
Diffstat (limited to 'core')
-rw-r--r--core/src/main/scala/org/apache/spark/deploy/DeployMessage.scala2
-rw-r--r--core/src/main/scala/org/apache/spark/deploy/client/AppClient.scala1
-rw-r--r--core/src/main/scala/org/apache/spark/deploy/master/ApplicationInfo.scala4
-rw-r--r--core/src/main/scala/org/apache/spark/deploy/master/Master.scala10
4 files changed, 16 insertions, 1 deletions
diff --git a/core/src/main/scala/org/apache/spark/deploy/DeployMessage.scala b/core/src/main/scala/org/apache/spark/deploy/DeployMessage.scala
index 0997507d01..9db6fd1ac4 100644
--- a/core/src/main/scala/org/apache/spark/deploy/DeployMessage.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/DeployMessage.scala
@@ -101,6 +101,8 @@ private[deploy] object DeployMessages {
case class RegisterApplication(appDescription: ApplicationDescription)
extends DeployMessage
+ case class UnregisterApplication(appId: String)
+
case class MasterChangeAcknowledged(appId: String)
// Master to AppClient
diff --git a/core/src/main/scala/org/apache/spark/deploy/client/AppClient.scala b/core/src/main/scala/org/apache/spark/deploy/client/AppClient.scala
index 3b72972525..4f06d7f96c 100644
--- a/core/src/main/scala/org/apache/spark/deploy/client/AppClient.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/client/AppClient.scala
@@ -157,6 +157,7 @@ private[spark] class AppClient(
case StopAppClient =>
markDead("Application has been stopped.")
+ master ! UnregisterApplication(appId)
sender ! true
context.stop(self)
}
diff --git a/core/src/main/scala/org/apache/spark/deploy/master/ApplicationInfo.scala b/core/src/main/scala/org/apache/spark/deploy/master/ApplicationInfo.scala
index f979ffa166..bc5b293379 100644
--- a/core/src/main/scala/org/apache/spark/deploy/master/ApplicationInfo.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/master/ApplicationInfo.scala
@@ -111,6 +111,10 @@ private[deploy] class ApplicationInfo(
endTime = System.currentTimeMillis()
}
+ private[master] def isFinished: Boolean = {
+ state != ApplicationState.WAITING && state != ApplicationState.RUNNING
+ }
+
def duration: Long = {
if (endTime != -1) {
endTime - startTime
diff --git a/core/src/main/scala/org/apache/spark/deploy/master/Master.scala b/core/src/main/scala/org/apache/spark/deploy/master/Master.scala
index 80506621f4..9a5d5877da 100644
--- a/core/src/main/scala/org/apache/spark/deploy/master/Master.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/master/Master.scala
@@ -339,7 +339,11 @@ private[master] class Master(
if (ExecutorState.isFinished(state)) {
// Remove this executor from the worker and app
logInfo(s"Removing executor ${exec.fullId} because it is $state")
- appInfo.removeExecutor(exec)
+ // If an application has already finished, preserve its
+ // state to display its information properly on the UI
+ if (!appInfo.isFinished) {
+ appInfo.removeExecutor(exec)
+ }
exec.worker.removeExecutor(exec)
val normalExit = exitStatus == Some(0)
@@ -428,6 +432,10 @@ private[master] class Master(
if (canCompleteRecovery) { completeRecovery() }
}
+ case UnregisterApplication(applicationId) =>
+ logInfo(s"Received unregister request from application $applicationId")
+ idToApp.get(applicationId).foreach(finishApplication)
+
case DisassociatedEvent(_, address, _) => {
// The disconnected client could've been either a worker or an app; remove whichever it was
logInfo(s"$address got disassociated, removing it.")