Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-48974] Use NIO Ivy file lock strategy #148

Merged
merged 1 commit into from
Jan 14, 2025

Conversation

basil
Copy link
Member

@basil basil commented Jan 14, 2025

Background

See JENKINS-72050. Ivy 2.5.2 (a security release) introduced flakiness in @Grab relating to XML parsing. After upgrading to 2.5.3, this regression was apparently resolved, but a user has still noticed that @Grab is still flaky.

Problem

See JENKINS-72050 (comment). Building 14 Pipeline jobs in parallel, each of which uses @Grab, results in failures. These failures are not present when running the jobs sequentially.

Evaluation

See IVY-654 (comment). As described by @danielcwc, the default Ivy cache has no lock protection. From https://ant.apache.org/ivy/history/2.5.3/concept.html#cache:

This part of the cache can be shared if you use a well suited lock strategy.

From https://ant.apache.org/ivy/history/2.5.3/settings/caches.html:

lockStrategy […] defaults to no-lock

From https://ant.apache.org/ivy/history/2.5.3/settings/lock-strategies.html:

no-lock This lock strategy actually performs no locking at all, and thus should not be used in an environment where the cache is shared by multiple processes.

From this we can see that the bug is a classic race condition.

Solution

Use a file locking strategy, such as

artifact-lock This strategy acquires a lock whenever a module descriptor or an artifact is downloaded to the cache, which makes a good solution when you want to share your repository cache. Note that this strategy is based on file locking, performed by default using the java.io.File.createNewFile() atomicity (which is documented as atomic in the javadoc, but not recommended to perform locks).

or

artifact-lock-nio (since 2.4) Like the artifact-lock strategy, this one also acquires a lock whenever a module descriptor or artifact is downloaded to the cache. But here the implementation is done with a java.nio.FileLock.

Implementation

A proper implementation would be to add <caches lockStrategy="artifact-lock-nio" /> below https://github.com/apache/groovy/blob/de5ff81e020b25289c2eba8f245d46118e3c799f/src/resources/groovy/grape/defaultGrapeConfig.xml#L22 in Groovy's defaultGrapeConfig.xml. However, this would involve making a change to Groovy upstream, waiting for that to be released, and then upgrading to that release, a nontrivial endeavor.

Instead, we change the lock strategy in GrapeHack (introduced in jenkinsci/workflow-cps-global-lib-plugin#9) from its default of no-lock to artifact-lock-nio, offering an escape hatch in case the user has any problems. This works around the upstream Groovy issue without requiring us to patch and release a new version of Groovy.

Testing done

Ran the test described in the linked issue comment. Reproduced the failure when running 14 parallel jobs before this PR. Could no longer reproduce the failure after this PR.

Verified in the debugger and by viewing FINE-level logs that the workaround was executing as expected, that the lock strategy was no-lock before GrapeHack executed, and that the lock strategy was artifact-lock-nio after GrapeHack executed.

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

@basil basil added the bug Something isn't working label Jan 14, 2025
@basil basil requested a review from a team as a code owner January 14, 2025 21:51
@jglick jglick enabled auto-merge January 14, 2025 21:57
@jglick jglick merged commit 7008455 into jenkinsci:master Jan 14, 2025
16 of 17 checks passed
@basil basil deleted the lock-strategy branch January 14, 2025 22:07
@basil basil changed the title Use NIO Ivy file lock strategy [JENKINS-48974] Use NIO Ivy file lock strategy Jan 14, 2025
@paulk-asert
Copy link

Which Groovy version would this need to get to for a proper upstream fix?

@basil
Copy link
Member Author

basil commented Jan 15, 2025

Which Groovy version would this need to get to for a proper upstream fix?

Jenkins is still using Groovy 2.4.21 (see JENKINS-53372).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants