skip to content

Walk through the difference between configurationCache.requested and configurationCache.active. Give a concrete scenario where requested is true but active is false.

level: middleimportance: must knowfreq 40%

answer

  1. intent vs effect
  2. --no-configuration-cache overrides properties
  3. getOrElse(false) for absent
  4. branch on active, log on requested
  5. demotion makes active false

basics

~20 s

requested means the user asked for the configuration cache; active means it is actually operating. They diverge when, for example, the user sets it in gradle.properties but passes --no-configuration-cache on the command line — requested true, active false.

solid answer

~40 s

`buildFeatures.configurationCache.requested` reflects whether the user *opted in* to the configuration cache through any channel (CLI flag, `gradle.properties`, init script). `active` reflects whether the cache is *genuinely in effect* for this specific invocation. The two are deliberately separate because opting in does not guarantee operation. Divergence cases: (1) the property `org.gradle.configuration-cache=true` is set but the invocation passes `--no-configuration-cache`, which overrides it — `requested` may still report the property-level intent while `active` is false; (2) the build hit a fatal incompatibility and Gradle ran without the cache; (3) certain invocation types (e.g. some tooling-API or sync paths) don't engage it. For plugin authors the practical rule: branch on `active` when deciding whether an incompatible code path is safe to take *right now*, and use `requested` for diagnostics about user intent.

code

bash · 4 lines
bash
# gradle.properties: org.gradle.configuration-cache=true  => requested intent is true
# But this invocation overrides it:
./gradlew build --no-configuration-cache
# Result for this run: requested reflects the opt-in, active = false

go deeper

for a junior

State the one-line difference: requested = asked for, active = actually on.

for a middle

Give the override scenario and explain which flag to branch behaviour on.

for a senior

Discuss demotion/invocation-type causes of divergence and the absent-provider handling.

for a principal

Tie it to org policy: properties express team intent, while active drives correctness; telemetry should report both to catch silent demotions across the fleet.

## The two-flag model Gradle separates *intent* from *effect* for opt-in build features. `BuildFeatureValue` exposes: - **`requested: Provider<Boolean>`** — the user's expressed opt-in. Sources include `--configuration-cache` / `--no-configuration-cache` on the CLI, `org.gradle.configuration-cache=true|false` in `gradle.properties`, and equivalents set via init/settings. When nothing is specified the provider may be **absent**, so read it with `getOrElse(false)`. - **`active: Provider<Boolean>`** — whether the configuration cache is actually operating for this invocation. This is what you should consult before choosing a code path that depends on cache semantics. ## Why they diverge A feature being requested does not guarantee it is active: 1. **Command-line override.** A team-wide `gradle.properties` may enable the cache, but a developer running `./gradlew build --no-configuration-cache` for debugging suppresses it for that run. Intent and effect now differ. 2. **Invocation type.** Not every entry point engages the cache identically; some special invocations run without it. 3. **Demotion.** When a build cannot use the cache, `active` is false even though the user asked for it. ## How to use each ```kotlin val cc = buildFeatures.configurationCache val active = cc.active.getOrElse(false) val requested = cc.requested.getOrElse(false) if (requested && !active) { logger.warn("Config cache was requested but is not active for this run.") } // Branch real behaviour on the EFFECTIVE state: if (active) { // use only cache-compatible APIs } else { // legacy path may use otherwise-incompatible APIs } ``` ## Mental model Think of `requested` as a setting and `active` as a runtime fact. Logging and telemetry care about the setting (did the user mean to use it?); behavioural branching cares about the fact (is it on *now*?). Conflating them is the classic mistake — code that toggles an incompatible API on `requested` can still break when `active` turns out false, or pointlessly degrade when it's actually on. ## Reading them safely Both are `Provider<Boolean>`; resolve with `.get()` only when you know a value exists, otherwise `.getOrElse(false)`. Reading these providers is configuration-cache-safe and can be done at configuration or execution time.

  • If you must pick ONE of requested/active to gate a cache-incompatible code path, which and why?
    active — it reflects whether the cache is genuinely operating right now, so it correctly tells you whether the incompatible API is safe.
  • Why read these with getOrElse(false) rather than get()?
    requested can be absent when the user never specified anything; get() on an absent provider throws, so getOrElse supplies a safe default.

saying these in an interview costs you the question

  • Branching real behaviour on requested instead of active.
  • Assuming a CLI flag and a gradle.properties value always agree.
  • Calling get() on requested without handling the absent case.

context