Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception when multiple tasks concurrently access a finalizeValueOnRead property #29004

Open
SaschaRiemer opened this issue Apr 30, 2024 · 4 comments
Labels
a:bug in:provider-api property lazy provider MapProperty ListProperty DirectoryProperty

Comments

@SaschaRiemer
Copy link

SaschaRiemer commented Apr 30, 2024

Current Behavior

Reading a property which is configured with finalizeValueOnRead() sometimes fails with this exception:

java.lang.UnsupportedOperationException: Valued object is in an unexpected state.	
	at org.gradle.api.internal.provider.ValueState$FinalizedValue.unexpected(ValueState.java:401)	
	at org.gradle.api.internal.provider.ValueState$FinalizedValue.forUpstream(ValueState.java:340)	
	at org.gradle.api.internal.provider.AbstractProperty.finalizeNow(AbstractProperty.java:281)	
	at org.gradle.api.internal.provider.AbstractProperty.lambda$beforeRead$0(AbstractProperty.java:276)	
	at org.gradle.api.internal.provider.ValueState.finalizeOnReadIfNeeded(ValueState.java:123)	
	at org.gradle.api.internal.provider.AbstractProperty.beforeRead(AbstractProperty.java:276)	
	at org.gradle.api.internal.provider.AbstractProperty.beforeRead(AbstractProperty.java:268)	
	at org.gradle.api.internal.provider.AbstractProperty.calculateOwnValue(AbstractProperty.java:162)	
	at org.gradle.api.internal.provider.AbstractMinimalProvider.calculateOwnPresentValue(AbstractMinimalProvider.java:80)	
	at org.gradle.api.internal.provider.AbstractMinimalProvider.get(AbstractMinimalProvider.java:100)	

Expected Behavior

Reading the property should be successful.

Context (optional)

A single extension exists on the rootProject. This allows configuring multiple tasks, one for each project, with a global configuration. Since the tasks have no dependencies between them, they can run in parallel.

Steps to Reproduce

An example project can be found at https://github.com/SaschaRiemer/gradle-concurrent-property
However, the error does not occur reliably. Execute "./gradlew myTask", and there is a chance that the build will fail with an exception. It can happen immediately, or take 50 tries, eventually, when executing the command often enough, it should occur.

However, after analyzing the source code, I believe the problem to be this:

  • An extension is created on the rootProject, this extension has a ListProperty
  • The property is configured as finalizeValueOnRead()
  • For each project, a task is created. The task, during execution, accesses that property
  • This can cause concurrent access to the property, because the tasks are executed in parallel.

Then, there is a race condition:

  • Two threads, say Thread 1 and Thread 2, concurrently execute two of these tasks
  • Both read the property, and first check whether the property needs to be finalized
  • Since the property is not yet finalized, this check returns true for both tasks
  • Thread 1 now finalized the value, i.e. it swaps AbstractProperty.state to a FinalizedValue
  • Then, Thread 2 also tries to finalize the value, effectively calling ValueState.forUpstream on a FinalizedValue, which throws an exception

Gradle version

8.7

Build scan URL (optional)

No response

Your Environment (optional)

No response

SaschaRiemer added a commit to SaschaRiemer/gradle-concurrent-property that referenced this issue May 2, 2024
@ov7a
Copy link
Member

ov7a commented May 7, 2024

The issue is in the backlog of the relevant team and is prioritized by them.

@ov7a ov7a added in:provider-api property lazy provider MapProperty ListProperty DirectoryProperty and removed to-triage labels May 7, 2024
@Sineaggi
Copy link

We've hit this in multiple projects.

@bamboo
Copy link
Member

bamboo commented May 14, 2024

Related: #29140

@Sineaggi
Copy link

Sineaggi commented Jun 3, 2024

@bamboo is this expected then? Or an issue to be fixed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:bug in:provider-api property lazy provider MapProperty ListProperty DirectoryProperty
Projects
None yet
Development

No branches or pull requests

4 participants