-
Notifications
You must be signed in to change notification settings - Fork 4.6k
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
Move stateful logic from local metadata to state #29190
Move stateful logic from local metadata to state #29190
Conversation
@@ -110,76 +110,6 @@ Artifacts | |||
hasIncubatingLegend() | |||
} | |||
|
|||
def "Only one suite with a given test type allowed per project"() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests were moved to TestReportAggregationPluginIntegrationTest.groovy
. See the commit message for more details.
* May be empty, in which case selection falls back to the legacy configurations available via {@link #getConfiguration(String)}. | ||
* The component should provide a configuration called {@value Dependency#DEFAULT_CONFIGURATION}. | ||
*/ | ||
List<? extends VariantGraphResolveMetadata> getVariantsForGraphTraversal(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These methods were previously defined in ComponentGraphResolveMetadata.java
(the super-interface to this interface), but have been moved here since local component metadata is now not responsible for configurations and variants (since the logic required to support these methods is stateful)
@@ -231,4 +237,38 @@ public AttributesSchemaInternal getAttributesSchema() { | |||
return metadata.getAttributesSchema(); | |||
} | |||
} | |||
|
|||
private static class ExternalGraphSelectionCandidates implements GraphSelectionCandidates { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied from AbstractComponentGraphResolveState.java
, but with the explicit check for isCanBeConsumed
replaced with an assert since all external components always return consumable configurations.
* A {@link ConfigurationMetadataFactory} which uses a list of pre-constructed configuration | ||
* metadata as its data source. | ||
*/ | ||
public static class ConfigurationsListMetadataFactory implements ConfigurationMetadataFactory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This factory and the one below have been migrated from the now removed DefaultLocalComponentGraphResolveMetadata.java
...n/java/org/gradle/internal/component/local/model/DefaultLocalComponentGraphResolveState.java
Outdated
Show resolved
Hide resolved
b017cfc
to
77190ce
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the old stateful component metadata this PR intends to make stateless. It has been replaced by LocalComponentGraphResolveMetadata.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests in this file were moved to LocalComponentGraphResolveStateFactoryTest
. A lot of changes had to be made, so git did not recognize the move.
@bot-gradle test apt |
I've triggered the following builds for you. Click here to see all build failures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a part of all this work, the ConfigurationNotConsumableFailure
should be handled more similarly to other resolution failures. Other than that it looks like a good change.
.../main/java/org/gradle/api/internal/artifacts/ivyservice/InMemoryResolutionResultBuilder.java
Outdated
Show resolved
Hide resolved
.../main/java/org/gradle/api/internal/artifacts/ivyservice/InMemoryResolutionResultBuilder.java
Outdated
Show resolved
Hide resolved
...le/api/internal/artifacts/ivyservice/projectmodule/DefaultProjectLocalComponentProvider.java
Outdated
Show resolved
Hide resolved
...java/org/gradle/internal/component/external/model/ExternalComponentGraphResolveMetadata.java
Show resolved
Hide resolved
.../test/groovy/org/gradle/internal/component/external/model/IvyDependencyDescriptorTest.groovy
Outdated
Show resolved
Hide resolved
...management/src/main/java/org/gradle/internal/component/model/ComponentGraphResolveState.java
Show resolved
Hide resolved
...n/java/org/gradle/internal/component/local/model/DefaultLocalComponentGraphResolveState.java
Outdated
Show resolved
Hide resolved
...n/java/org/gradle/internal/component/local/model/DefaultLocalComponentGraphResolveState.java
Outdated
Show resolved
Hide resolved
...n/java/org/gradle/internal/component/local/model/DefaultLocalComponentGraphResolveState.java
Outdated
Show resolved
Hide resolved
...n/java/org/gradle/internal/component/local/model/DefaultLocalComponentGraphResolveState.java
Show resolved
Hide resolved
Prior changes have attempted to add a distinction between immutable component metadata and mutable component state. Currently, the component metadata is mutable, and calling methods on it may cause user code to run. The metadata caches its computed values. The state which calls those metadata methods transforms the metadata's computed values and then also caches its transformations. This double layer of caching makes it very difficult to properly handle project lock synchronization. This change consolidates the logic of computing variants and configurations into the component state. All stateful logic from the component metadata has been moved into the component state, and the component metadata type is now fully immutable. The most significant change here is that a `ComponentGraphResolveMetadata` instance no longer has methods to expose the component's variants or configrations. For local components, this logic is now completely handled by the component state. For external components, the metadata still has the responsibility of computing variants and configurations. So, a new interface for external metadata has been introduced to expose this functionality, `ExternalComponentGraphResolveMetadata`. Note that this commit does not actually solve the project locking issues present in the code. Its sole purpose is to collapse the double-caching layers into a single class, so that the project locking can be handled much more easily in a separate change.
…encies This data is only used for reporting tasks and is almost never needed. Only capture the data if it is used. (and in reality, this data isn't even needed in the in-memory resolution result builder either, since it is captured and sourced from the full resolution result anyways) Also move tests that verify tests cannot share a test type into the test report aggregation integ test. We no longer realize all variants in the current project's component when we resolve a configuration in that component. This means we do not call the code that detects duplicate test types when we run a test. This is a known problem, and the solution is to build a more robust artifact reselection mechanism that can support multiple tests with the same test type. For now, we move these tests into a test that does trigger the error.
4491d91
to
1ac7e5e
Compare
- Rename `returnAllVariants` to `includeAllSelectableVariantResults` for better clarity and consistency with naming on the state type - Add javadoc - Deprecate `getLegacyMetadata` on the state type and add suppressions where it is still being used - Rename `DefaultResolutionResultBuilder` to `ResolutionResultGraphBuilder` to better differentiate it from the related but different StreamingResolutinoResultBuilder and InMemoryResolutionResultBuilder that delegate to it - Remove `supportsAttributeMatching` method from `GraphSelectionCandiates` in favor of checking if the variants for attribute matching is empty - Move `ConfigurationMetadtaFactory` method to top-level file - Use `ResolutionFailureHandler` to handle configuration not consumable failures. We hard-code the resolution instead of using a failure dsecriber since at the moment there is no dynamic way to introduce new desribers for this type of failures. We should migrate to this pattern for other failures that do not have dynamic describer interfaces in order to avoid complexity and indirection.
439be1c
to
0f58327
Compare
@bot-gradle test this |
I've triggered the following builds for you. Click here to see all build failures. |
Prior changes have attempted to add a distinction between immutable component metadata and mutable component state.
Currently, the component metadata is mutable, and calling methods on it may cause user code to run. The metadata caches its computed values.
The state which calls those metadata methods transforms the metadata's computed values and then also caches its transformations.
This double layer of caching makes it very difficult to properly handle project lock synchronization. This change
consolidates the logic of computing variants and configurations into the component state. All stateful logic from the
component metadata has been moved into the component state, and the component metadata type is now fully immutable.
The most significant change here is that a
ComponentGraphResolveMetadata
instance no longer has methods to exposethe component's variants or configrations. For local components, this logic is now completely handled by the component
state. For external components, the metadata still has the responsibility of computing variants and configurations. So,
a new interface for external metadata has been introduced to expose this functionality,
ExternalComponentGraphResolveMetadata
.Note that this commit does not actually solve the project locking issues present in the code. Its sole purpose is to collapse
the double-caching layers into a single class, so that the project locking can be handled much more easily in a separate change.
Reviewing cheatsheet
Before merging the PR, comments starting with