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

Interrupting a synchronous remote call should `Thread.interrupt` the corresponding thread on the remote side

      Interrupting a synchronous remote call should `Thread.interrupt` the corresponding thread on the remote side. 

      I'm working on a plugin (builder) that I want to make compatible with master/slave setup and looks like if a user cancels the build from the master my plugin does not get interrupted and still gets executed until the end and only then the job is marked as canceled even tough it still finished doing everything.

       
      The flow of the plugin is basically like this:
       

      public void perform(@Nonnull Run<?, ?> build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws IOException {
           launcher.getChannel().call(deployCallable);
      }

       
      deployCallable is an instance of a inner class described bellow:
       

      private static class DeployCallable extends MasterToSlaveCallable<Boolean, InterruptedException> { // So it works in master/slave setup
          private static final long serialVersionUID = 1L;
      
          public Boolean call() throws InterruptedException { 
              for folder in path { 
                  zip(folder); 
              } 
      
              for zip in zipFiles {
                  upload(zip); // Using Apache HTTP Client
              }
          }
      }
      

       
      In this case the problem is that that if I click cancel on the job it still runs until the build step is finished and all files are zipped and uploaded and only then it marks the build as aborted. 

          [JENKINS-46705] Interrupting a synchronous remote call should `Thread.interrupt` the corresponding thread on the remote side

          Oleg Nenashev added a comment -

          Not sure about interrupting the thread, but I agree it makes sense to enforce termination on the remote side

          Oleg Nenashev added a comment - Not sure about interrupting the thread, but I agree it makes sense to enforce termination on the remote side

          Any way that would make being able to handle interrupting the job would be good so that it doesn't continue executing until it finished everything when you actually canceled it after a few seconds.

          Daniel Anechitoaie added a comment - Any way that would make being able to handle interrupting the job would be good so that it doesn't continue executing until it finished everything when you actually canceled it after a few seconds.

          Oleg Nenashev added a comment -

          Actually the termination should already happen: https://github.com/jenkinsci/remoting/blob/a1294d6fd5e0053098a532488aca02586c02a887/src/main/java/hudson/remoting/Request.java#L196-L203 . Probably I should add some logging, so we could understand why it does not happen in your case.

          Any chance that the plugin suppresses `InterruptedException` somewhere?

          Oleg Nenashev added a comment - Actually the termination should already happen: https://github.com/jenkinsci/remoting/blob/a1294d6fd5e0053098a532488aca02586c02a887/src/main/java/hudson/remoting/Request.java#L196-L203 . Probably I should add some logging, so we could understand why it does not happen in your case. Any chance that the plugin suppresses `InterruptedException` somewhere?

          Daniel Anechitoaie added a comment - Here's the code for the plugin: https://github.com/jenkinsci/osf-builder-suite-for-sfcc-deploy-plugin/blob/master/src/main/java/org/jenkinsci/plugins/osfbuildersuiteforsfcc/deploy/DeployBuilder.java#L468 I'm not suppressing InterruptedException.

          Let me do some more testing on my side. And I'll come back with more feedback. I need to make sure I don't do something wrong.

           

          I have one question, can I make "MasterToSlaveCallable<Boolean, InterruptedException> {" be able to throw two exceptions? As I'd like to continue letting it throw InterruptedException so users can cancel it, but also I should be able to throw AbortException in case of an error to stop the build, no?

          As from what I see returning true/false is deprecated.

          Daniel Anechitoaie added a comment - Let me do some more testing on my side. And I'll come back with more feedback. I need to make sure I don't do something wrong.   I have one question, can I make "MasterToSlaveCallable<Boolean, InterruptedException> {" be able to throw two exceptions? As I'd like to continue letting it throw InterruptedException so users can cancel it, but also I should be able to throw AbortException in case of an error to stop the build, no? As from what I see returning true/false is deprecated.

          oleg_nenashev I have this code https://github.com/jenkinsci/osf-builder-suite-for-sfcc-deploy-plugin/blob/master/src/main/java/org/jenkinsci/plugins/osfbuildersuiteforsfcc/deploy/DeployBuilder.java#L410

           

          And I'm not catching the InterruptedException anywhere but when I stop from master job still continues until finished and only at end build is marked as canceled.

           

          I'm not sure if I'm doing something wrong in the code but I've tried all I can think of and it's not working.

          If I move the code from the MasterToSlaveCallable<Void, IOException> class directly inside the perform function then I can cancel the job while it's in progress but it's no longer master/slave distributed compatible.

          Daniel Anechitoaie added a comment - oleg_nenashev I have this code https://github.com/jenkinsci/osf-builder-suite-for-sfcc-deploy-plugin/blob/master/src/main/java/org/jenkinsci/plugins/osfbuildersuiteforsfcc/deploy/DeployBuilder.java#L410   And I'm not catching the InterruptedException anywhere but when I stop from master job still continues until finished and only at end build is marked as canceled.   I'm not sure if I'm doing something wrong in the code but I've tried all I can think of and it's not working. If I move the code from the MasterToSlaveCallable<Void, IOException> class directly inside the perform function then I can cancel the job while it's in progress but it's no longer master/slave distributed compatible.

          Oleg Nenashev added a comment -

          Have you tried debugging the behavior on the agent side as I suggested in the mailing list?

          Oleg Nenashev added a comment - Have you tried debugging the behavior on the agent side as I suggested in the mailing list?

          Not yet. I'm not really sure ow to do this. I'll try and see what I can do.

          Currently I was just running it with "mvn hpi:run". So not with a real slave agent.

          Should't it work both ways? (both when you just have the master and when you have master/slave).

           

          Daniel Anechitoaie added a comment - Not yet. I'm not really sure ow to do this. I'll try and see what I can do. Currently I was just running it with "mvn hpi:run". So not with a real slave agent. Should't it work both ways? (both when you just have the master and when you have master/slave).  

          I've tried multiple things but still can't get it working or figure out why it's not working.

           

          I get this exception:

          java.lang.InterruptedException
          at hudson.model.Build$BuildExecution.build(Build.java:213)
          at hudson.model.Build$BuildExecution.doRun(Build.java:162)
          at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:534)
          at hudson.model.Run.execute(Run.java:1728)
          at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
          at hudson.model.ResourceController.execute(ResourceController.java:98)
          at hudson.model.Executor.run(Executor.java:404)

           

          So looks like it's there, but still this happens after my build step finishes and I can't cancel it while it's in progress.

           

          oleg_nenashev Any idea if there's any plugin that implements a build step and that can be interrupted/cancelled?  So I can look at that plugin source code and understand what needs to be done.

          Daniel Anechitoaie added a comment - I've tried multiple things but still can't get it working or figure out why it's not working.   I get this exception: java.lang.InterruptedException at hudson.model.Build$BuildExecution.build(Build.java:213) at hudson.model.Build$BuildExecution.doRun(Build.java:162) at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:534) at hudson.model.Run.execute(Run.java:1728) at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43) at hudson.model.ResourceController.execute(ResourceController.java:98) at hudson.model.Executor.run(Executor.java:404)   So looks like it's there, but still this happens after my build step finishes and I can't cancel it while it's in progress.   oleg_nenashev Any idea if there's any plugin that implements a build step and that can be interrupted/cancelled?  So I can look at that plugin source code and understand what needs to be done.

            Unassigned Unassigned
            danechitoaie Daniel Anechitoaie
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: