You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ivy-user@ant.apache.org by DYER Chris <Ch...@sydac.com> on 2022/01/19 05:06:16 UTC

Chain Resolver and TTL with multiple caches

Hi,
I am trying to configure a cache configuration to handle some development use cases.

I would like to resolve the latest version of a module, in a chain of resolvers, but with a different TTL per resolver in that chain.


We have multiple url repositories hosting modules with different status levels.
And a local filesystem resolver that developers can push locally built modules to.

We currently have modules using latest.integation as our revision and a dynamic resolve.

The URL repositories tend to be updated reasonably infrequently (maybe once a week say).
But resolving latest against the url repositories can be time consuming (sometimes our sever can be slow).

So I would like to be able to resolve latest from the url repositories once and keep them,
But check the integration repository for new modules that may have just been published locally.

I have been attempting to use the time to live to do this.

I would like to configure a TTL on anything coming down from the url resolvers to something like 1day
And then for local modules, always look for newer versions (i.e. no TTL)

My attempted configuration looked something like this.

  <resolvers>
    <chain name="all-repos">
      <url name="release" m2compatible="true" cache="timed_cache">
        <ivy pattern="${nexus-releases}/${ivy.ivy.pattern.default}" />
        <artifact pattern="${nexus-releases}/${ivy.artifact.pattern.default}" />
      </url>
      <url name="milestone" m2compatible="true" cache="timed_cache">
        <ivy pattern="${nexus-milestones}/${ivy.ivy.pattern.default}" />
        <artifact pattern="${nexus-milestones}/${ivy.artifact.pattern.default}" />
      </url>
      <url name="preview" m2compatible="true" cache="timed_cache">
        <ivy pattern="${nexus-previews}/${ivy.ivy.pattern.default}" />
        <artifact pattern="${nexus-previews}/${ivy.artifact.pattern.default}" />
      </url>
      <filesystem name="integration" m2compatible="true" local="true" cache=" integration_cache ">
        <ivy pattern="${ivy.integration.root}/${ivy.ivy.pattern.default}" />
        <artifact pattern="${ivy.integration.root}/${ivy.artifact.pattern.default}" />
      </filesystem>
    </chain>
  </resolvers>

  <caches resolutionCacheDir="${resolution_cache_dir}" repositoryCacheDir="${repository_cache_dir}">
    <cache name="timed_cache" defaultTTL="1d" basedir="${ivy.settings.dir}/.ivy/timed_cache"/>
    <cache name="integration_cache" basedir="${ivy.settings.dir}/.ivy/integration_cache"/>
  </caches>


But what I was finding is that the first thing it would try is a newly constructed "default-cache" see that there was no resolved module (or that the resolution had expired) and hit each url to find the latest.

I suspect this is because I am using a chain resolver and that doesn't have a cache defined (hence the default-cache).

So I can change this to
    <chain name="all-repos" cache="timed_cache">

Which will now correctly apply the TTL and not check the url repositories on subsequent resolves.

But now it also will not check the local filesystem repository for a newly published module.

Specifying a different cache on the chain
    <chain name="all-repos" cache="chain_cache">
Results in the same behaviour as not specifying anything
On resolution I get an expired resolved revision in the chain_cache and it will check each url and end up finding the module in the timed_cache.

Does anyone know if this sort of thing is supported or have some ideas on how else I may achieve this?

I guess I want the chain resolver to check each of it children every time, but defer the expiration of ttl of each child resolve to the associated cache manager.

Something like on a resolve of latest.integration

  1.  check chain cache -> expired (ttl 0s)
     *   check child 1 cache -> expired (ttl 1d) -> get latest.integration -> return rev 1

                                                               i.      cache child 1 result

     *   check child 2 cache -> expired (ttl 0s) - get latest integration -> return rev 2-dev1

                                                               i.      cache child 2 result

  1.  check latest between children -> rev 2-dev1
     *   cache chain result
Subsequent resolve

  1.  check chain cache -> expired (ttl 0s)
     *   check child 1 cache -> valid (ttl 1d) -> return rev 1
     *   check child 2 cache -> expired (ttl 0s) - get latest integration -> return rev 2-dev2

                                                               i.      cache child 2 result

  1.  check latest between children -> rev 2-dev2
     *   cache chain result

Perhaps I can raise an improvement in the Ivy jira

Cheers,
Chris