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

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

    Details

    • Type: New Feature
    • Status: Open
    • Priority: Minor
    • Resolution: Unresolved
    • Affects Version/s: 2.4.8
    • Fix Version/s: None
    • Component/s: Grape
    • Labels:
      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

            • Assignee:
              Unassigned
              Reporter:
              yetanotherion Ion Alberdi
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated: