Skip to content
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion core/src/main/java/hudson/slaves/SlaveComputer.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ public class SlaveComputer extends Computer {
*/
private final TaskListener taskListener;

/**
* Flag to ensure afterDisconnect() is called only once per connection.
*/

private volatile boolean afterDisconnectCalled = false;


/**
* Number of failed attempts to reconnect to this node
Expand Down Expand Up @@ -650,6 +656,7 @@ public void onClosed(Channel c, IOException cause) {
Functions.printStackTrace(cause, taskListener.error("Connection terminated"));
}
closeChannel();
safeAfterDisconnect(); // changed from direct call to safe method to avoid multiple calls
try {
launcher.afterDisconnect(SlaveComputer.this, taskListener);
} catch (Throwable t) {
Expand Down Expand Up @@ -745,6 +752,10 @@ public void onClosed(Channel c, IOException cause) {
this.absoluteRemoteFs = remoteFS;
defaultCharset = Charset.forName(defaultCharsetName);

// Reset the flag for the new connection

afterDisconnectCalled = false;

synchronized (statusChangeLock) {
statusChangeLock.notifyAll();
}
Expand All @@ -769,6 +780,25 @@ public void onClosed(Channel c, IOException cause) {
Jenkins.get().getQueue().scheduleMaintenance();
}

private void safeAfterDisconnect() {
if(!afterDisconnectCalled){
synchronized (this){
if(!afterDisconnectCalled){
afterDisconnectCalled = true;
try{
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

Add spaces around braces to follow standard Java formatting conventions. This block should be formatted as 'try {' instead of 'try{'.

Suggested change
try{
try {

Copilot uses AI. Check for mistakes.
launcher.afterDisconnect(SlaveComputer.this, taskListener);
} catch (Throwable t){
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

Add space before opening brace to follow standard Java formatting conventions. It should be '} catch (Throwable t) {' instead of '} catch (Throwable t){'.

Suggested change
} catch (Throwable t){
} catch (Throwable t) {

Copilot uses AI. Check for mistakes.
LogRecord lr = new LogRecord(Level.SEVERE,
"Launcher {0}'s afterDisconnect method propagated an exception when {1}'s connection was closed: {2}");
lr.setThrown(t);
lr.setParameters(new Object[]{launcher, SlaveComputer.this.getName(), t.getMessage()});
logger.log(lr);
}
}
}
}
}

@Override
public Channel getChannel() {
return channel;
Expand Down Expand Up @@ -825,7 +855,8 @@ public void run() {
// (which could be typical) won't block UI thread.
launcher.beforeDisconnect(SlaveComputer.this, taskListener);
closeChannel();
launcher.afterDisconnect(SlaveComputer.this, taskListener);
safeAfterDisconnect();
// launcher.afterDisconnect(SlaveComputer.this, taskListener);
}
});
}
Expand Down
Loading