mirror of https://github.com/sbt/sbt.git
Make progress an object
This commit reworks TaskProgress so that it is a singleton object. By using a singleton, we ensure that there is at most one progress thread running at a time. With multiple threads, there can be flickering in the progress reports. This fixes https://github.com/sbt/sbt/issues/5547. There also was a bug that the reference to the progress thread was not reset when the thread itself exited. As a result, it was possible for progress reporting to stop while tasks were still running. This seemed to primarily happen in multi-project builds. It should be fixed by this change.
This commit is contained in:
parent
a4e1c5aad5
commit
db4878c786
|
|
@ -255,7 +255,7 @@ object EvaluateTask {
|
||||||
extracted,
|
extracted,
|
||||||
structure
|
structure
|
||||||
)
|
)
|
||||||
val reporters = maker.map(_.progress) ++ Some(new TaskProgress) ++
|
val reporters = maker.map(_.progress) ++ Some(TaskProgress) ++
|
||||||
(if (SysProp.taskTimings)
|
(if (SysProp.taskTimings)
|
||||||
new TaskTimings(reportOnShutdown = false, state.globalLogging.full) :: Nil
|
new TaskTimings(reportOnShutdown = false, state.globalLogging.full) :: Nil
|
||||||
else Nil)
|
else Nil)
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,14 @@ import sbt.internal.util._
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
object TaskProgress extends TaskProgress
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* implements task progress display on the shell.
|
* implements task progress display on the shell.
|
||||||
*/
|
*/
|
||||||
private[sbt] final class TaskProgress
|
private[sbt] class TaskProgress private ()
|
||||||
extends AbstractTaskExecuteProgress
|
extends AbstractTaskExecuteProgress
|
||||||
with ExecuteProgress[Task] {
|
with ExecuteProgress[Task] {
|
||||||
@deprecated("Use the no argument constructor.", "1.4.0")
|
|
||||||
def this(log: ManagedLogger) = this()
|
|
||||||
private[this] val lastTaskCount = new AtomicInteger(0)
|
private[this] val lastTaskCount = new AtomicInteger(0)
|
||||||
private[this] val currentProgressThread = new AtomicReference[Option[ProgressThread]](None)
|
private[this] val currentProgressThread = new AtomicReference[Option[ProgressThread]](None)
|
||||||
private[this] val sleepDuration = SysProp.supershellSleep.millis
|
private[this] val sleepDuration = SysProp.supershellSleep.millis
|
||||||
|
|
@ -38,6 +38,13 @@ private[sbt] final class TaskProgress
|
||||||
private[this] def doReport(): Unit = { hasReported.set(true); report() }
|
private[this] def doReport(): Unit = { hasReported.set(true); report() }
|
||||||
setDaemon(true)
|
setDaemon(true)
|
||||||
start()
|
start()
|
||||||
|
private def resetThread(): Unit =
|
||||||
|
currentProgressThread.synchronized {
|
||||||
|
currentProgressThread.getAndSet(None) match {
|
||||||
|
case Some(t) if t != this => currentProgressThread.set(Some(t))
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
}
|
||||||
@tailrec override def run(): Unit = {
|
@tailrec override def run(): Unit = {
|
||||||
if (!isClosed.get() && (!hasReported.get || active.nonEmpty)) {
|
if (!isClosed.get() && (!hasReported.get || active.nonEmpty)) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -61,6 +68,8 @@ private[sbt] final class TaskProgress
|
||||||
|
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
|
} else {
|
||||||
|
resetThread()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +80,7 @@ private[sbt] final class TaskProgress
|
||||||
interrupt()
|
interrupt()
|
||||||
report()
|
report()
|
||||||
appendProgress(ProgressEvent("Info", Vector(), None, None, None))
|
appendProgress(ProgressEvent("Info", Vector(), None, None, None))
|
||||||
()
|
resetThread()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue