Merge pull request #4556 from eed3si9n/wip/progress

Make sure progress thread gets shutdown
This commit is contained in:
eugene yokota 2019-03-08 20:41:41 -05:00 committed by GitHub
commit 354f85cecb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 10 deletions

View File

@ -290,6 +290,9 @@ lazy val taskProj = (project in file("tasks"))
testedBaseSettings,
name := "Tasks",
mimaSettings,
mimaBinaryIssueFilters ++= Seq(
exclude[ReversedMissingMethodProblem]("sbt.ExecuteProgress.stop")
)
)
.configure(addSbtUtilControl)

View File

@ -161,7 +161,7 @@ object EvaluateTask {
import std.Transform
import Keys.state
lazy private val sharedProgress = new TaskTimings(shutdown = true)
lazy private val sharedProgress = new TaskTimings(reportOnShutdown = true)
// sbt-pgp calls this
private[sbt] def defaultProgress(): ExecuteProgress[Task] = ExecuteProgress.empty[Task]
@ -170,7 +170,7 @@ object EvaluateTask {
if (java.lang.Boolean.getBoolean("sbt.task.timings.on.shutdown"))
sharedProgress
else
new TaskTimings(shutdown = false)
new TaskTimings(reportOnShutdown = false)
} else {
if (ConsoleAppender.showProgress) new TaskProgress(currentRef)
else ExecuteProgress.empty[Task]
@ -412,6 +412,7 @@ object EvaluateTask {
def shutdown(): Unit = {
// First ensure that all threads are stopped for task execution.
shutdownThreads()
config.progressReporter.stop()
// Now we run the gc cleanup to force finalizers to clear out file handles (yay GC!)
if (config.forceGarbageCollection) {

View File

@ -138,6 +138,20 @@ object StandardMain {
// This is to workaround https://github.com/sbt/io/issues/110
sys.props.put("jna.nosys", "true")
ConsoleAppender.setTerminalWidth(JLine.usingTerminal(_.getWidth))
ConsoleAppender.setShowProgress(
ConsoleAppender.formatEnabledInEnv && sys.props
.get("sbt.progress")
.flatMap({ s =>
ConsoleAppender.parseLogOption(s) match {
case LogOption.Always => Some(true)
case LogOption.Never => Some(false)
case _ => None
}
})
.getOrElse(true)
)
import BasicCommandStrings.isEarlyCommand
val userCommands = configuration.arguments.map(_.trim)
val (earlyCommands, normalCommands) = (preCommands ++ userCommands).partition(isEarlyCommand)

View File

@ -31,6 +31,7 @@ private[sbt] final class TaskProgress(currentRef: ProjectRef) extends ExecutePro
private[this] val isReady = new AtomicBoolean(false)
private[this] val lastTaskCount = new AtomicInteger(0)
private[this] val isAllCompleted = new AtomicBoolean(false)
private[this] val isStopped = new AtomicBoolean(false)
override def initial: Unit = ()
override def registered(
@ -67,14 +68,18 @@ private[sbt] final class TaskProgress(currentRef: ProjectRef) extends ExecutePro
override def completed[A](state: Unit, task: Task[A], result: Result[A]): Unit = ()
override def stop(): Unit = {
isStopped.set(true)
}
import ExecutionContext.Implicits._
Future {
while (!isReady.get) {
while (!isReady.get && !isStopped.get) {
blocking {
Thread.sleep(500)
}
}
while (!isAllCompleted.get) {
while (!isAllCompleted.get && !isStopped.get) {
blocking {
report()
Thread.sleep(500)

View File

@ -20,9 +20,9 @@ import TaskName._
* - -Dsbt.task.timings.on.shutdown=true|false
* - -Dsbt.task.timings.unit=number
* - -Dsbt.task.timings.threshold=number
* @param shutdown Should the report be given when exiting the JVM (true) or immediately (false)?
* @param reportOnShutdown Should the report be given when exiting the JVM (true) or immediately (false)?
*/
private[sbt] final class TaskTimings(shutdown: Boolean) extends ExecuteProgress[Task] {
private[sbt] final class TaskTimings(reportOnShutdown: Boolean) extends ExecuteProgress[Task] {
private[this] val calledBy = new ConcurrentHashMap[Task[_], Task[_]]
private[this] val anonOwners = new ConcurrentHashMap[Task[_], Task[_]]
private[this] val timings = new ConcurrentHashMap[Task[_], Long]
@ -41,7 +41,7 @@ private[sbt] final class TaskTimings(shutdown: Boolean) extends ExecuteProgress[
type S = Unit
if (shutdown) {
if (reportOnShutdown) {
start = System.nanoTime
Runtime.getRuntime.addShutdownHook(new Thread {
override def run() = report()
@ -49,7 +49,7 @@ private[sbt] final class TaskTimings(shutdown: Boolean) extends ExecuteProgress[
}
def initial = {
if (!shutdown)
if (!reportOnShutdown)
start = System.nanoTime
}
def registered(
@ -72,10 +72,12 @@ private[sbt] final class TaskTimings(shutdown: Boolean) extends ExecuteProgress[
}
def completed[T](state: Unit, task: Task[T], result: Result[T]) = ()
def allCompleted(state: Unit, results: RMap[Task, Result]) =
if (!shutdown) {
if (!reportOnShutdown) {
report()
}
def stop(): Unit = ()
private val reFilePath = raw"\{[^}]+\}".r
private[this] def report() = {

View File

@ -10,7 +10,7 @@ object Dependencies {
// sbt modules
private val ioVersion = "1.3.0-M5"
private val utilVersion = "1.3.0-M4"
private val utilVersion = "1.3.0-M5"
private val lmVersion =
sys.props.get("sbt.build.lm.version") match {
case Some(version) => version

View File

@ -60,6 +60,9 @@ private[sbt] trait ExecuteProgress[F[_]] {
/** All tasks have completed with the final `results` provided. */
def allCompleted(state: S, results: RMap[F, Result]): S
/** Notifies that either all tasks have finished or cancelled. */
def stop(): Unit
}
/** This module is experimental and subject to binary and source incompatible changes at any time. */
@ -74,5 +77,6 @@ private[sbt] object ExecuteProgress {
def workFinished[A](task: F[A], result: Either[F[A], Result[A]]) = ()
def completed[A](state: Unit, task: F[A], result: Result[A]) = ()
def allCompleted(state: Unit, results: RMap[F, Result]) = ()
def stop(): Unit = ()
}
}