-
-
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
Adjusted TaskListener flushing in remote code #3961
Conversation
@@ -761,6 +761,7 @@ protected final void printCommandLine(@Nonnull String[] cmd, @CheckForNull FileP | |||
buf.append(c); | |||
} | |||
listener.getLogger().println(buf.toString()); | |||
listener.getLogger().flush(); |
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 this is commented out, ArgumentListBuilder2Test.slaveMask
fails (gets a blank string)—unless you start the test with
static {
System.setProperty("hudson.util.StreamTaskListener.AUTO_FLUSH", "true");
}
in which case it passes, demonstrating the effectiveness of the flag on the remote side.
@@ -376,27 +462,4 @@ public static Long getLong(String name, Long def, Level logLevel) { | |||
return def; | |||
} | |||
|
|||
@CheckForNull | |||
private static String tryGetValueFromContext(String key) { | |||
if (!JenkinsJVM.isJenkinsJVM()) { |
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.
Inverting control. This was always a bit hackish anyway. Amends #3362 to make agent-side calls work, not merely not crash.
*/ | ||
//TODO: Define a correct design of this engine later. Should be accessible in libs (remoting, stapler) and Jenkins modules too |
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.
Fixed for agents, and Jenkins modules should be able to use this already. If the need arises, we could move this into a standalone library usable from Remoting and Stapler, though I think these do well enough for now using Java Platform methods.
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { | ||
out = new PrintStream((OutputStream)in.readObject(),true); | ||
out = new PrintStream((OutputStream)in.readObject(), AUTO_FLUSH); |
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.
The meat of the change: switching auoFlush
on the remote copy from true
to (by default) false
.
// Take a snapshot of all system properties and context variables available on the master at the time the agent starts. | ||
allStrings = new HashMap<>(); | ||
allStrings.putAll(handler.getAllStrings()); | ||
allStrings.putAll((Map) System.getProperties()); // these take precedence |
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 understand correctly, this would mean that calling SystemProperties.getString("file.separator")
on the agent would actually get you the value from the master, which could be problematic if the agent is running a different OS than the master. Not necessarily a huge problem as long as anyone using SystemProperties
on an agent is careful to avoid reading machine/OS dependent properties, and the API is @Restricted(NoExternalUse.class)
, but maybe it would be safer to only copy properties whose keys contain hudson
or jenkins
in the name?
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.
calling
SystemProperties.getString("file.separator")
on the agent would actually get you the value from the master
No, because getString
will first check the local system properties. This snapshot is only used for fallbacks of variables not set on the agent.
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 don't think this should be a problem, since even on master you would get weird results today if part of your code relied on the System property value alone for a given key, while the rest takes into account the context variable. If the former is undefined, SystemProperties
might still have a value but System.getProperty
won't.
in one branch looks like a flake to me. |
FWIW, I ran
So, AFAICT not even the failure seen in CI. We'll see how the currently ongoing build goes. |
*/ | ||
//TODO: Define a correct design of this engine later. Should be accessible in libs (remoting, stapler) and Jenkins modules too | ||
@SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Currently Jenkins instance may have one ond only one context") |
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.
typo?
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 just @oleg-nenashev’s grammar, moved as is from line 85.
I suspect the flake manifests itself only under heavy load conditions, which would not be simulated by rerunning the test serially. |
This appears to be behaviour that manifests itself in Pipeline builds, and was fixed by jenkinsci/jenkins#3961. To ensure we don't lose buffered logs on Jenkins versions before 2.173, we now ensure the log is flushed after use on the remote agent.
Amends #3563 a bit. See discussion in jenkinsci/workflow-api-plugin#81.
StreamTaskListener
created on the master does not set thePrintStream.autoFlush
flag. So why would we do so on the remote side? That merely produces a flurry ofProxyOutputStream.Flush
packets. We expect that code flushes a stream when it is done with it. In fact from 2.121.x → 2.138.x for freestyle builds runningShell
I see introduced flush packets, from [JENKINS-52729] Launcher.ProcStarter.stdout(TaskListener) discards remotability #3563 I presume, which this PR corrects again.RemoteLaunchCallable
on the agent side produces aLocalLauncher
which produces aLocalProc
which usesStreamCopyThread
to forward stdout/stderr of the process. Yet as far as I can tell, this never flushed its sink unless you pass thecloseOut
flag (which no code in core does), meaning the tail end of log output could be lost if the sink were buffered. Freestyle builds have unbuffered logs, so probably this never mattered, but for JEP-210 I am finding that some buffering for Pipeline with local log storage is useful for performance reasons, and definitely for cloud log storage it is expected.Launcher
is not used in this way for durable tasks likesh
, but variousSynchronousNonBlockingStepExecution
s (and thus alsoSimpleBuildStep
s) use it.(The main pieces originally filed in #3703, but with a feature flag added.)
Proposed changelog entries
-Dhudson.util.StreamTaskListener.AUTO_FLUSH=true
to restore the previous behavior for freestyle builds. Note that Pipeline builds always expect remote flush.SystemProperties
may now be used from agent-side code.Desired reviewers
@jenkinsci/code-reviewers