[Gradle] Introduce TransientLazy for ResolvedDependencyGraph
Gradle Configuration Cache writer serialises objects that implement java.lang.Serializable interface. SynchronizedLazyImpl does implement it by initialising value before serialization. This can cause issues for GCC because after initialisation value can contain unsupported entities that Gradle can't save as Configuration Cache. Gradle can serialise lambdas so UnserializableLazy implementation benefits from it.
This commit is contained in:
+1
-1
@@ -885,7 +885,7 @@ internal class CacheBuilder(
|
|||||||
val kotlinOptions: KotlinCommonToolOptions,
|
val kotlinOptions: KotlinCommonToolOptions,
|
||||||
val externalDependenciesArgs: List<String>
|
val externalDependenciesArgs: List<String>
|
||||||
) {
|
) {
|
||||||
val rootCacheDirectory by lazy(rootCacheDirectoryProvider)
|
val rootCacheDirectory by UnserializableLazy(rootCacheDirectoryProvider)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
operator fun invoke(
|
operator fun invoke(
|
||||||
|
|||||||
+30
-1
@@ -35,4 +35,33 @@ fun <T : Any> provider(
|
|||||||
|
|
||||||
fun <T : Any> property(
|
fun <T : Any> property(
|
||||||
defaultValueProvider: () -> T
|
defaultValueProvider: () -> T
|
||||||
): PropertyDelegate<T> = PropertyDelegate(defaultValueProvider)
|
): PropertyDelegate<T> = PropertyDelegate(defaultValueProvider)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to [SynchronizedLazyImpl] but doesn't implement [Serializable] in the way
|
||||||
|
* that value gets initialised upon serialisation.
|
||||||
|
* It is intended that [initializer] gets serialised.
|
||||||
|
* Reason: Sometimes Gradle Configuration Cache can't serialise some entities that
|
||||||
|
* are produced by [initializer] but is okay serialising [initializer]
|
||||||
|
*/
|
||||||
|
internal class TransientLazy<T: Any>(
|
||||||
|
private val initializer: () -> T
|
||||||
|
) : Lazy<T> {
|
||||||
|
@Volatile
|
||||||
|
@Transient
|
||||||
|
private var _value: T? = null
|
||||||
|
override fun isInitialized(): Boolean = _value != null
|
||||||
|
override val value get(): T {
|
||||||
|
val v1 = _value
|
||||||
|
if (v1 != null) return v1
|
||||||
|
|
||||||
|
return synchronized(this) {
|
||||||
|
val v2 = _value
|
||||||
|
if (v2 == null) {
|
||||||
|
initializer().also { _value = it }
|
||||||
|
} else {
|
||||||
|
v2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-6
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.utils
|
package org.jetbrains.kotlin.gradle.utils
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.ArtifactCollection
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.artifacts.result.DependencyResult
|
import org.gradle.api.artifacts.result.DependencyResult
|
||||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
||||||
@@ -27,14 +28,14 @@ internal const val INTRANSITIVE = "intransitive"
|
|||||||
*/
|
*/
|
||||||
internal class ResolvedDependencyGraph
|
internal class ResolvedDependencyGraph
|
||||||
private constructor (
|
private constructor (
|
||||||
val files: FileCollection,
|
|
||||||
private val graphRootProvider: Provider<ResolvedComponentResult>,
|
private val graphRootProvider: Provider<ResolvedComponentResult>,
|
||||||
private val artifactsProvider: Provider<Set<ResolvedArtifactResult>>
|
private val artifactCollection: ArtifactCollection
|
||||||
) {
|
) {
|
||||||
val root get() = graphRootProvider.get()
|
val root get() = graphRootProvider.get()
|
||||||
val artifacts get() = artifactsProvider.get()
|
val files: FileCollection get() = artifactCollection.artifactFiles
|
||||||
|
val artifacts get() = artifactCollection.artifacts
|
||||||
|
|
||||||
val artifactsByComponentId by lazy { artifacts.groupBy { it.id.componentIdentifier } }
|
private val artifactsByComponentId by TransientLazy { artifacts.groupBy { it.id.componentIdentifier } }
|
||||||
|
|
||||||
val allDependencies: List<DependencyResult> get() {
|
val allDependencies: List<DependencyResult> get() {
|
||||||
fun DependencyResult.allDependenciesRecursive(): List<DependencyResult> =
|
fun DependencyResult.allDependenciesRecursive(): List<DependencyResult> =
|
||||||
@@ -54,9 +55,8 @@ private constructor (
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
operator fun invoke(project: Project, configuration: Configuration) = ResolvedDependencyGraph(
|
operator fun invoke(project: Project, configuration: Configuration) = ResolvedDependencyGraph(
|
||||||
files = project.files(configuration),
|
|
||||||
graphRootProvider = configuration.incoming.resolutionResult.let { rr -> project.provider { rr.root } },
|
graphRootProvider = configuration.incoming.resolutionResult.let { rr -> project.provider { rr.root } },
|
||||||
artifactsProvider = configuration.incoming.artifacts.let { collection -> project.provider { collection.artifacts } }
|
artifactCollection = configuration.incoming.artifacts
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user