![JAR search and dependency download from the Maven repository](/logo.png)
sbt.internal.AbstractTaskProgress.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of main_2.12 Show documentation
Show all versions of main_2.12 Show documentation
sbt is an interactive build tool
/*
* sbt
* Copyright 2023, Scala center
* Copyright 2011 - 2022, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt
package internal
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicLong
import scala.collection.JavaConverters._
import scala.collection.mutable
import scala.collection.immutable.VectorBuilder
import scala.concurrent.duration._
private[sbt] abstract class AbstractTaskExecuteProgress extends ExecuteProgress[Task] {
import AbstractTaskExecuteProgress.Timer
private[this] val showScopedKey = Def.showShortKey(None)
private[this] val anonOwners = new ConcurrentHashMap[Task[_], Task[_]]
private[this] val calledBy = new ConcurrentHashMap[Task[_], Task[_]]
private[this] val timings = new ConcurrentHashMap[Task[_], Timer]
private[sbt] def timingsByName: mutable.Map[String, AtomicLong] = {
val result = new ConcurrentHashMap[String, AtomicLong]
timings.forEach { (task, timing) =>
val duration = timing.durationNanos
result.putIfAbsent(taskName(task), new AtomicLong(duration)) match {
case null =>
case t => t.getAndAdd(duration); ()
}
}
result.asScala
}
private[sbt] def anyTimings = !timings.isEmpty
def currentTimings: Iterator[(Task[_], Timer)] = timings.asScala.iterator
private[internal] def exceededThreshold(task: Task[_], threshold: FiniteDuration): Boolean =
timings.get(task) match {
case null => false
case t => t.durationMicros > threshold.toMicros
}
private[internal] def timings(
tasks: java.util.Set[Task[_]],
thresholdMicros: Long
): Vector[(Task[_], Long)] = {
val result = new VectorBuilder[(Task[_], Long)]
val now = System.nanoTime
tasks.forEach { t =>
timings.get(t) match {
case null =>
case timing =>
if (timing.isActive) {
val elapsed = (now - timing.startNanos) / 1000
if (elapsed > thresholdMicros) result += t -> elapsed
}
}
}
result.result()
}
def activeTasks(now: Long) = {
val result = new VectorBuilder[(Task[_], FiniteDuration)]
timings.forEach { (task, timing) =>
if (timing.isActive) result += task -> (now - timing.startNanos).nanos
}
result.result
}
override def afterRegistered(
task: Task[_],
allDeps: Iterable[Task[_]],
pendingDeps: Iterable[Task[_]]
): Unit = {
// we need this to infer anonymous task names
pendingDeps foreach { t =>
if (TaskName.transformNode(t).isEmpty) {
anonOwners.put(t, task)
}
}
}
override def beforeWork(task: Task[_]): Unit = {
timings.put(task, new Timer)
()
}
protected def clearTimings: Boolean = false
override def afterWork[A](task: Task[A], result: Either[Task[A], Result[A]]): Unit = {
if (clearTimings) timings.remove(task)
else
timings.get(task) match {
case null =>
case t => t.stop()
}
// we need this to infer anonymous task names
result.left.foreach { t =>
calledBy.put(t, task)
}
}
private[this] val taskNameCache = new ConcurrentHashMap[Task[_], String]
protected def taskName(t: Task[_]): String = taskNameCache.get(t) match {
case null =>
val name = taskName0(t)
taskNameCache.putIfAbsent(t, name)
name
case name => name
}
private[this] def taskName0(t: Task[_]): String = {
def definedName(node: Task[_]): Option[String] =
node.info.name orElse TaskName.transformNode(node).map(showScopedKey.show)
def inferredName(t: Task[_]): Option[String] = nameDelegate(t) map taskName
def nameDelegate(t: Task[_]): Option[Task[_]] =
Option(anonOwners.get(t)) orElse Option(calledBy.get(t))
definedName(t) orElse inferredName(t) getOrElse TaskName.anonymousName(t)
}
}
object AbstractTaskExecuteProgress {
private[sbt] class Timer() {
val startNanos: Long = System.nanoTime()
val threadName: String = Thread.currentThread().getName
var endNanos: Long = 0L
def stop(): Unit = {
endNanos = System.nanoTime()
}
def isActive = endNanos == 0L
def durationNanos: Long = endNanos - startNanos
def startMicros: Long = (startNanos.toDouble / 1000).toLong
def durationMicros: Long = (durationNanos.toDouble / 1000).toLong
def currentElapsedMicros: Long =
((System.nanoTime() - startNanos).toDouble / 1000).toLong
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy