mirror of https://github.com/sbt/sbt.git
Limit TaskProgress threads
I noticed some flickering in super shell progress lines and realized that it was because there were multiple progress threads running concurrently. This is problematic because each thread has a completely different state so if each thread has an active task, the display will flicker between the two tasks. I think this is caused primarily by dynamic tasks. At least the example where I was seeing it was caused by a dynamic task.
This commit is contained in:
parent
ccecf1e412
commit
f0bec6d9e3
|
|
@ -224,29 +224,33 @@ object EvaluateTask {
|
||||||
structure: BuildStructure,
|
structure: BuildStructure,
|
||||||
state: State
|
state: State
|
||||||
): ExecuteProgress[Task] = {
|
): ExecuteProgress[Task] = {
|
||||||
val maker: Seq[Keys.TaskProgress] = getSetting(
|
state.get(currentTaskProgress).map(_.progress).getOrElse {
|
||||||
Keys.progressReports,
|
val maker: Seq[Keys.TaskProgress] = getSetting(
|
||||||
Seq(),
|
Keys.progressReports,
|
||||||
extracted,
|
Seq(),
|
||||||
structure
|
extracted,
|
||||||
)
|
structure
|
||||||
val progressReporter = extracted.get(progressState in ThisBuild).map { ps =>
|
)
|
||||||
ps.reset()
|
val progressReporter = extracted.getOpt(progressState in ThisBuild).flatMap {
|
||||||
ConsoleAppender.setShowProgress(true)
|
case Some(ps) =>
|
||||||
val appender = MainAppender.defaultScreen(StandardMain.console)
|
ps.reset()
|
||||||
appender match {
|
ConsoleAppender.setShowProgress(true)
|
||||||
case c: ConsoleAppender => c.setProgressState(ps)
|
val appender = MainAppender.defaultScreen(StandardMain.console)
|
||||||
case _ =>
|
appender match {
|
||||||
|
case c: ConsoleAppender => c.setProgressState(ps)
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
val log = LogManager.progressLogger(appender)
|
||||||
|
Some(new TaskProgress(log))
|
||||||
|
case _ => None
|
||||||
|
}
|
||||||
|
val reporters = maker.map(_.progress) ++ progressReporter ++
|
||||||
|
(if (SysProp.taskTimings) new TaskTimings(reportOnShutdown = false) :: Nil else Nil)
|
||||||
|
reporters match {
|
||||||
|
case xs if xs.isEmpty => ExecuteProgress.empty[Task]
|
||||||
|
case xs if xs.size == 1 => xs.head
|
||||||
|
case xs => ExecuteProgress.aggregate[Task](xs)
|
||||||
}
|
}
|
||||||
val log = LogManager.progressLogger(appender)
|
|
||||||
new TaskProgress(log)
|
|
||||||
}
|
|
||||||
val reporters = maker.map(_.progress) ++ progressReporter ++
|
|
||||||
(if (SysProp.taskTimings) new TaskTimings(reportOnShutdown = false) :: Nil else Nil)
|
|
||||||
reporters match {
|
|
||||||
case xs if xs.isEmpty => ExecuteProgress.empty[Task]
|
|
||||||
case xs if xs.size == 1 => xs.head
|
|
||||||
case xs => ExecuteProgress.aggregate[Task](xs)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO - Should this pull from Global or from the project itself?
|
// TODO - Should this pull from Global or from the project itself?
|
||||||
|
|
|
||||||
|
|
@ -482,6 +482,7 @@ object Keys {
|
||||||
object TaskProgress {
|
object TaskProgress {
|
||||||
def apply(progress: ExecuteProgress[Task]): TaskProgress = new TaskProgress(progress)
|
def apply(progress: ExecuteProgress[Task]): TaskProgress = new TaskProgress(progress)
|
||||||
}
|
}
|
||||||
|
private[sbt] val currentTaskProgress = AttributeKey[TaskProgress]("current-task-progress")
|
||||||
val useSuperShell = settingKey[Boolean]("Enables (true) or disables the super shell.")
|
val useSuperShell = settingKey[Boolean]("Enables (true) or disables the super shell.")
|
||||||
val turbo = settingKey[Boolean]("Enables (true) or disables optional performance features.")
|
val turbo = settingKey[Boolean]("Enables (true) or disables optional performance features.")
|
||||||
// This key can be used to add custom ExecuteProgress instances
|
// This key can be used to add custom ExecuteProgress instances
|
||||||
|
|
|
||||||
|
|
@ -179,10 +179,18 @@ object MainLoop {
|
||||||
val channelName = exec.source map (_.channelName)
|
val channelName = exec.source map (_.channelName)
|
||||||
StandardMain.exchange publishEventMessage
|
StandardMain.exchange publishEventMessage
|
||||||
ExecStatusEvent("Processing", channelName, exec.execId, Vector())
|
ExecStatusEvent("Processing", channelName, exec.execId, Vector())
|
||||||
|
|
||||||
try {
|
try {
|
||||||
def process(): State = {
|
def process(): State = {
|
||||||
val newState = Command.process(exec.commandLine, state)
|
val progressState = state.get(sbt.Keys.currentTaskProgress) match {
|
||||||
|
case Some(_) => state
|
||||||
|
case _ =>
|
||||||
|
if (state.get(Keys.stateBuildStructure).isDefined) {
|
||||||
|
val extracted = Project.extract(state)
|
||||||
|
val progress = EvaluateTask.executeProgress(extracted, extracted.structure, state)
|
||||||
|
state.put(sbt.Keys.currentTaskProgress, new Keys.TaskProgress(progress))
|
||||||
|
} else state
|
||||||
|
}
|
||||||
|
val newState = Command.process(exec.commandLine, progressState)
|
||||||
if (exec.commandLine.contains("session"))
|
if (exec.commandLine.contains("session"))
|
||||||
newState.get(hasCheckedMetaBuild).foreach(_.set(false))
|
newState.get(hasCheckedMetaBuild).foreach(_.set(false))
|
||||||
val doneEvent = ExecStatusEvent(
|
val doneEvent = ExecStatusEvent(
|
||||||
|
|
@ -198,7 +206,8 @@ object MainLoop {
|
||||||
} else { // send back a notification
|
} else { // send back a notification
|
||||||
StandardMain.exchange publishEventMessage doneEvent
|
StandardMain.exchange publishEventMessage doneEvent
|
||||||
}
|
}
|
||||||
newState
|
newState.get(sbt.Keys.currentTaskProgress).foreach(_.progress.stop())
|
||||||
|
newState.remove(sbt.Keys.currentTaskProgress)
|
||||||
}
|
}
|
||||||
// The split on space is to handle 'reboot full' and 'reboot'.
|
// The split on space is to handle 'reboot full' and 'reboot'.
|
||||||
state.currentCommand.flatMap(_.commandLine.trim.split(" ").headOption) match {
|
state.currentCommand.flatMap(_.commandLine.trim.split(" ").headOption) match {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue