1717
1818package org .apache .spark .deploy .master
1919
20- import java .io .FileNotFoundException
21- import java .net .URLEncoder
2220import java .text .SimpleDateFormat
2321import java .util .Date
24- import java .util .concurrent .{ConcurrentHashMap , ScheduledFuture , TimeUnit }
22+ import java .util .concurrent .{ScheduledFuture , TimeUnit }
2523
2624import scala .collection .mutable .{ArrayBuffer , HashMap , HashSet }
27- import scala .concurrent .{ExecutionContext , Future }
28- import scala .concurrent .duration .Duration
29- import scala .language .postfixOps
3025import scala .util .Random
3126
32- import org .apache .hadoop .fs .Path
33-
3427import org .apache .spark .{SecurityManager , SparkConf , SparkException }
3528import org .apache .spark .deploy .{ApplicationDescription , DriverDescription ,
3629 ExecutorState , SparkHadoopUtil }
3730import org .apache .spark .deploy .DeployMessages ._
38- import org .apache .spark .deploy .history .HistoryServer
3931import org .apache .spark .deploy .master .DriverState .DriverState
4032import org .apache .spark .deploy .master .MasterMessages ._
4133import org .apache .spark .deploy .master .ui .MasterWebUI
4234import org .apache .spark .deploy .rest .StandaloneRestServer
4335import org .apache .spark .internal .Logging
4436import org .apache .spark .metrics .MetricsSystem
4537import org .apache .spark .rpc ._
46- import org .apache .spark .scheduler .{EventLoggingListener , ReplayListenerBus }
4738import org .apache .spark .serializer .{JavaSerializer , Serializer }
48- import org .apache .spark .ui .SparkUI
4939import org .apache .spark .util .{ThreadUtils , Utils }
5040
5141private [deploy] class Master (
@@ -59,10 +49,6 @@ private[deploy] class Master(
5949 private val forwardMessageThread =
6050 ThreadUtils .newDaemonSingleThreadScheduledExecutor(" master-forward-message-thread" )
6151
62- private val rebuildUIThread =
63- ThreadUtils .newDaemonSingleThreadExecutor(" master-rebuild-ui-thread" )
64- private val rebuildUIContext = ExecutionContext .fromExecutor(rebuildUIThread)
65-
6652 private val hadoopConf = SparkHadoopUtil .get.newConfiguration(conf)
6753
6854 private def createDateFormat = new SimpleDateFormat (" yyyyMMddHHmmss" ) // For application IDs
@@ -85,8 +71,6 @@ private[deploy] class Master(
8571 private val addressToApp = new HashMap [RpcAddress , ApplicationInfo ]
8672 private val completedApps = new ArrayBuffer [ApplicationInfo ]
8773 private var nextAppNumber = 0
88- // Using ConcurrentHashMap so that master-rebuild-ui-thread can add a UI after asyncRebuildUI
89- private val appIdToUI = new ConcurrentHashMap [String , SparkUI ]
9074
9175 private val drivers = new HashSet [DriverInfo ]
9276 private val completedDrivers = new ArrayBuffer [DriverInfo ]
@@ -199,7 +183,6 @@ private[deploy] class Master(
199183 checkForWorkerTimeOutTask.cancel(true )
200184 }
201185 forwardMessageThread.shutdownNow()
202- rebuildUIThread.shutdownNow()
203186 webUi.stop()
204187 restServer.foreach(_.stop())
205188 masterMetricsSystem.stop()
@@ -391,9 +374,6 @@ private[deploy] class Master(
391374 case CheckForWorkerTimeOut =>
392375 timeOutDeadWorkers()
393376
394- case AttachCompletedRebuildUI (appId) =>
395- // An asyncRebuildSparkUI has completed, so need to attach to master webUi
396- Option (appIdToUI.get(appId)).foreach { ui => webUi.attachSparkUI(ui) }
397377 }
398378
399379 override def receiveAndReply (context : RpcCallContext ): PartialFunction [Any , Unit ] = {
@@ -844,17 +824,13 @@ private[deploy] class Master(
844824 if (completedApps.size >= RETAINED_APPLICATIONS ) {
845825 val toRemove = math.max(RETAINED_APPLICATIONS / 10 , 1 )
846826 completedApps.take(toRemove).foreach { a =>
847- Option (appIdToUI.remove(a.id)).foreach { ui => webUi.detachSparkUI(ui) }
848827 applicationMetricsSystem.removeSource(a.appSource)
849828 }
850829 completedApps.trimStart(toRemove)
851830 }
852831 completedApps += app // Remember it in our history
853832 waitingApps -= app
854833
855- // If application events are logged, use them to rebuild the UI
856- asyncRebuildSparkUI(app)
857-
858834 for (exec <- app.executors.values) {
859835 killExecutor(exec)
860836 }
@@ -953,89 +929,6 @@ private[deploy] class Master(
953929 exec.state = ExecutorState .KILLED
954930 }
955931
956- /**
957- * Rebuild a new SparkUI from the given application's event logs.
958- * Return the UI if successful, else None
959- */
960- private [master] def rebuildSparkUI (app : ApplicationInfo ): Option [SparkUI ] = {
961- val futureUI = asyncRebuildSparkUI(app)
962- ThreadUtils .awaitResult(futureUI, Duration .Inf )
963- }
964-
965- /** Rebuild a new SparkUI asynchronously to not block RPC event loop */
966- private [master] def asyncRebuildSparkUI (app : ApplicationInfo ): Future [Option [SparkUI ]] = {
967- val appName = app.desc.name
968- val notFoundBasePath = HistoryServer .UI_PATH_PREFIX + " /not-found"
969- val eventLogDir = app.desc.eventLogDir
970- .getOrElse {
971- // Event logging is disabled for this application
972- app.appUIUrlAtHistoryServer = Some (notFoundBasePath)
973- return Future .successful(None )
974- }
975- val futureUI = Future {
976- val eventLogFilePrefix = EventLoggingListener .getLogPath(
977- eventLogDir, app.id, appAttemptId = None , compressionCodecName = app.desc.eventLogCodec)
978- val fs = Utils .getHadoopFileSystem(eventLogDir, hadoopConf)
979- val inProgressExists = fs.exists(new Path (eventLogFilePrefix +
980- EventLoggingListener .IN_PROGRESS ))
981-
982- val eventLogFile = if (inProgressExists) {
983- // Event logging is enabled for this application, but the application is still in progress
984- logWarning(s " Application $appName is still in progress, it may be terminated abnormally. " )
985- eventLogFilePrefix + EventLoggingListener .IN_PROGRESS
986- } else {
987- eventLogFilePrefix
988- }
989-
990- val logInput = EventLoggingListener .openEventLog(new Path (eventLogFile), fs)
991- val replayBus = new ReplayListenerBus ()
992- val ui = SparkUI .createHistoryUI(new SparkConf , replayBus, new SecurityManager (conf),
993- appName, HistoryServer .UI_PATH_PREFIX + s " / ${app.id}" , app.startTime)
994- try {
995- replayBus.replay(logInput, eventLogFile, inProgressExists)
996- } finally {
997- logInput.close()
998- }
999-
1000- Some (ui)
1001- }(rebuildUIContext)
1002-
1003- futureUI.onSuccess { case Some (ui) =>
1004- appIdToUI.put(app.id, ui)
1005- // `self` can be null if we are already in the process of shutting down
1006- // This happens frequently in tests where `local-cluster` is used
1007- if (self != null ) {
1008- self.send(AttachCompletedRebuildUI (app.id))
1009- }
1010- // Application UI is successfully rebuilt, so link the Master UI to it
1011- // NOTE - app.appUIUrlAtHistoryServer is volatile
1012- app.appUIUrlAtHistoryServer = Some (ui.basePath)
1013- }(ThreadUtils .sameThread)
1014-
1015- futureUI.onFailure {
1016- case fnf : FileNotFoundException =>
1017- // Event logging is enabled for this application, but no event logs are found
1018- val title = s " Application history not found ( ${app.id}) "
1019- var msg = s " No event logs found for application $appName in ${app.desc.eventLogDir.get}. "
1020- logWarning(msg)
1021- msg += " Did you specify the correct logging directory?"
1022- msg = URLEncoder .encode(msg, " UTF-8" )
1023- app.appUIUrlAtHistoryServer = Some (notFoundBasePath + s " ?msg= $msg&title= $title" )
1024-
1025- case e : Exception =>
1026- // Relay exception message to application UI page
1027- val title = s " Application history load error ( ${app.id}) "
1028- val exception = URLEncoder .encode(Utils .exceptionString(e), " UTF-8" )
1029- var msg = s " Exception in replaying log for application $appName! "
1030- logError(msg, e)
1031- msg = URLEncoder .encode(msg, " UTF-8" )
1032- app.appUIUrlAtHistoryServer =
1033- Some (notFoundBasePath + s " ?msg= $msg&exception= $exception&title= $title" )
1034- }(ThreadUtils .sameThread)
1035-
1036- futureUI
1037- }
1038-
1039932 /** Generate a new app ID given a app's submission date */
1040933 private def newApplicationId (submitDate : Date ): String = {
1041934 val appId = " app-%s-%04d" .format(createDateFormat.format(submitDate), nextAppNumber)
0 commit comments