Make sure background jobs are shut down

This commit is contained in:
Eugene Yokota 2017-01-20 08:26:06 -05:00
parent 74cfbd4a9c
commit 2321648e96
5 changed files with 22 additions and 14 deletions

View File

@ -13,7 +13,8 @@ abstract class BackgroundJobService extends Closeable {
* then you could process.destroy() for example.
*/
def runInBackground(spawningTask: ScopedKey[_], state: State)(start: (Logger) => Unit): JobHandle
def close: Unit = ()
def close(): Unit
def shutdown(): Unit
def jobs: Vector[JobHandle]
def stop(job: JobHandle): Unit
def waitFor(job: JobHandle): Unit

View File

@ -134,12 +134,10 @@ object Defaults extends BuildCommon {
includeFilter in unmanagedJars :== "*.jar" | "*.so" | "*.dll" | "*.jnilib" | "*.zip",
includeFilter in unmanagedResources :== AllPassFilter,
fileToStore :== DefaultFileToStore,
bgJobService := { new DefaultBackgroundJobService() },
bgList := { bgJobService.value.jobs },
ps := psTask.value,
bgStop := bgStopTask.evaluated,
bgWaitFor := bgWaitForTask.evaluated,
onUnload := { s => try onUnload.value(s) finally bgJobService.value.close() }
bgWaitFor := bgWaitForTask.evaluated
)
private[sbt] lazy val globalIvyCore: Seq[Setting[_]] =

View File

@ -20,7 +20,8 @@ import sbt.internal.{
Script,
SessionSettings,
SettingCompletions,
LogManager
LogManager,
DefaultBackgroundJobService
}
import sbt.internal.util.{ AttributeKey, AttributeMap, complete, ConsoleOut, GlobalLogging, LineRange, MainAppender, SimpleReader, Types }
import sbt.util.{ Level, Logger }
@ -81,8 +82,11 @@ object StandardMain {
def runManaged(s: State): xsbti.MainResult =
{
val previous = TrapExit.installManager()
try MainLoop.runLogged(s)
finally TrapExit.uninstallManager(previous)
try {
try {
MainLoop.runLogged(s)
} finally DefaultBackgroundJobService.backgroundJobService.shutdown()
} finally TrapExit.uninstallManager(previous)
}
/** The common interface to standard output, used for all built-in ConsoleLoggers. */

View File

@ -1,12 +1,12 @@
package sbt
package internal
import java.util.concurrent.atomic.{ AtomicLong, AtomicInteger }
import java.util.concurrent.atomic.AtomicLong
import java.io.Closeable
import sbt.util.{ Logger, LogExchange, Level }
import sbt.internal.util.MainAppender
import Def.ScopedKey
import sbt.util.Logger
import Def.{ ScopedKey, Setting }
import scala.concurrent.ExecutionContext
import Scope.GlobalScope
/**
* Interface between sbt and a thing running in the background.
@ -99,7 +99,8 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe
pool.run(this, spawningTask, state)(start)
}
override def close(): Unit = {
override final def close(): Unit = shutdown()
override def shutdown(): Unit = {
while (jobSet.nonEmpty) {
jobSet.headOption.foreach {
case handle: ThreadJobHandle @unchecked =>
@ -259,10 +260,13 @@ private[sbt] class BackgroundThreadPool extends java.io.Closeable {
}
private[sbt] class DefaultBackgroundJobService extends AbstractBackgroundJobService {
private val generateId: AtomicInteger = new AtomicInteger
override def makeContext(id: Long, spawningTask: ScopedKey[_], state: State): Logger = {
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)
}

View File

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