Skip to content

Commit 0d8a2af

Browse files
kohsukeoleg-nenashev
authored andcommitted
[JENKINS-39289] When a proxy fails, report what caused the channel to go down (#128)
Today, this requires out of bound knowledge about which connection the proxy was representing, then use other means to figure out why it has failed. This exception chaining shortens that step and makes it easy to find the cause as to why the channel was shut down.
1 parent 46c72a5 commit 0d8a2af

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

src/main/java/hudson/remoting/Channel.java

+34-5
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public class Channel implements VirtualChannel, IChannel, Closeable {
201201
* termination and simplify the circles into chains which can then be collected easily by the garbage collector.
202202
* @since FIXME after merge
203203
*/
204-
private final Ref reference = new Ref(this);
204+
private final Ref reference;
205205

206206
/**
207207
* Registered listeners.
@@ -491,6 +491,7 @@ public Channel(String name, ExecutorService exec, CommandTransport transport, bo
491491
*/
492492
protected Channel(ChannelBuilder settings, CommandTransport transport) throws IOException {
493493
this.name = settings.getName();
494+
this.reference = new Ref(this);
494495
this.executor = new InterceptingExecutorService(settings.getExecutors(),decorators);
495496
this.arbitraryCallableAllowed = settings.isArbitraryCallableAllowed();
496497
this.remoteClassLoadingAllowed = settings.isRemoteClassLoadingAllowed();
@@ -537,7 +538,7 @@ public void terminate(IOException e) {
537538
}
538539

539540
/**
540-
* Gets the {@link Ref} for this {@link Channel}. The {@link Ref} will be {@linkplain Ref#clear()}ed when
541+
* Gets the {@link Ref} for this {@link Channel}. The {@link Ref} will be {@linkplain Ref#clear(Exception)}ed when
541542
* the channel is terminated in order to break any complex object cycles.
542543
* @return the {@link Ref} for this {@link Channel}
543544
* @since FIXME after merge
@@ -896,7 +897,7 @@ public void terminate(IOException e) {
896897
}
897898
exportedObjects.abort(e);
898899
// break any object cycles into simple chains to simplify work for the garbage collector
899-
reference.clear();
900+
reference.clear(e);
900901
} finally {
901902
notifyAll();
902903
}
@@ -1703,17 +1704,29 @@ protected int[] initialValue() {
17031704
* @see #reference
17041705
*/
17051706
/*package*/ static final class Ref {
1707+
/**
1708+
* @see {@link Channel#getName()}
1709+
*/
1710+
@Nonnull
1711+
private final String name;
1712+
17061713
/**
17071714
* The channel.
17081715
*/
17091716
@CheckForNull
17101717
private Channel channel;
17111718

1719+
/**
1720+
* If the channel is cleared, retain the reason channel was closed to assist diagnostics.
1721+
*/
1722+
private Exception cause;
1723+
17121724
/**
17131725
* Constructor.
17141726
* @param channel the {@link Channel}.
17151727
*/
17161728
private Ref(@CheckForNull Channel channel) {
1729+
this.name = channel.getName();
17171730
this.channel = channel;
17181731
}
17191732

@@ -1726,12 +1739,28 @@ public Channel channel() {
17261739
return channel;
17271740
}
17281741

1742+
/**
1743+
* If the channel is null, return the cause of the channel termination.
1744+
*/
1745+
public Exception cause() {
1746+
return cause;
1747+
}
1748+
1749+
/**
1750+
* @see Channel#getName()
1751+
*/
1752+
@Nonnull
1753+
public String name() {
1754+
return name;
1755+
}
1756+
17291757
/**
17301758
* Clears the {@link #channel} to signify that the {@link Channel} has been closed and break any complex
17311759
* object cycles that might prevent the full garbage collection of the channel's associated object tree.
17321760
*/
1733-
public void clear() {
1734-
channel = null;
1761+
public void clear(Exception cause) {
1762+
this.channel = null;
1763+
this.cause = cause;
17351764
}
17361765

17371766
/**

src/main/java/hudson/remoting/RemoteInvocationHandler.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,15 @@ private Channel channel() {
182182
*/
183183
@Nonnull
184184
private Channel channelOrFail() throws IOException {
185-
final Channel channel = channel();
186-
if (channel == null) {
187-
throw new IOException("Backing channel is disconnected.");
185+
final Ref ch = this.channel;
186+
if (ch == null) {
187+
throw new IOException("Not connected to any channel");
188+
}
189+
Channel c = ch.channel();
190+
if (c == null) {
191+
throw new IOException("Backing channel '"+ch.name()+"' is disconnected.",ch.cause());
188192
}
189-
return channel;
193+
return c;
190194
}
191195

192196
/**

0 commit comments

Comments
 (0)