Skip to content
This repository was archived by the owner on Nov 7, 2023. It is now read-only.

Commit 8b584be

Browse files
committed
adding a "retry loop" inside sendHTTPCall, so that if the connection failed... it will retry a certain amount of times before marking the build as failed.
1 parent 0f704da commit 8b584be

File tree

1 file changed

+60
-7
lines changed

1 file changed

+60
-7
lines changed

src/main/java/org/jenkinsci/plugins/ParameterizedRemoteTrigger/RemoteBuildConfiguration.java

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class RemoteBuildConfiguration extends Builder {
5656

5757
private final boolean shouldNotFailBuild;
5858
private final int pollInterval;
59+
private final int connectionRetryLimit = 5;
5960
private final boolean preventRemoteBuildQueue;
6061
private final boolean blockBuildUntilComplete;
6162

@@ -654,10 +655,38 @@ public String getBuildStatus(String buildUrlString, AbstractBuild build, BuildLi
654655
return buildStatus;
655656
}
656657

658+
/**
659+
* Orchestrates all calls to the remote server.
660+
* Also takes care of any credentials or failed-connection retries.
661+
*
662+
* @param urlString the URL that needs to be called
663+
* @param requestType the type of request (GET, POST, etc)
664+
* @param build the build that is being triggered
665+
* @param listener build listener
666+
* @return a valid JSON object, or null
667+
* @throws IOException
668+
*/
657669
public JSONObject sendHTTPCall(String urlString, String requestType, AbstractBuild build, BuildListener listener)
658670
throws IOException {
659-
RemoteJenkinsServer remoteServer = this.findRemoteHost(this.getRemoteJenkinsName());
671+
672+
return sendHTTPCall( urlString, requestType, build, listener, 1 );
673+
}
660674

675+
/**
676+
* Same as sendHTTPCall, but keeps track of the number of failed connection attempts (aka: the number of times this
677+
* method has been called).
678+
* In the case of a failed connection, the method calls it self recursively and increments numberOfAttempts
679+
*
680+
* @see sendHTTPCall
681+
* @param numberOfAttempts number of time that the connection has been attempted
682+
* @return
683+
* @throws IOException
684+
*/
685+
public JSONObject sendHTTPCall(String urlString, String requestType, AbstractBuild build, BuildListener listener, int numberOfAttempts)
686+
throws IOException {
687+
RemoteJenkinsServer remoteServer = this.findRemoteHost(this.getRemoteJenkinsName());
688+
int retryLimit = this.getConnectionRetryLimit();
689+
661690
if (remoteServer == null) {
662691
this.failBuild(new Exception("No remote host is defined for this job."), listener);
663692
return null;
@@ -693,6 +722,7 @@ public JSONObject sendHTTPCall(String urlString, String requestType, AbstractBui
693722
byte[] encodedAuthKey = Base64.encodeBase64(usernameTokenConcat.getBytes());
694723
connection.setRequestProperty("Authorization", "Basic " + new String(encodedAuthKey));
695724
}
725+
696726
try {
697727
connection.setDoInput(true);
698728
connection.setRequestProperty("Accept", "application/json");
@@ -729,13 +759,29 @@ public JSONObject sendHTTPCall(String urlString, String requestType, AbstractBui
729759
}
730760

731761
} catch (IOException e) {
732-
//If we get a 404 when trying to check a builds status (aka: called from "getBuildStatus") it just means that the build hasn't been queued up because there aren't any more executors available to call the remote server.
733-
//So we basically pretend like the error didn't happen.
734-
String callingMethod = Thread.currentThread().getStackTrace()[2].getMethodName();
735-
if(connection.getResponseCode() == 404 && callingMethod == "getBuildStatus"){
736-
return null;
762+
763+
//If we have connectionRetryLimit set to > 0 then retry that many times.
764+
if( numberOfAttempts <= retryLimit) {
765+
listener.getLogger().println("Connection to remote server failed, waiting for to retry - " + this.pollInterval + " seconds until next attempt.");
766+
767+
// Sleep for 'pollInterval' seconds.
768+
// Sleep takes miliseconds so need to convert this.pollInterval to milisecopnds (x 1000)
769+
try {
770+
// Could do with a better way of sleeping...
771+
Thread.sleep(this.pollInterval * 1000);
772+
} catch (InterruptedException ex) {
773+
this.failBuild(ex, listener);
774+
}
775+
776+
777+
listener.getLogger().println("Retry attempt #" + numberOfAttempts + " out of " + retryLimit );
778+
numberOfAttempts++;
779+
responseObject = sendHTTPCall(urlString, requestType, build, listener, numberOfAttempts);
780+
}else if(numberOfAttempts > retryLimit){
781+
//reached the maximum number of retries, time to fail
782+
this.failBuild(new Exception("Max number of connection retries have been exeeded."), listener);
737783
}else{
738-
//something failed with the connection, so throw an exception to mark the build as failed.
784+
//something failed with the connection and we retried the max amount of times... so throw an exception to mark the build as failed.
739785
this.failBuild(e, listener);
740786
}
741787

@@ -797,6 +843,13 @@ public int getPollInterval() {
797843
return this.pollInterval;
798844
}
799845

846+
/**
847+
* @return the connectionRetryLimit
848+
*/
849+
public int getConnectionRetryLimit() {
850+
return connectionRetryLimit;
851+
}
852+
800853
public String getToken() {
801854
return this.token;
802855
}

0 commit comments

Comments
 (0)