Details
-
New Feature
-
Status: Open
-
Minor
-
Resolution: Unresolved
-
2.4.8
-
None
-
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.