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-41880] Synchronise on Fingerprint #69

Merged
merged 3 commits into from May 11, 2018

Conversation

@bjoernhaeuser
Copy link
Contributor

bjoernhaeuser commented Apr 3, 2018

I am not sure this makes any sense. I am just trying to solve this
issue: https://issues.jenkins-ci.org/browse/JENKINS-41880

My thoughts:

This is likely caused by changing the finger prints, the finger prints
are scoped to the project (right?). If this is the case synchronising on
the project could make sense. Also addFromFacet should not be a
performance killer and rather quick.

The alternative would be for me to synchronise the complete access to the method.

WDYT?

I am not sure this makes any sense. I am just trying to solve this
issue: https://issues.jenkins-ci.org/browse/JENKINS-41880

My thoughts:

This is likely caused by changing the finger prints, the finger prints
are scoped to the project (right?). If this is the case synchronising on
the project could make sense. Also `addFromFacet` should not be a
performance killer and rather quick.

The alternative would be for me to synchronise the complete access to the method.

WDYT?
@bjoernhaeuser bjoernhaeuser changed the title Synchronise on project [JENKINS-41880] Synchronise on project Apr 3, 2018
@oleg-nenashev oleg-nenashev requested review from jglick and oleg-nenashev Apr 4, 2018
@bjoernhaeuser
Copy link
Contributor Author

bjoernhaeuser commented Apr 4, 2018

Thanks!

@@ -96,20 +96,20 @@ public String getUrlName() {
public @CheckForNull String getFingerprintHash(@CheckForNull String imageId) {
return (imageId != null) ? DockerFingerprints.getFingerprintHash(imageId) : null;
}

This comment has been minimized.

Copy link
@jglick

jglick Apr 5, 2018

Member

Please revert formatting-only changes, and configure your editor to not change whitespace in lines you have not otherwise edited.

BulkChange bc = new BulkChange(f);
try {
if (ancestorFacet == null) {
ancestorFacet = new DockerAncestorFingerprintFacet(f, timestamp, descendantImageId);

This comment has been minimized.

Copy link
@jglick

jglick Apr 5, 2018

Member

Unreadable diff. This is much easier to follow, but generally I recommend not changing indentation of large code blocks, since it messes up other things like cherry-picks and merges.


import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

This comment has been minimized.

Copy link
@jglick

jglick Apr 5, 2018

Member

Unrelated, revert.

long timestamp = System.currentTimeMillis();
if (ancestorImageId != null) {
Fingerprint f = forImage(run, ancestorImageId);
synchronized (run.getParent()) {

This comment has been minimized.

Copy link
@jglick

jglick Apr 5, 2018

Member

The PR could be reduced to the addition of this line and its closing brace.

Anyway, this looks wrong to me. A Fingerprint, by design, represents something that is (potentially) shared across multiple builds, typically of different jobs. And Fingerprint.save synchronizes on this. So I suspect you rather want to be synchronizing on each Fingerprint being manipulated. Try:

diff --git a/src/main/java/org/jenkinsci/plugins/docker/commons/fingerprint/DockerFingerprints.java b/src/main/java/org/jenkinsci/plugins/docker/commons/fingerprint/DockerFingerprints.java
index 047b4e4..95c62f4 100644
--- a/src/main/java/org/jenkinsci/plugins/docker/commons/fingerprint/DockerFingerprints.java
+++ b/src/main/java/org/jenkinsci/plugins/docker/commons/fingerprint/DockerFingerprints.java
@@ -257,6 +257,7 @@ public class DockerFingerprints {
         long timestamp = System.currentTimeMillis();
         if (ancestorImageId != null) {
             Fingerprint f = forImage(run, ancestorImageId);
+            synchronized (f) {
             Collection<FingerprintFacet> facets = f.getFacets();
             DockerDescendantFingerprintFacet descendantFacet = null;
             for (FingerprintFacet facet : facets) {
@@ -278,8 +279,10 @@ public class DockerFingerprints {
             } finally {
                 bc.abort();
             }
+            }
         }
         Fingerprint f = forImage(run, descendantImageId);
+        synchronized (f) {
         Collection<FingerprintFacet> facets = f.getFacets();
         DockerAncestorFingerprintFacet ancestorFacet = null;
         for (FingerprintFacet facet : facets) {
@@ -303,6 +306,7 @@ public class DockerFingerprints {
         } finally {
             bc.abort();
         }
+        }
     }
 
 }

and see if that fixes your issue.

@bjoernhaeuser
Copy link
Contributor Author

bjoernhaeuser commented Apr 5, 2018

I removed all unrelated changes and went with the suggestion to synchronize the fingerprint. I just tested this on our jenkins installation and it looks very promising.

@bjoernhaeuser
Copy link
Contributor Author

bjoernhaeuser commented Apr 5, 2018

promising as in: no ConcurrentModificationExceptions anymore

@bjoernhaeuser
Copy link
Contributor Author

bjoernhaeuser commented Apr 6, 2018

@jglick could you take another look please? :)

@@ -257,6 +257,7 @@ public static void addFromFacet(@CheckForNull String ancestorImageId, @Nonnull S
long timestamp = System.currentTimeMillis();
if (ancestorImageId != null) {
Fingerprint f = forImage(run, ancestorImageId);
synchronized (f) {
Collection<FingerprintFacet> facets = f.getFacets();

This comment has been minimized.

Copy link
@crummy

crummy Apr 18, 2018

Looks like some indentation is needed here, and after the next synchronized block too

This comment has been minimized.

Copy link
@jglick

jglick May 10, 2018

Member

The idea was to avoid touching every line in between, which makes diffs harder to read and complicates merges & cherry-picks.

@bjoernhaeuser
Copy link
Contributor Author

bjoernhaeuser commented Apr 21, 2018

This is now runnig for two weeks in our production setup and the error disappeared.

@bjoernhaeuser
Copy link
Contributor Author

bjoernhaeuser commented May 9, 2018

@jglick Could you lift your "Requested changes"?

@oleg-nenashev oleg-nenashev requested a review from jglick May 9, 2018
@oleg-nenashev oleg-nenashev changed the title [JENKINS-41880] Synchronise on project [JENKINS-41880] Synchronise on Fingerprint May 9, 2018
Copy link
Member

oleg-nenashev left a comment

LGTM, at least it should reduce the risk of race conditions significantly eve if there issues in lazy loading for fingerprints.

@jglick
jglick approved these changes May 10, 2018
@@ -257,6 +257,7 @@ public static void addFromFacet(@CheckForNull String ancestorImageId, @Nonnull S
long timestamp = System.currentTimeMillis();
if (ancestorImageId != null) {
Fingerprint f = forImage(run, ancestorImageId);
synchronized (f) {
Collection<FingerprintFacet> facets = f.getFacets();

This comment has been minimized.

Copy link
@jglick

jglick May 10, 2018

Member

The idea was to avoid touching every line in between, which makes diffs harder to read and complicates merges & cherry-picks.

@jglick
Copy link
Member

jglick commented May 10, 2018

@abayer I think you own this

@bjoernhaeuser
Copy link
Contributor Author

bjoernhaeuser commented May 10, 2018

Thanks everyone!

@abayer
Copy link
Member

abayer commented May 10, 2018

@jglick - I don't think so - I've literally never touched this plugin, don't have permissions on it, and am traveling/on vacation for the next two weeks. =)

@jglick jglick merged commit c38b852 into jenkinsci:master May 11, 2018
1 check passed
1 check passed
continuous-integration/jenkins/pr-merge This commit looks good
Details
@bjoernhaeuser bjoernhaeuser deleted the bjoernhaeuser:synchronise-on-project branch May 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

5 participants
You can’t perform that action at this time.