Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-48070

Re-entrant calls in a load() groovy script jump to top of lock not top of function

      I've got a groovy script that I call using load() in my Jenkinsfile. I needed it to call itself with a different parameter when exception handling. However, it doesn't call itself in a way you would expect:

      def call(in_path) {
      timeout(1) {
        def my_path = in_path
      
        print "Start of call(${my_path}) FINDMEAGAIN"
        lock ("mylock") {
          print "Start of call(${my_path}):lock block"
          try {
            print "Start of call(${my_path}):try block"
            error "Nope!"
          } catch (err) {
            print "In Exception - calling self"
            def my_pathp = my_path + "X"
            if (my_pathp.length() < 50) {
              print "Calling call(${my_pathp})"
              call(my_pathp)
            }
            print "Back to call(${my_path})"
          }
        }
        return null
      }
      }
      

      You would expect to see the FINDMEAGAIN in the console multiple times. Or you would expect the lock to hang trying to re-lock. Instead, I get this:

      Start of call(rpms/centos7) FINDMEAGAIN
      [Pipeline] lock
      Trying to acquire lock on [mylock]
      Lock acquired on [mylock]
      [Pipeline] {
      [Pipeline] echo
      Start of call(rpms/centos7):lock block
      [Pipeline] echo
      Start of call(rpms/centos7):try block
      [Pipeline] error
      [Pipeline] echo
      In Exception - calling self
      [Pipeline] echo
      Calling call(rpms/centos7X)
      [Pipeline] echo
      Start of call(rpms/centos7):lock block
      [Pipeline] echo
      Start of call(rpms/centos7):try block
      [Pipeline] error
      [Pipeline] echo
      In Exception - calling self
      [Pipeline] echo
      Calling call(rpms/centos7X)
      [Pipeline] echo
      Start of call(rpms/centos7):lock block
      [Pipeline] echo
      Start of call(rpms/centos7):try block
      [Pipeline] error
      [Pipeline] echo
      In Exception - calling self
      

      This repeats until a stack overflow. I assume the variables not changing is a groovy thing concerning references vs copies or something, but that doesn't explain why the call is not going to the top.

      In experimenting, I found that if this snippet wasn't in call(), but something defined above it and called within, it worked as expected.

          [JENKINS-48070] Re-entrant calls in a load() groovy script jump to top of lock not top of function

          Aaron D. Marasco created issue -
          Claes Buckwalter made changes -
          Description Original: I've got a groovy script that I call using {{load()}} in my {{Jenkinsfile}}. I needed it to call itself with a different parameter when exception handling. However, it doesn't call itself in a way you would expect:

          {code:java}
          def call(in_path) {
          timeout(1) {
            def my_path = in_path

            print "Start of call(${my_path}) FINDMEAGAIN"
            lock ("mylock") {
              print "Start of call(${my_path}):lock block"
              try {
                print "Start of call(${my_path}):try block"
                error "Nope!"
              } catch (err) {
                print "In Exception - calling self"
                def my_pathp = my_path + "X"
                if (my_pathp.length() < 50) {
                  print "Calling call(${my_pathp})"
                  call(my_pathp)
                }
                print "Back to call(${my_path})"
              }
            }
            return null
          }
          }
          {code}

          You would expect to see the {{FINDMEAGAIN}} in the console multiple times. Or you would expect the {{lock}} to hang trying to re-lock. Instead, I get this:
          {noformat}
          Start of call(rpms/centos7) FINDMEAGAIN
          [Pipeline] lock
          Trying to acquire lock on [mylock]
          Lock acquired on [mylock]
          [Pipeline] {
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          [Pipeline] echo
          Calling call(rpms/centos7X)
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          [Pipeline] echo
          Calling call(rpms/centos7X)
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          {noformat}

          This repeats until a stack overflow. I assume the variables not changing is a groovy thing concerning references vs copies or something, but that doesn't explain why the call is not going to the top.

          In experimenting, I found that if this snippet wasn't in {{call()}}, but something defined above it and called within, it worked as expected.
          New: I've got a groovy script that I call using {{load()}} in my {{Jenkinsfile}}. I needed it to call itself with a different parameter when exception handling. However, it doesn't call itself in a way you would expect:
          {code:java}
          def call(in_path) {
          timeout(1) {
            def my_path = in_path

            print "Start of call(${my_path}) FINDMEAGAIN"
            lock ("mylock") {
              print "Start of call(${my_path}):lock block"
              try {
                print "Start of call(${my_path}):try block"
                error "Nope!"
              } catch (err) {
                print "In Exception - calling self"
                def my_pathp = my_path + "X"
                if (my_pathp.length() < 50) {
                  print "Calling call(${my_pathp})"
                  call(my_pathp)
                }
                print "Back to call(${my_path})"
              }
            }
            return null
          }
          }
          {code}
          You would expect to see the {{FINDMEAGAIN}} in the console multiple times. Or you would expect the {{lock}} to hang trying to re-lock. Instead, I get this:
          {noformat}
          Start of call(rpms/centos7) FINDMEAGAIN
          [Pipeline] lock
          Trying to acquire lock on [mylock]
          Lock acquired on [mylock]
          [Pipeline] {
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          [Pipeline] echo
          Calling call(rpms/centos7X)
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          [Pipeline] echo
          Calling call(rpms/centos7X)
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          {noformat}
          This repeats until a stack overflow. I assume the variables not changing is a groovy thing concerning references vs copies or something, but that doesn't explain why the call is not going to the top.

          In experimenting, I found that if this snippet wasn't in {{call()}}, but something defined above it and called within, it worked as expected.j
          Aaron D. Marasco made changes -
          Description Original: I've got a groovy script that I call using {{load()}} in my {{Jenkinsfile}}. I needed it to call itself with a different parameter when exception handling. However, it doesn't call itself in a way you would expect:
          {code:java}
          def call(in_path) {
          timeout(1) {
            def my_path = in_path

            print "Start of call(${my_path}) FINDMEAGAIN"
            lock ("mylock") {
              print "Start of call(${my_path}):lock block"
              try {
                print "Start of call(${my_path}):try block"
                error "Nope!"
              } catch (err) {
                print "In Exception - calling self"
                def my_pathp = my_path + "X"
                if (my_pathp.length() < 50) {
                  print "Calling call(${my_pathp})"
                  call(my_pathp)
                }
                print "Back to call(${my_path})"
              }
            }
            return null
          }
          }
          {code}
          You would expect to see the {{FINDMEAGAIN}} in the console multiple times. Or you would expect the {{lock}} to hang trying to re-lock. Instead, I get this:
          {noformat}
          Start of call(rpms/centos7) FINDMEAGAIN
          [Pipeline] lock
          Trying to acquire lock on [mylock]
          Lock acquired on [mylock]
          [Pipeline] {
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          [Pipeline] echo
          Calling call(rpms/centos7X)
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          [Pipeline] echo
          Calling call(rpms/centos7X)
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          {noformat}
          This repeats until a stack overflow. I assume the variables not changing is a groovy thing concerning references vs copies or something, but that doesn't explain why the call is not going to the top.

          In experimenting, I found that if this snippet wasn't in {{call()}}, but something defined above it and called within, it worked as expected.j
          New: I've got a groovy script that I call using {{load()}} in my {{Jenkinsfile}}. I needed it to call itself with a different parameter when exception handling. However, it doesn't call itself in a way you would expect:
          {code:java}
          def call(in_path) {
          timeout(1) {
            def my_path = in_path

            print "Start of call(${my_path}) FINDMEAGAIN"
            lock ("mylock") {
              print "Start of call(${my_path}):lock block"
              try {
                print "Start of call(${my_path}):try block"
                error "Nope!"
              } catch (err) {
                print "In Exception - calling self"
                def my_pathp = my_path + "X"
                if (my_pathp.length() < 50) {
                  print "Calling call(${my_pathp})"
                  call(my_pathp)
                }
                print "Back to call(${my_path})"
              }
            }
            return null
          }
          }
          {code}
          You would expect to see the {{FINDMEAGAIN}} in the console multiple times. Or you would expect the {{lock}} to hang trying to re-lock. Instead, I get this:
          {noformat}
          Start of call(rpms/centos7) FINDMEAGAIN
          [Pipeline] lock
          Trying to acquire lock on [mylock]
          Lock acquired on [mylock]
          [Pipeline] {
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          [Pipeline] echo
          Calling call(rpms/centos7X)
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          [Pipeline] echo
          Calling call(rpms/centos7X)
          [Pipeline] echo
          Start of call(rpms/centos7):lock block
          [Pipeline] echo
          Start of call(rpms/centos7):try block
          [Pipeline] error
          [Pipeline] echo
          In Exception - calling self
          {noformat}
          This repeats until a stack overflow. I assume the variables not changing is a groovy thing concerning references vs copies or something, but that doesn't explain why the call is not going to the top.

          In experimenting, I found that if this snippet wasn't in {{call()}}, but something defined above it and called within, it worked as expected.

            Unassigned Unassigned
            aarondmarasco_vsi Aaron D. Marasco
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: