PageRenderTime 21ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/core/src/main/scala/org/apache/spark/deploy/worker/CommandUtils.scala

https://gitlab.com/sumonsun/Spark
Scala | 96 lines | 54 code | 12 blank | 30 comment | 7 complexity | e398cc52a94595768805d27405ad1d2b MD5 | raw file
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.spark.deploy.worker
  18. import java.io.{File, FileOutputStream, InputStream, IOException}
  19. import java.lang.System._
  20. import org.apache.spark.Logging
  21. import org.apache.spark.deploy.Command
  22. import org.apache.spark.util.Utils
  23. /**
  24. ** Utilities for running commands with the spark classpath.
  25. */
  26. private[spark]
  27. object CommandUtils extends Logging {
  28. def buildCommandSeq(command: Command, memory: Int, sparkHome: String): Seq[String] = {
  29. val runner = getEnv("JAVA_HOME", command).map(_ + "/bin/java").getOrElse("java")
  30. // SPARK-698: do not call the run.cmd script, as process.destroy()
  31. // fails to kill a process tree on Windows
  32. Seq(runner) ++ buildJavaOpts(command, memory, sparkHome) ++ Seq(command.mainClass) ++
  33. command.arguments
  34. }
  35. private def getEnv(key: String, command: Command): Option[String] =
  36. command.environment.get(key).orElse(Option(System.getenv(key)))
  37. /**
  38. * Attention: this must always be aligned with the environment variables in the run scripts and
  39. * the way the JAVA_OPTS are assembled there.
  40. */
  41. def buildJavaOpts(command: Command, memory: Int, sparkHome: String): Seq[String] = {
  42. val memoryOpts = Seq(s"-Xms${memory}M", s"-Xmx${memory}M")
  43. // Exists for backwards compatibility with older Spark versions
  44. val workerLocalOpts = Option(getenv("SPARK_JAVA_OPTS")).map(Utils.splitCommandString)
  45. .getOrElse(Nil)
  46. if (workerLocalOpts.length > 0) {
  47. logWarning("SPARK_JAVA_OPTS was set on the worker. It is deprecated in Spark 1.0.")
  48. logWarning("Set SPARK_LOCAL_DIRS for node-specific storage locations.")
  49. }
  50. val libraryOpts =
  51. if (command.libraryPathEntries.size > 0) {
  52. val joined = command.libraryPathEntries.mkString(File.pathSeparator)
  53. Seq(s"-Djava.library.path=$joined")
  54. } else {
  55. Seq()
  56. }
  57. // Figure out our classpath with the external compute-classpath script
  58. val ext = if (System.getProperty("os.name").startsWith("Windows")) ".cmd" else ".sh"
  59. val classPath = Utils.executeAndGetOutput(
  60. Seq(sparkHome + "/bin/compute-classpath" + ext),
  61. extraEnvironment = command.environment)
  62. val userClassPath = command.classPathEntries ++ Seq(classPath)
  63. val javaVersion = System.getProperty("java.version")
  64. val permGenOpt = if (!javaVersion.startsWith("1.8")) Some("-XX:MaxPermSize=128m") else None
  65. Seq("-cp", userClassPath.filterNot(_.isEmpty).mkString(File.pathSeparator)) ++
  66. permGenOpt ++ libraryOpts ++ workerLocalOpts ++ command.javaOpts ++ memoryOpts
  67. }
  68. /** Spawn a thread that will redirect a given stream to a file */
  69. def redirectStream(in: InputStream, file: File) {
  70. val out = new FileOutputStream(file, true)
  71. // TODO: It would be nice to add a shutdown hook here that explains why the output is
  72. // terminating. Otherwise if the worker dies the executor logs will silently stop.
  73. new Thread("redirect output to " + file) {
  74. override def run() {
  75. try {
  76. Utils.copyStream(in, out, true)
  77. } catch {
  78. case e: IOException =>
  79. logInfo("Redirection to " + file + " closed: " + e.getMessage)
  80. }
  81. }
  82. }.start()
  83. }
  84. }