Skip to content

Commit

Permalink
[FIXED JENKINS-38539] Turn on SO_KEEPALIVE and provide CLI option to …
Browse files Browse the repository at this point in the history
…turn it off again

- Most OSes have a default SO_KEEPALIVE of 2 hours, and perform keepalive without generating any significant traffic
  The master side of the connection already has SO_KEEPALIVE enabled, this just allows both OSes to keep their own
  guidance and therefore assist when tuning the agent side is more appropriate than changing the kernel parameters on
  the master side (as the master is handling the HTTP requests of users)
- Would probably be perfectly safe to not even expose the -noKeepAlive option as the SO_KEEPALIVE should be invisible
  But there may be users that have the requirement to disable, so safer to provide the option
- Change was developed against the stable-2.x branch
  • Loading branch information
stephenc committed Sep 27, 2016
1 parent 4f01088 commit ca87021
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/main/java/hudson/remoting/Engine.java
Expand Up @@ -138,6 +138,13 @@ public void run() {

private boolean noReconnect;

/**
* Determines whether the socket will have {@link Socket#setKeepAlive(boolean)} set or not.
*
* @since TODO
*/
private boolean keepAlive = true;

private JarCache jarCache = new FileSystemJarCache(new File(System.getProperty("user.home"),".jenkins/cache/jars"),true);

public Engine(EngineListener listener, List<URL> hudsonUrls, String secretKey, String slaveName) {
Expand Down Expand Up @@ -178,6 +185,24 @@ public void setNoReconnect(boolean noReconnect) {
this.noReconnect = noReconnect;
}

/**
* Returns {@code true} if and only if the socket to the master will have {@link Socket#setKeepAlive(boolean)} set.
*
* @return {@code true} if and only if the socket to the master will have {@link Socket#setKeepAlive(boolean)} set.
*/
public boolean isKeepAlive() {
return keepAlive;
}

/**
* Sets the {@link Socket#setKeepAlive(boolean)} to use for the connection to the master.
*
* @param keepAlive the {@link Socket#setKeepAlive(boolean)} to use for the connection to the master.
*/
public void setKeepAlive(boolean keepAlive) {
this.keepAlive = keepAlive;
}

public void setCandidateCertificates(List<X509Certificate> candidateCertificates) {
this.candidateCertificates = candidateCertificates == null
? null
Expand Down Expand Up @@ -409,6 +434,7 @@ private Socket connect(@CheckForNull String host, @CheckForNull String port) thr
s.connect(targetAddress);

s.setTcpNoDelay(true); // we'll do buffering by ourselves
s.setKeepAlive(keepAlive);

// set read time out to avoid infinite hang. the time out should be long enough so as not
// to interfere with normal operation. the main purpose of this is that when the other peer dies
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/hudson/remoting/Launcher.java
Expand Up @@ -189,6 +189,10 @@ public boolean verify(String s, SSLSession sslSession) {
@Option(name="-noReconnect",usage="Doesn't try to reconnect when a communication fail, and exit instead")
public boolean noReconnect = false;

@Option(name = "-noKeepAlive",
usage = "Do not open the socket to the master with SO_KEEPALIVE enabled")
public boolean noKeepAlive = false;

public static void main(String... args) throws Exception {
Launcher launcher = new Launcher();
CmdLineParser parser = new CmdLineParser(launcher);
Expand Down Expand Up @@ -229,6 +233,9 @@ public void run() throws Exception {
if (this.noReconnect) {
jnlpArgs.add("-noreconnect");
}
if (this.noKeepAlive) {
jnlpArgs.add("-noKeepAlive");
}
try {
hudson.remoting.jnlp.Main._main(jnlpArgs.toArray(new String[jnlpArgs.size()]));
} catch (CmdLineException e) {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/hudson/remoting/jnlp/Main.java
Expand Up @@ -85,6 +85,10 @@ public class Main {
usage="If the connection ends, don't retry and just exit.")
public boolean noReconnect = false;

@Option(name="-noKeepAlive",
usage="Do not open the socket to the master with SO_KEEPALIVE enabled")
public boolean noKeepAlive = false;

@Option(name = "-cert",
usage = "Specify additional X.509 encoded PEM certificates to trust when connecting to Jenkins " +
"root URLs. If starting with @ then the remainder is assumed to be the name of the " +
Expand Down Expand Up @@ -173,6 +177,7 @@ public Engine createEngine() {
if(jarCache!=null)
engine.setJarCache(new FileSystemJarCache(jarCache,true));
engine.setNoReconnect(noReconnect);
engine.setKeepAlive(!noKeepAlive);
if (candidateCertificates != null && !candidateCertificates.isEmpty()) {
CertificateFactory factory;
try {
Expand Down

0 comments on commit ca87021

Please sign in to comment.