-
-
Notifications
You must be signed in to change notification settings - Fork 9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FIXES JENKINS-28245] Allow finer-grained tuning of ChannelPinger. #1687
[FIXES JENKINS-28245] Allow finer-grained tuning of ChannelPinger. #1687
Conversation
@@ -136,6 +150,7 @@ public void onClosed(Channel channel, IOException cause) { | |||
}); | |||
|
|||
t.start(); | |||
LOGGER.fine("Ping thread started for " + channel + " with a " + interval + " minute interval"); | |||
LOGGER.fine("Ping thread started for " + channel + " with a " + | |||
intervalSeconds + " second interval and a " + timeoutSeconds + " second timeout."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also change to not have slow logging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by slow logging? Building up the string like that (including in case of FINE not actually being logged)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logger.log(Level.FINE, "This is a {0} {1} {2}", new Object[] {"paramaterised", "message", "in a log"});
Using this the string concatenation will not take place if the log is not enabled (whereas the code in ln187 will always perform String concatenation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Third argument should be array of argument objects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without benchmarking, I'd guess overhead for a string concatenation like this is going to be roughly comparable to the overhead of creating/GCing that object array, especially in the context of something that only happens once per slave connection, but I can swap to that.
(My main objection is the ugliness of losing the log-level convenience wrappers + needing to manually make the array... I really wish we'd just ship FormattingLogger as part of guava.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SC will be worse - as it still involves garbage collection for the implicit StringBuilder and Object/array creation is highly optimized
(I pine for slf4j....)
👍 for seconds
Do you mean slave.jar? |
No, slave.jar is the remoting jar, which is just enough to bootstrap the system. After that, the Jenkins master squirts its classes over the wire to the slave. |
private static final String INTERVAL_MINUTES_PROPERTY = ChannelPinger.class.getName() + ".pingInterval"; | ||
private static final String INTERVAL_SECONDS_PROPERTY = ChannelPinger.class.getName() + ".pingIntervalSeconds"; | ||
|
||
private static final int DEFAULT_TIMEOUT_SECONDS = Integer.getInteger(TIMEOUT_SECONDS_PROPERTY, 4 * 60); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not a "default" if it gets the value from a system property.
Also there is no other code change here or linked to call the new constructor outside of the no args constructor - so this adds confusion where the attempt is to reduce it.
Marked as WiP (comments from @jtnord ) |
9abf88c
to
3743bfe
Compare
@jtnord - Updated. I'd had the other constructor for tests (which I hadn't finished buttoning up), but ditched it since the test harness needs to be able to play with the system properties anyways. Added my test class to confirm that those properties are getting read & passed along, though it does NOT actually dig into the guts of the resulting PingThread like I'd originally intended. |
@oleg-nenashev 1) what marked? |
public SetUpRemotePing(int pingInterval) { | ||
this.pingInterval = pingInterval; | ||
static class SetUpRemotePing extends MasterToSlaveCallable<Void, IOException> { | ||
private final int pingTimeoutSeconds; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think (but may be mistaken) that this should have a serialVersionUID defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in the change description, it really isn't; these don't get persisted and re-read by potentially differently-compiled code, and remoting is already taking care of making master/slave run the same compiled bits with the JVM's same auto-rolled UID.
There are already plenty of Callables demonstrating this if you grep for MasterToSlaveCallable, e.g.:
https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/jenkins/util/VirtualFile.java#L417-L438
https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java#L52-L92
https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/jenkins/slaves/StandardOutputSwapper.java#L38-L74
https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/jenkins/model/Jenkins.java#L2048-L2052
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are issues with differences in JVM versions between master and slave. I have customer issues where not having a serialVersionUID defined has caused Jenkins to blow up (thankfully all of these cases were in plugins). Just because some instances of callables in Core have been lucky so far does not mean it is a safe pattern to follow.
In addition, assuming that the Jenkins core implementation of Remoting (with its current contract of classloaders) is the only implementation is a risky assumption. We have an alternative implementation for Master-to-Master communication which (for security reasons) does not allow remote class loading and as such the serialVersionUID must match for any callables that are transferred over that Channel. While we are not in a position to release that implementation at the present time, I know it is on our roadmap to release it in the future. It would be better if the habit of serialVersionUID alway was better applied in Core so that when we do open source this code we can set an earlier lower-bound on the Master version that the code applies to.
3743bfe
to
8c55dd2
Compare
<groupId>com.google.guava</groupId> | ||
<artifactId>guava-testlib</artifactId> | ||
<version>${guavaVersion}</version> | ||
<scope>test</scope> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry didn't notice this before but adding scope to a dependency in a dependency Management section is IMHO just evil (at some point you may want to actually depend on this thing and then all the transitive dependencies break - its also not clear in the using pom that it is using it at the right scope - and I have been bitten by this on one too many occasions now).
Other than that LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, good catch. Got my two poms mixed up there.
Updated!
* Allows customization in seconds, not minutes * Allows customization of the ping timeout (before, you could set a custom interval, but the timeout would always be PingThread's 4 minute default) This also drops the serialVersionUID from ChannelPinger.SetUpRemotePing; without one provided, the JVM will generate one on demand which is sufficient for the purposes here since these are never persisted and master & slave run the same compiled code. (And it demonstrably works since countless other MasterToSlaveCallables fail to specify their own custom IDs)
8c55dd2
to
b20f158
Compare
👍 |
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava-testlib</artifactId> | ||
<version>${guavaVersion}</version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I get the code correctly, it should be included in the test scope only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the above comments on the previous version where I'd had a mental hiccup and done just that. This is the big block that's specifying versions of things, and then it's scoped to test down in in core/pom.xml where it's actually consumed. (And then, anecdotally, it appears scoping inside dependencyManagement is completely ignored since core/pom.xml still successfully picked up a version number from the supposedly scoped definition here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed
👍 for the improvement BTW |
I think the serialVersionUID issue should be addressed, then this is ready to go. |
@deadmoose |
@deadmoose are you planning on finishing this PR? If not I propose to close it. I'll submit one with similar changes. |
Closing as superseded by #2645 where @deadmoose's work was preserved. Please @deadmoose feel totally free to tell us if you feel something should (have) be done differently here. Even in private if you prefer. Thanks for your work! |
custom interval, but the timeout would always be PingThread's 4
minute default)
This also drops the serialVersionUID from ChannelPinger.SetUpRemotePing;
without one provided, the JVM will generate one on demand which is
sufficient for the purposes here since these are never persisted and
master & slave run the same compiled code. (And it demonstrably works
since countless other MasterToSlaveCallables fail to specify their own
custom IDs)