aboutsummaryrefslogtreecommitdiff
path: root/stage1/Stage1.scala
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2017-02-09 21:20:11 -0500
committerChristopher Vogt <oss.nsp@cvogt.org>2017-02-09 22:43:00 -0500
commite8673866b79f7473391dcee26243eee80d5d3cb6 (patch)
tree16146affeebdb58cd302a1f8527220c906818c96 /stage1/Stage1.scala
parentbee13ba7a4458482ce00a5c6bae4cd64328c4e5e (diff)
downloadcbt-e8673866b79f7473391dcee26243eee80d5d3cb6.tar.gz
cbt-e8673866b79f7473391dcee26243eee80d5d3cb6.tar.bz2
cbt-e8673866b79f7473391dcee26243eee80d5d3cb6.zip
idempotent change propagation
using lastModified instead of a non-idempotent needsUpdate flag this fixes a bug where dependees would not be rebuilt if cbt exited or was killed after dependencies were already rebuilt.
Diffstat (limited to 'stage1/Stage1.scala')
-rw-r--r--stage1/Stage1.scala100
1 files changed, 50 insertions, 50 deletions
diff --git a/stage1/Stage1.scala b/stage1/Stage1.scala
index 27c6402..1fd4663 100644
--- a/stage1/Stage1.scala
+++ b/stage1/Stage1.scala
@@ -39,7 +39,8 @@ abstract class Stage2Base{
case class Stage2Args(
cwd: File,
args: Seq[String],
- cbtHasChanged: Boolean,
+ stage2LastModified: Long,
+ logger: Logger,
classLoaderCache: ClassLoaderCache,
cache: File,
cbtHome: File,
@@ -47,8 +48,9 @@ case class Stage2Args(
)(
implicit val transientCache: java.util.Map[AnyRef,AnyRef]
){
- val ClassLoaderCache( logger, persistentCache ) = classLoaderCache
+ val persistentCache = classLoaderCache.hashMap
}
+
object Stage1{
protected def newerThan( a: File, b: File ) ={
a.lastModified > b.lastModified
@@ -56,13 +58,14 @@ object Stage1{
def getBuild( _context: java.lang.Object, buildStage1: BuildStage1Result ) = {
val context = _context.asInstanceOf[Context]
- val logger = new Logger( context.enabledLoggers, context.start )
- val (changed, classLoader) = buildStage2(
+ val logger = new Logger( context.enabledLoggers, buildStage1.start )
+ val (cbtLastModified, classLoader) = buildStage2(
buildStage1,
- ClassLoaderCache( logger, context.persistentCache ),
+ new ClassLoaderCache( context.persistentCache ),
context.cbtHome,
- context.cache
- )( context.transientCache )
+ context.cache,
+ logger
+ )(context.transientCache)
classLoader
.loadClass("cbt.Stage2")
@@ -70,15 +73,16 @@ object Stage1{
.invoke(
null,
context.copy(
- cbtHasChanged = context.cbtHasChanged || buildStage1.changed || changed // might be redundant
+ cbtLastModified = Math.max( context.cbtLastModified, cbtLastModified )
)
)
}
def buildStage2(
- buildStage1: BuildStage1Result, classLoaderCache: ClassLoaderCache, cbtHome: File, cache: File
- )(implicit transientCache: java.util.Map[AnyRef,AnyRef]): (Boolean, ClassLoader) = {
- import classLoaderCache.logger
+ buildStage1: BuildStage1Result, classLoaderCache: ClassLoaderCache, cbtHome: File, cache: File, logger: Logger
+ )(implicit transientCache: java.util.Map[AnyRef,AnyRef]): (Long, ClassLoader) = {
+
+ import buildStage1._
val lib = new Stage1Lib(logger)
import lib._
@@ -89,61 +93,58 @@ object Stage1{
stage2.listFiles ++ (stage2 ++ "/plugins").listFiles
).toVector.filter(_.isFile).filter(_.toString.endsWith(".scala"))
- val cbtHasChanged = buildStage1.changed || lib.needsUpdate(stage2sourceFiles, stage2StatusFile)
-
val cls = this.getClass.getClassLoader.loadClass("cbt.NailgunLauncher")
- val cbtDependency = new CbtDependency(cbtHasChanged, mavenCache, nailgunTarget, stage1Target, stage2Target, new File(buildStage1.compatibilityClasspath))
+ def cbtDependencies = new CbtDependencies(
+ mavenCache, nailgunTarget, stage1Target, stage2Target,
+ new File(buildStage1.compatibilityClasspath)
+ )
logger.stage1("Compiling stage2 if necessary")
- compile(
- cbtHasChanged,
- cbtHasChanged,
+ val Some( stage2LastModified ) = compile(
+ buildStage1.stage1LastModified,
stage2sourceFiles, stage2Target, stage2StatusFile,
- cbtDependency.dependencies,
+ cbtDependencies.stage2Dependency.dependencies,
mavenCache,
Seq("-deprecation","-feature","-unchecked"), classLoaderCache,
zincVersion = constants.zincVersion, scalaVersion = constants.scalaVersion
)(transientCache)
logger.stage1(s"calling CbtDependency.classLoader")
- if( cbtHasChanged && classLoaderCache.cache.containsKey( cbtDependency.classpath.string ) ) {
- classLoaderCache.cache.remove( cbtDependency.classpath.string )
- } else {
- assert(
- buildStage1.compatibilityClasspath === cbtDependency.stage1Dependency.compatibilityDependency.classpath.string,
- "compatibility classpath different from NailgunLauncher"
- )
- assert(
- buildStage1.stage1Classpath === cbtDependency.stage1Dependency.classpath.string,
- "stage1 classpath different from NailgunLauncher"
- )
- assert(
- classLoaderCache.cache.containsKey( cbtDependency.stage1Dependency.compatibilityDependency.classpath.string ),
- "cbt unchanged, expected compatibility classloader to be cached"
- )
- assert(
- classLoaderCache.cache.containsKey( cbtDependency.stage1Dependency.classpath.string ),
- "cbt unchanged, expected stage1/nailgun classloader to be cached"
- )
- }
- val stage2ClassLoader = cbtDependency.classLoader(classLoaderCache)
+ assert(
+ buildStage1.compatibilityClasspath === cbtDependencies.compatibilityDependency.classpath.string,
+ "compatibility classpath different from NailgunLauncher"
+ )
+ assert(
+ buildStage1.stage1Classpath === cbtDependencies.stage1Dependency.classpath.string,
+ "stage1 classpath different from NailgunLauncher"
+ )
+ assert(
+ classLoaderCache.containsKey( cbtDependencies.compatibilityDependency.classpath.string, cbtDependencies.compatibilityDependency.lastModified ),
+ "cbt unchanged, expected compatibility classloader to be cached"
+ )
+ assert(
+ classLoaderCache.containsKey( cbtDependencies.stage1Dependency.classpath.string, cbtDependencies.stage1Dependency.lastModified ),
+ "cbt unchanged, expected stage1 classloader to be cached"
+ )
+
+ val stage2ClassLoader = cbtDependencies.stage2Dependency.classLoader(classLoaderCache)
{
// a few classloader sanity checks
val compatibilityClassLoader =
- cbtDependency.stage1Dependency.compatibilityDependency.classLoader(classLoaderCache)
+ cbtDependencies.compatibilityDependency.classLoader(classLoaderCache)
assert(
classOf[BuildInterface].getClassLoader == compatibilityClassLoader,
classOf[BuildInterface].getClassLoader.toString ++ "\n\nis not the same as\n\n" ++ compatibilityClassLoader.toString
)
//-------------
val stage1ClassLoader =
- cbtDependency.stage1Dependency.classLoader(classLoaderCache)
+ cbtDependencies.stage1Dependency.classLoader(classLoaderCache)
assert(
- classOf[Stage1Dependency].getClassLoader == stage1ClassLoader,
- classOf[Stage1Dependency].getClassLoader.toString ++ "\n\nis not the same as\n\n" ++ stage1ClassLoader.toString
+ classOf[Stage1ArgsParser].getClassLoader == stage1ClassLoader,
+ classOf[Stage1ArgsParser].getClassLoader.toString ++ "\n\nis not the same as\n\n" ++ stage1ClassLoader.toString
)
//-------------
assert(
@@ -152,7 +153,7 @@ object Stage1{
)
}
- ( cbtHasChanged, stage2ClassLoader )
+ ( stage2LastModified, stage2ClassLoader )
}
def run(
@@ -160,24 +161,23 @@ object Stage1{
cache: File,
cbtHome: File,
buildStage1: BuildStage1Result,
- start: java.lang.Long,
persistentCache: java.util.Map[AnyRef,AnyRef]
): Int = {
val args = Stage1ArgsParser(_args.toVector)
- val logger = new Logger(args.enabledLoggers, start)
+ val logger = new Logger(args.enabledLoggers, buildStage1.start)
implicit val transientCache: java.util.Map[AnyRef,AnyRef] = new java.util.HashMap
logger.stage1(s"Stage1 start")
- val classLoaderCache = ClassLoaderCache( logger, persistentCache )
-
+ val classLoaderCache = new ClassLoaderCache( persistentCache )
- val (cbtHasChanged, classLoader) = buildStage2( buildStage1, classLoaderCache, cbtHome, cache )
+ val (stage2LastModified, classLoader) = buildStage2( buildStage1, classLoaderCache, cbtHome, cache, logger )
val stage2Args = Stage2Args(
new File( args.args(0) ),
args.args.drop(1).dropWhile(_ == "direct").toVector,
// launcher changes cause entire nailgun restart, so no need for them here
- cbtHasChanged = cbtHasChanged,
+ stage2LastModified = stage2LastModified,
+ logger = logger,
classLoaderCache = classLoaderCache,
cache,
cbtHome,