Ivy
  1. Ivy
  2. IVY-1454

OverlappingFileLockException when using artifact-lock-nio

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.4.0
    • Fix Version/s: 2.4.0-RC1
    • Component/s: Core
    • Labels:
      None
    • Environment:

      Debian Linux (Wheezy)
      Oracle Java 1.7.0+update45,
      ivy_2.4.0.alpha_20131214174343.jar downloaded from https://builds.apache.org/job/Ivy/446/

      Description

      When trying to use artifact-lock-nio as the lock strategy, I get resolve errors due to OverlappingFileLockException being thrown:

      [ivy:resolve] WARN: 	:: org.hamcrest#hamcrest-core;1.1: java.nio.channels.OverlappingFileLockException at sun.nio.ch.SharedFileLockTable.checkList(FileLockTable.java:255)
      [ivy:resolve] WARN: 	:: org.glassfish#javax.ejb;3.1: java.nio.channels.OverlappingFileLockException at sun.nio.ch.SharedFileLockTable.checkList(FileLockTable.java:255)
      [ivy:resolve] WARN: 	:: org.jboss.weld.se#weld-se-core;1.1.10.Final: java.nio.channels.OverlappingFileLockException at sun.nio.ch.SharedFileLockTable.checkList(FileLockTable.java:255)
      

      The reason is probably related to our use of the <parallel> and <antcallback> tasks. The documentation of the antcallback task is here: http://ant-contrib.sourceforge.net/tasks/tasks/antcallback_task.html

      <parallel threadcount="${tests.maxThreads}">
      	<antcallback target="testsomething" return="tests.failed"/>
      	<antcallback target="testsomeother" return="tests.failed"/>
      	<antcallback target="testsomemore" return="tests.failed"/>
      </parallel>
      

      All the testxxx targets perform a resolve before running some junit tests in a separate vm. These resolve calls appear to cause the OverlappingFileLockException.

      1. IVY-1454-r3.patch
        10 kB
        Charles Duffy
      2. test--IVY-1454.zip
        3 kB
        Carsten Pfeiffer

        Activity

        Hide
        Carsten Pfeiffer added a comment -

        Another problem with that strategy is that it leaves lock files in the cache when the build fails.

        Show
        Carsten Pfeiffer added a comment - Another problem with that strategy is that it leaves lock files in the cache when the build fails.
        Hide
        Charles Duffy added a comment - - edited

        Leaving (unlocked) lock files in the cache is actually correct behavior for flock/fcntl-type locking. This ensures that anyone creating a new lock is doing so against the same inode(s).

        That said, these should be left behind unconditionally, not only on failure.

        Show
        Charles Duffy added a comment - - edited Leaving (unlocked) lock files in the cache is actually correct behavior for flock/fcntl-type locking. This ensures that anyone creating a new lock is doing so against the same inode(s). That said, these should be left behind unconditionally, not only on failure.
        Hide
        Carsten Pfeiffer added a comment -

        I see. I had some other resolve failures and thought they were related to the lock files. I'll monitor this.

        Show
        Carsten Pfeiffer added a comment - I see. I had some other resolve failures and thought they were related to the lock files. I'll monitor this.
        Hide
        Charles Duffy added a comment -

        I'm trying to generate a minimal reproducer and failing thus far. For instance, the following works perfectly:

        (ns ivy-lock-test.core
          (:import [org.apache.ivy.plugins.lock NIOFileLockStrategy]))
        
        (def strategy (NIOFileLockStrategy. true))
        (defn with-lock [file run-fn]
          (try
            (.lockArtifact strategy nil file)
            (run-fn)
            (finally
              (.unlockArtifact strategy nil file))))
        
        (defn artificially-slow-fn []
          (Thread/sleep 500))
        
        (pmap
         (partial with-lock (java.io.File. "/tmp/test-lockfile"))
         (take 100 (repeat artificially-slow-fn)))
        
        Show
        Charles Duffy added a comment - I'm trying to generate a minimal reproducer and failing thus far. For instance, the following works perfectly: (ns ivy-lock-test.core (: import [org.apache.ivy.plugins.lock NIOFileLockStrategy])) (def strategy (NIOFileLockStrategy. true )) (defn with-lock [file run-fn] ( try (.lockArtifact strategy nil file) (run-fn) ( finally (.unlockArtifact strategy nil file)))) (defn artificially-slow-fn [] ( Thread /sleep 500)) (pmap (partial with-lock (java.io.File. "/tmp/test-lockfile" )) (take 100 (repeat artificially-slow-fn)))
        Hide
        Charles Duffy added a comment -

        ...actually, if there's a process boundary between the parent process that first grabs the lock and the child process that tries to hold it concurrently, this would make a great deal of sense.

        TODO: investigate implementation of antcallback, and whether it involves subprocess execution.

        Show
        Charles Duffy added a comment - ...actually, if there's a process boundary between the parent process that first grabs the lock and the child process that tries to hold it concurrently, this would make a great deal of sense. TODO: investigate implementation of antcallback, and whether it involves subprocess execution.
        Hide
        Carsten Pfeiffer added a comment -

        This is a testproject that reproduces the error. It's just a <parallel> task with multiple <ivy:resolve> tasks being called.

        Just run the supplied build.xml.

        Show
        Carsten Pfeiffer added a comment - This is a testproject that reproduces the error. It's just a <parallel> task with multiple <ivy:resolve> tasks being called. Just run the supplied build.xml.
        Hide
        Charles Duffy added a comment -

        Please test the proposed patch.

        Show
        Charles Duffy added a comment - Please test the proposed patch.
        Hide
        Charles Duffy added a comment -

        Sorry – withdrawing that first rev. Another to follow.

        Show
        Charles Duffy added a comment - Sorry – withdrawing that first rev. Another to follow.
        Hide
        Charles Duffy added a comment -

        Withdrawing proposed patch again.

        Show
        Charles Duffy added a comment - Withdrawing proposed patch again.
        Hide
        Charles Duffy added a comment -

        Somehow, despite still adding a "X must be static" comment, the static keyword got lost between r2 of the patch being tested and posted.

        r3 puts it back.

        Thank you again for the very helpful test case, and please accept my apologies for the churn.

        Show
        Charles Duffy added a comment - Somehow, despite still adding a "X must be static" comment, the static keyword got lost between r2 of the patch being tested and posted. r3 puts it back. Thank you again for the very helpful test case, and please accept my apologies for the churn.
        Hide
        Charles Duffy added a comment -

        Committed a final implementation (w/ a permanent addition to the full test suite) in r1552434.

        Show
        Charles Duffy added a comment - Committed a final implementation (w/ a permanent addition to the full test suite) in r1552434.

          People

          • Assignee:
            Charles Duffy
            Reporter:
            Carsten Pfeiffer
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development