Skip to content
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

[JENKINS-70531] Apply timeout on WebSocket write operations #7596

Merged
merged 7 commits into from Feb 5, 2023
Merged
18 changes: 13 additions & 5 deletions core/src/main/java/jenkins/agents/WebSocketAgents.java
Expand Up @@ -34,7 +34,6 @@
import hudson.remoting.AbstractByteBufferCommandTransport;
import hudson.remoting.Capability;
import hudson.remoting.ChannelBuilder;
import hudson.remoting.ChunkHeader;
import hudson.remoting.Engine;
import java.io.IOException;
import java.nio.ByteBuffer;
Expand All @@ -44,6 +43,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.slaves.JnlpAgentReceiver;
Expand Down Expand Up @@ -166,11 +166,19 @@ protected void error(Throwable cause) {

class Transport extends AbstractByteBufferCommandTransport {

Transport() {
super(true);
}

@Override
protected void write(ByteBuffer header, ByteBuffer data) throws IOException {
LOGGER.finest(() -> "sending message of length " + ChunkHeader.length(ChunkHeader.peek(header)));
sendBinary(header, false);
sendBinary(data, true);
protected void write(ByteBuffer headerAndData) throws IOException {
// As in Engine.runWebSocket:
LOGGER.finest(() -> "sending message of length " + (headerAndData.remaining() - 2));
try {
sendBinary(headerAndData).get(5, TimeUnit.MINUTES);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that any channel write operation should be under 5 minutes?

I know it's a bad practice, but what if a plugin is copying big files from the agent to the controller, that could easily take more than 5 minutes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean if you are using archiveArtifacts without artifact-manager-s3. Yes that could easily run over 5m for one copy operation; but this timeout is for one transport frame, which is currently only 8k (for WebSocket it could probably be increased considerably). Even one Command (broken into frames) would not necessarily be the full file size, since you would be using a RemoteOutputStream sending ProxyOutputStream.Chunks which default to 1Mb. (all IIUC, but certainly worth testing)

} catch (Exception x) {
throw new IOException(x);
}
}

@Override
Expand Down
3 changes: 2 additions & 1 deletion pom.xml
Expand Up @@ -87,7 +87,8 @@ THE SOFTWARE.
<changelog.url>https://www.jenkins.io/changelog</changelog.url>

<!-- Bundled Remoting version -->
<remoting.version>3085.vc4c6977c075a</remoting.version>
<!-- TODO https://github.com/jenkinsci/remoting/pull/621 -->
<remoting.version>3099.v6f431148cd72</remoting.version>
<!-- Minimum Remoting version, which is tested for API compatibility -->
<remoting.minimum.supported.version>4.7</remoting.minimum.supported.version>

Expand Down