On 16 Feb 2014, at 2:59 pm, Daz DeBoer <darrell.deb...@gradleware.com> wrote:
> G'day > Just wanted to announce some fairly significant updates to the way we are > performing dependency resolution for dynamic versions. > > Motivation > Using component metadata rules, it's possible to update the 'status' of an > ivy module during resolution. This status value is then used to determine > which module version to choose when using a resolver like 'latest.release' > (choose the newest version with a status of 'release'). > > Until now, there has been an issue with caching of these values. Since we > cache the mapping of 'latest.release' to a specific version, any changes to > the rules were not reflected until cache expiry. This is a problem because we > think that component metadata rules should be 'live', and not have the result > of these rules cached. > > Implementation > This issue is now fixed, but it involved some significant changes. The > biggest change is that the resolver is no longer responsible for mapping a > dynamic version to a single version: the resolver simply returns a list of > available versions for a module, and the high-level UserResolverChain chooses > the best matching version from that list. This means that each > ModuleVersionRepository now has 3 functions: list versions for a module, get > metadata for a module version, and get artifacts. > A ModuleVersionRepository (resolver) does not map a dynamic version to a > static version: instead it lists the available versions for a module > ModuleVersionRepository now has 3 functions: > list versions for a module > get metadata for a module version > get artifacts. > This module version listing is cached per ModuleVersionRepository > UserResolverChain chooses the best matching version from the list. > If the module version metadata is required to choose the best matching > version (ie to determine 'latest.release'), then each module is resolved and > the component metadata rules are applied. This means that changes to the > rules take effect immediately This is good stuff. We can also later push this up higher again, to take into account all incoming selectors when selecting a version (eg given `1.+` and `[1.2,1.5]` we should choose 1.5 even when 1.6 is available - that kind of thing). > There are a few implications of this change: > Since the version listing is cached, if you have previously resolved > "group:module:1.+" and then resolve "group:module:2.+:, the second resolve > will use the cached version listing. So this means that the resolution of > '2.+' could contain stale data until cache expiry, even though that > particular selector has not been previously resolved. This also means we make fewer HTTP requests when there are multiple dynamic selectors for a given module resolved during a build, and also only get the meta-data file once when resolving a dynamic selector against multiple repositories. It also means that new versions don’t appear at arbitrary points during the build - so, for example, if I resolve `latest.integration` and determine that versions 1.1 and 1.2 are present (selecting 1.2), and then later resolve `latest.release`, I don’t suddenly have 1.3 appear. > For custom ivy resolvers (deprecated), an extra HTTP GET request is made for > ivy.xml when resolving an uncached dynamic version. I think we can live with this. We could possibly have the cache manager that we pass to the resolver deal with this and short-circuit downloading any meta-data file that we’ve already downloaded in the same resolve. -- Adam Murdoch Gradle Co-founder http://www.gradle.org VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com