Merge pull request #7567 from adpi2/backport-7538

[1.10.x] Fix `dependency-management/force-update-period` (backport of #7538)
This commit is contained in:
adpi2 2024-05-23 08:49:48 +02:00 committed by GitHub
commit 29d6912754
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 35 deletions

View File

@ -3797,7 +3797,7 @@ object Classpaths {
forceUpdatePeriod.value match {
case None => false
case Some(period) =>
val fullUpdateOutput = cacheDirectory / "out"
val fullUpdateOutput = cacheDirectory / "output"
val now = System.currentTimeMillis
val diff = now - IO.getModifiedTimeOrZero(fullUpdateOutput)
val elapsedDuration = new FiniteDuration(diff, TimeUnit.MILLISECONDS)

View File

@ -110,13 +110,16 @@ private[sbt] object LibraryManagement {
}
/* Skip resolve if last output exists, otherwise error. */
def skipResolve(cache: CacheStore): UpdateInputs => UpdateReport = {
def skipResolve(cache: CacheStore)(inputs: UpdateInputs): UpdateReport = {
import sbt.librarymanagement.LibraryManagementCodec._
Tracked.lastOutput[UpdateInputs, UpdateReport](cache) {
case (_, Some(out)) => markAsCached(out)
case _ =>
sys.error("Skipping update requested, but update has not previously run successfully.")
}
val cachedReport = Tracked
.lastOutput[UpdateInputs, UpdateReport](cache) {
case (_, Some(out)) => out
case _ =>
sys.error("Skipping update requested, but update has not previously run successfully.")
}
.apply(inputs)
markAsCached(cachedReport)
}
// Mark UpdateReport#stats as "cached." This is used by the dependers later
@ -127,15 +130,21 @@ private[sbt] object LibraryManagement {
def doResolve(cache: CacheStore): UpdateInputs => UpdateReport = {
val doCachedResolve = { (inChanged: Boolean, updateInputs: UpdateInputs) =>
import sbt.librarymanagement.LibraryManagementCodec._
val cachedResolve = Tracked.lastOutput[UpdateInputs, UpdateReport](cache) {
case (_, Some(out)) if upToDate(inChanged, out) => markAsCached(out)
case pair =>
log.debug(s"""not up to date. inChanged = $inChanged, force = $force""")
resolve
}
import scala.util.control.Exception.catching
catching(classOf[NullPointerException], classOf[OutOfMemoryError])
.withApply { t =>
try {
var isCached = false
val report = Tracked
.lastOutput[UpdateInputs, UpdateReport](cache) {
case (_, Some(out)) if upToDate(inChanged, out) =>
isCached = true
out
case pair =>
log.debug(s"""not up to date. inChanged = $inChanged, force = $force""")
resolve
}
.apply(updateInputs)
if (isCached) markAsCached(report) else report
} catch {
case t @ (_: NullPointerException | _: OutOfMemoryError) =>
val resolvedAgain = resolve
val culprit = t.getClass.getSimpleName
log.warn(s"Update task caching failed due to $culprit.")
@ -143,8 +152,7 @@ private[sbt] object LibraryManagement {
resolvedAgain.toString.linesIterator.foreach(log.warn(_))
log.trace(t)
resolvedAgain
}
.apply(cachedResolve(updateInputs))
}
}
import LibraryManagementCodec._
Tracked.inputChanged(cacheStoreFactory.make("inputs"))(doCachedResolve)
@ -155,7 +163,7 @@ private[sbt] object LibraryManagement {
val extraInputHash = module.extraInputHash
val settings = module.moduleSettings
val outStore = cacheStoreFactory.make("output")
val handler = if (skip && !force) skipResolve(outStore) else doResolve(outStore)
val handler = if (skip && !force) skipResolve(outStore)(_) else doResolve(outStore)
// Remove clock for caching purpose
val withoutClock = updateConfig.withLogicalClock(LogicalClock.unknown)
handler((extraInputHash, settings, withoutClock))
@ -257,7 +265,7 @@ private[sbt] object LibraryManagement {
forceUpdatePeriod.value match {
case None => false
case Some(period) =>
val fullUpdateOutput = cacheDirectory / "out"
val fullUpdateOutput = cacheDirectory / "output"
val now = System.currentTimeMillis
val diff = now - fullUpdateOutput.lastModified()
val elapsedDuration = new scala.concurrent.duration.FiniteDuration(

View File

@ -1,17 +1,19 @@
ThisBuild / useCoursier := false
name := "force-update-period"
scalaVersion := "2.12.18"
libraryDependencies += "log4j" % "log4j" % "1.2.16" % "compile"
autoScalaLibrary := false
crossPaths := false
TaskKey[Unit]("check-last-update-time") := (streams map { (s) =>
val fullUpdateOutput = s.cacheDirectory / "out"
val timeDiff = System.currentTimeMillis()-fullUpdateOutput.lastModified()
val exists = fullUpdateOutput.exists()
s.log.info(s"Amount of time since last full update: $timeDiff")
if (exists && timeDiff > 5000) {
sys.error("Full update not performed")
TaskKey[Unit]("check-last-update-time") := {
val s = streams.value
val updateOutput = crossTarget.value / "update" / updateCacheName.value / "output"
if (!updateOutput.exists()) {
sys.error("Update cache does not exist")
}
}).value
val timeDiff = System.currentTimeMillis() - updateOutput.lastModified()
s.log.info(s"Amount of time since last full update: $timeDiff")
if (timeDiff > 5000) {
sys.error("Update not performed")
}
}

View File

@ -1,11 +1,11 @@
$ absent target/resolution-cache
$ absent target/scala-2.12/resolution-cache
> compile
$ exists target/resolution-cache
$ exists target/scala-2.12/resolution-cache
> checkLastUpdateTime
$ sleep 10000
$ sleep 5000
> compile
# This is expected to fail
-> checkLastUpdateTime
> set forceUpdatePeriod := Some(new scala.concurrent.duration.FiniteDuration(5000, java.util.concurrent.TimeUnit.MILLISECONDS))
> compile
> checkLastUpdateTime
> checkLastUpdateTime