Move background job service directory location

Rather than putting the background job temporary files in whatever
java.io.tmpdir points to, this commit moves the files into a
subdirectory of target in the project root directory.

To make the directory configurable via settings, I had to move the
declaration of the bgJobService setting later in the project
initialization process. I don't think this should matter because
background jobs shouldn't be created until after the project has loaded
all of its settings..
This commit is contained in:
Ethan Atkins 2019-11-18 11:35:04 -08:00
parent 73edc8d4ff
commit 73a196798f
5 changed files with 43 additions and 16 deletions

View File

@ -351,7 +351,7 @@ object Defaults extends BuildCommon {
sys.env.contains("CI") || SysProp.ci,
// watch related settings
pollInterval :== Watch.defaultPollInterval,
) ++ LintUnused.lintSettings
) ++ LintUnused.lintSettings ++ DefaultBackgroundJobService.backgroundJobServiceSettings
)
def defaultTestTasks(key: Scoped): Seq[Setting[_]] =

View File

@ -251,6 +251,7 @@ object Keys {
val javaOptions = taskKey[Seq[String]]("Options passed to a new JVM when forking.").withRank(BPlusTask)
val envVars = taskKey[Map[String, String]]("Environment variables used when forking a new JVM").withRank(BTask)
val bgJobServiceDirectory = settingKey[File]("The directory for temporary files used by background jobs.")
val bgJobService = settingKey[BackgroundJobService]("Job manager used to run background jobs.")
val bgList = taskKey[Seq[JobHandle]]("List running background jobs.")
val ps = taskKey[Seq[JobHandle]]("bgList variant that displays on the log.")

View File

@ -130,7 +130,7 @@ object StandardMain {
try {
MainLoop.runLogged(s)
} finally {
try DefaultBackgroundJobService.backgroundJobService.shutdown()
try DefaultBackgroundJobService.shutdown()
finally hook.close()
()
}

View File

@ -12,7 +12,8 @@ import java.io.{ Closeable, File, FileInputStream, IOException }
import java.nio.file.attribute.BasicFileAttributes
import java.nio.file.{ FileVisitResult, Files, Path, SimpleFileVisitor }
import java.security.{ DigestInputStream, MessageDigest }
import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.{ AtomicLong, AtomicReference }
import sbt.Def.{ Classpath, ScopedKey, Setting }
import sbt.Scope.GlobalScope
@ -61,13 +62,16 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe
private val nextId = new AtomicLong(1)
private val pool = new BackgroundThreadPool()
private var serviceTempDirOpt: Option[File] = None
private def serviceTempDir = serviceTempDirOpt match {
case Some(dir) => dir
case _ =>
val dir = IO.createTemporaryDirectory
serviceTempDirOpt = Some(dir)
dir
private[sbt] def serviceTempDirBase: File
private val serviceTempDirRef = new AtomicReference[File]
private def serviceTempDir: File = serviceTempDirRef.synchronized {
serviceTempDirRef.get match {
case null =>
val dir = IO.createUniqueDirectory(serviceTempDirBase)
serviceTempDirRef.set(dir)
dir
case s => s
}
}
// hooks for sending start/stop events
protected def onAddJob(@deprecated("unused", "") job: JobHandle): Unit = ()
@ -166,7 +170,7 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe
}
}
pool.close()
serviceTempDirOpt foreach IO.delete
Option(serviceTempDirRef.get).foreach(IO.delete)
}
private def withHandle(job: JobHandle)(f: ThreadJobHandle => Unit): Unit = job match {
@ -465,14 +469,37 @@ private[sbt] class BackgroundThreadPool extends java.io.Closeable {
}
}
private[sbt] class DefaultBackgroundJobService extends AbstractBackgroundJobService {
private[sbt] class DefaultBackgroundJobService(private[sbt] val serviceTempDirBase: File)
extends AbstractBackgroundJobService {
@deprecated("Use the constructor that specifies the background job temporary directory", "1.4.0")
def this() = this(IO.createTemporaryDirectory)
override def makeContext(id: Long, spawningTask: ScopedKey[_], state: State): ManagedLogger = {
val extracted = Project.extract(state)
LogManager.constructBackgroundLog(extracted.structure.data, state)(spawningTask)
}
}
private[sbt] object DefaultBackgroundJobService {
lazy val backgroundJobService: DefaultBackgroundJobService = new DefaultBackgroundJobService
lazy val backgroundJobServiceSetting: Setting[_] =
((Keys.bgJobService in GlobalScope) :== backgroundJobService)
private[this] val backgroundJobServices = new ConcurrentHashMap[File, DefaultBackgroundJobService]
private[sbt] def shutdown(): Unit = {
backgroundJobServices.values.forEach(_.shutdown())
backgroundJobServices.clear()
}
private[sbt] lazy val backgroundJobServiceSetting: Setting[_] =
(Keys.bgJobService in GlobalScope) := {
val path = (sbt.Keys.bgJobServiceDirectory in GlobalScope).value
val newService = new DefaultBackgroundJobService(path)
backgroundJobServices.putIfAbsent(path, newService) match {
case null => newService
case s =>
newService.shutdown()
s
}
}
private[sbt] lazy val backgroundJobServiceSettings: Seq[Def.Setting[_]] = Def.settings(
Keys.bgJobServiceDirectory in GlobalScope := {
sbt.Keys.appConfiguration.value.baseDirectory / "target" / "bg-jobs"
},
backgroundJobServiceSetting
)
}

View File

@ -130,7 +130,6 @@ private[sbt] object Load {
def injectGlobal(state: State): Seq[Setting[_]] =
(appConfiguration in GlobalScope :== state.configuration) +:
LogManager.settingsLogger(state) +:
DefaultBackgroundJobService.backgroundJobServiceSetting +:
EvaluateTask.injectSettings
def defaultWithGlobal(