diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index b50ddefda..58b0df1c9 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -3,6 +3,7 @@ */ package sbt +import scala.concurrent.duration.Duration import Attributed.data import Scope.{ fillTaskAxis, GlobalScope, ThisScope } import sbt.Compiler.InputsWithPrevious @@ -157,7 +158,7 @@ object Defaults extends BuildCommon { fork :== false, initialize :== {}, forcegc :== sys.props.get("sbt.task.forcegc").map(java.lang.Boolean.parseBoolean).getOrElse(GCUtil.defaultForceGarbageCollection), - minForcegcInterval :== sys.props.get("sbt.task.minForcegcInterval").map(java.lang.Integer.parseInt).getOrElse(GCUtil.defaultMinForcegcInterval) + minForcegcInterval :== GCUtil.defaultMinForcegcInterval )) def defaultTestTasks(key: Scoped): Seq[Setting[_]] = inTask(key)(Seq( tags := Seq(Tags.Test -> 1), diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index 6e57f9326..6b14c04dc 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -3,6 +3,7 @@ */ package sbt +import scala.concurrent.duration.Duration import java.io.File import Def.{ displayFull, dummyState, ScopedKey, Setting } import Keys.{ streams, Streams, TaskStreams } @@ -88,9 +89,9 @@ sealed trait EvaluateTaskConfig { def forceGarbageCollection: Boolean /** - * Interval in seconds. + * Interval to force GC. */ - def minForcegcInterval: Int + def minForcegcInterval: Duration } final object EvaluateTaskConfig { /** Pulls in the old configuration format. */ @@ -123,7 +124,7 @@ final object EvaluateTaskConfig { progressReporter: ExecuteProgress[Task], cancelStrategy: TaskCancellationStrategy, forceGarbageCollection: Boolean, - minForcegcInterval: Int): EvaluateTaskConfig = { + minForcegcInterval: Duration): EvaluateTaskConfig = { val r = restrictions val check = checkCycles val cs = cancelStrategy @@ -230,7 +231,7 @@ object EvaluateTask { private[sbt] def forcegc(extracted: Extracted, structure: BuildStructure): Boolean = getSetting(Keys.forcegc in Global, GCUtil.defaultForceGarbageCollection, extracted, structure) // TODO - Should this pull from Global or from the project itself? - private[sbt] def minForcegcInterval(extracted: Extracted, structure: BuildStructure): Int = + private[sbt] def minForcegcInterval(extracted: Extracted, structure: BuildStructure): Duration = getSetting(Keys.minForcegcInterval in Global, GCUtil.defaultMinForcegcInterval, extracted, structure) def getSetting[T](key: SettingKey[T], default: T, extracted: Extracted, structure: BuildStructure): T = diff --git a/main/src/main/scala/sbt/GCUtil.scala b/main/src/main/scala/sbt/GCUtil.scala index 5dbd22a5e..cc223fd54 100644 --- a/main/src/main/scala/sbt/GCUtil.scala +++ b/main/src/main/scala/sbt/GCUtil.scala @@ -1,22 +1,23 @@ package sbt import java.util.concurrent.atomic.AtomicLong +import scala.concurrent.duration._ import scala.util.control.NonFatal private[sbt] object GCUtil { // Returns the default force garbage collection flag, // as specified by system properties. val defaultForceGarbageCollection: Boolean = true - val defaultMinForcegcInterval: Int = 60 + val defaultMinForcegcInterval: Duration = 60.seconds val lastGcCheck: AtomicLong = new AtomicLong(0L) - def forceGcWithInterval(minForcegcInterval: Int, log: Logger): Unit = + def forceGcWithInterval(minForcegcInterval: Duration, log: Logger): Unit = { val now = System.currentTimeMillis val last = lastGcCheck.get // This throttles System.gc calls to interval - if (now - last > minForcegcInterval * 1000) { - lastGcCheck.set(now) + if (now - last > minForcegcInterval.toMillis) { + lastGcCheck.lazySet(now) forceGc(log) } } diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 6cf2cd3bb..59faafdae 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -5,6 +5,7 @@ package sbt import java.io.File import java.net.URL +import scala.concurrent.duration.Duration import Def.ScopedKey import complete._ import inc.Analysis @@ -342,7 +343,7 @@ object Keys { val concurrentRestrictions = SettingKey[Seq[Tags.Rule]]("concurrent-restrictions", "Rules describing restrictions on concurrent task execution.", BSetting) val cancelable = SettingKey[Boolean]("cancelable", "Enables (true) or disables (false) the ability to interrupt task execution with CTRL+C.", BMinusSetting) val forcegc = SettingKey[Boolean]("forcegc", "Enables (true) or disables (false) forcing garbage collection after task run when needed.", BMinusSetting) - val minForcegcInterval = SettingKey[Int]("min-forcegc-interval", "Minimal interval (in seconds) to check for forcing garbage collection.") + val minForcegcInterval = SettingKey[Duration]("min-forcegc-interval", "Minimal interval to check for forcing garbage collection.") val settingsData = std.FullInstance.settingsData val streams = TaskKey[TaskStreams]("streams", "Provides streams for logging and persisting data.", DTask) val taskDefinitionKey = Def.taskDefinitionKey