This message was deleted.
# configuration-cache
s
This message was deleted.
c
that’s good, if it were fully accurate. If you write a file inside a ValueSource - standard FileOutputStream stuff - that invalidates the configuration cache.
Copy code
Calculating task graph as configuration cache cannot be reused because file '../../../../.cloudshift-gradle/.cloudshift-codeartifact.properties' has changed.
…all that code is inside a single ValueSource.
In this case, the writing of that file has no bearing on what the ValueSource returns - would prefer to not invalidate the cache.
v
You might have found a bug. Iirc things like reading files, reading system properties, and so on, should not cause configuration cache to be invalidate if done inside a value source implementation but should be auto-detected outside. Maybe that writing is not handled as exception? But actually my guess would have been that this file is somewhere read as input for configuration cache and that it is not the writing of the file in the value source, but the reading as input invalidates the cache actually. But that's just a wild guess without analyzing the build.
c
possibly a bug, though the
ValueSource
docs hint that it’s only reading:
A value source implementation is exempt from the automatic detection of work graph cache inputs. For example, if the
obtain()
method calls
System.getenv("FOO")
then changes to the
FOO
environment variable only invalidate the cache if the value returned by the
obtain()
method itself changes. The same applies to reading files or system properties.
That file is used in one class (read and write), buried way down deep inside a ValueSource call hierarchy.
trying to track down how/where Gradle instruments code to detect file/property/env access…
Byte code manipulation in
org.gradle.internal.classpath.InstrumentingTransformer
, Not seeing anything for writing in there. It’s possible that the pattern being used to read/write isn’t properly caught by the instrumentation.
Ok, so - was able to reproduce. tl;dr - you can’t pass a ValueSource (including
providers.environmentVariable
or
providers.gradleProperty
as an input parameter to another ValueSource. In digging through the internals, the logic works as: a) Transforming classloader (
org.gradle.internal.classpath.InstrumentingTransformer
) - finds all kinds of relevant code (such as file open, get env variable, etc) and rewrites the code to emit events b) event handler (
org.gradle.configurationcache.fingerprint.ConfigurationCacheFingerprintWriter
) stores these changes _conditionally_; the conditional is based on a ThreadLocal variable
inputTrackingDisabledForThread
c) when a value is obtained from a ValueSource, it first emits a
beforeValueObtained()
event; this sets the input tracking OFF d) value is obtained from ValueSource e) ValueSource emits
afterValueObtained()
event; this sets the input tracking ON The problem comes when using a ValueSource (such as a Gradle property) as an input parameter to your ValueSource (it may be if there are an odd-number of ValueSource parameters) - the fingerprinting of those inputs resolves the values, and leaves input tracking ON for the body of your ValueSource. Ouch. Will get the repro cleaned up and an issue created in the morning.
v
Oh, so the "is tracking" is not a counter but a boolean. Nice find.