dongjoon-hyun commented on code in PR #58054:
URL: https://github.com/apache/spark/pull/58054#discussion_r3806537684


##########
core/src/main/scala/org/apache/spark/SparkContext.scala:
##########
@@ -2075,6 +2075,159 @@ class SparkContext(config: SparkConf) extends Logging {
     }
   }
 
+  // Whether the executors are held via `holdExecutors()`, and, when dynamic 
allocation is
+  // disabled, the number of executors to restore on `resumeExecutors()`.
+  @volatile private var _executorsHeld: Boolean = false
+  private var heldNumExecutors: Int = 0
+
+  /**
+   * Whether `holdExecutors()` is supported in the current deployment. It 
requires a scheduler
+   * backend that can adjust the number of executors, decommission support, 
and shuffle data
+   * kept outside the executors: either an external shuffle service or a 
`ShuffleDataIO` with
+   * reliable storage.
+   */
+  private[spark] def executorHoldSupported: Boolean = {
+    schedulerBackend.isInstanceOf[ExecutorAllocationClient] &&
+      (conf.get(SHUFFLE_SERVICE_ENABLED) || 
shuffleDriverComponents.supportsReliableStorage()) &&
+      conf.get(DECOMMISSION_ENABLED)
+  }
+
+  /** Whether the executors are currently held by `holdExecutors()`. */
+  private[spark] def executorsHeld: Boolean = _executorsHeld
+
+  /**
+   * :: DeveloperApi ::
+   * Hold the whole application by declining to allocate new executors and 
gracefully
+   * decommissioning all existing ones. Each executor finishes its running 
tasks and then exits,
+   * while the shuffle data already written remains available through the 
external shuffle

Review Comment:
   Fixed in 137ebdb with the sentence you suggested.



##########
core/src/main/scala/org/apache/spark/ExecutorAllocationManager.scala:
##########
@@ -175,6 +175,18 @@ private[spark] class ExecutorAllocationManager(
   //   (2) an executor idle timeout has elapsed.
   @volatile private var initializing: Boolean = true
 
+  // Whether allocation is suspended because the executors are held. While 
this is true,
+  // `schedule()` is a no-op so that pending tasks do not bring up new 
executors.
+  // See `SparkContext.holdExecutors()`.
+  private var suspended: Boolean = false
+
+  // Whether the current executor targets still have to be pushed to the 
cluster manager. Set
+  // when a push from `suspend()`/`resume()` fails or is rejected (e.g. before 
the YARN AM has
+  // registered), and by `reset()`, which may run inside a cluster manager RPC 
handler where a
+  // synchronous request would self-deadlock (e.g. YARN's 
RegisterClusterManager). The push is
+  // performed from the allocation thread in `schedule()` and retried until 
acknowledged.
+  private var targetSyncPending: Boolean = false

Review Comment:
   Fixed in 137ebdb: the class doc now names the deferred target push 
(`targetSyncPending`) as the one exception to the no-retry assumption.



-- 
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]

Reply via email to