Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-8097

Add an argument to set the resolution cache path in @Grab

    XMLWordPrintableJSON

Details

    • New Feature
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 2.4.8
    • None
    • Grape
    • None

    Description

      Ivy does not support concurrent access to its resolution cache
      https://issues.apache.org/jira/browse/IVY-654

      Grape relies on Ivy. For this reason, Grape cannot support concurrent access to its resolution cache neither.

      When using the @Grab annotation in jenkins groovyCommand or systemGroovyCommand, the related code is vulnerable to race conditions. When the race condition appears in a systemGroovyCommand, we have no choice but to reboot jenkins as all consecutive calls to @Grab fail.

      Among the two solutions we tried:

      • Protect the calls to grab with a lock similar to ivy's "artifact-lock-nio" strategy. Works but slow.
      • Set Ivy's lock on the repository cache and setup Grab to use a different cache resolution cache for each concurrent jobs. The following code permits to fix a test we did to reproduce the race condition.
          static IvySettings createIvySettings(String resolutionPath, boolean dumpSettings) {
              // Copy/Paste/Purged from GrapeIvy.groovy
              IvySettings settings = new IvySettings()
      
              settings.load(new File(GROOVY_HOME, "grapeConfig.xml"))
              // set up the cache dirs
              settings.defaultCache = new File(GRAPES_HOME)
              settings.setVariable("ivy.default.configuration.m2compatible", "true")
              settings.setDefaultResolutionCacheBasedir(resolutionPath)
              return settings
          }
      
          static GrapeIvy ivyWithCustomResolutionPath(String resolutionPath) {
              Class<?> grapeIvyClass = Class.forName("groovy.grape.GrapeIvy");
              Object instance = grapeIvyClass.newInstance()
              Field field = grapeIvyClass.getDeclaredField("ivyInstance");
              field.setAccessible(true);
              field.set(instance, Ivy.newInstance(createIvySettings(resolutionPath)));
              return ((GrapeIvy)instance)
          }
      

      We'd like to propose to add an additional argument to Grab to setup Ivy's resolution cache directory.

      Note that this solution seems to have been adopted by these users too
      https://rbcommons.com/s/twitter/r/3436/

      Would you agree on such a feature ? We'd be glad to propose a PR.

      Attachments

        Activity

          People

            Unassigned Unassigned
            yetanotherion Ion Alberdi
            Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated: