Browse Source

Improve Network.shutdown() and logging in Peer.

Network.shutdown() called Peer.shutdown() on each Peer
while holding synchronization lock on this.connectedPeers.

This would cause a problem during Peer.shutdown() as some
other reachable code would also want synchronized access
to this.connectedPeers. Typical symptoms would be log
entries like:

2019-07-02 11:13:05 DEBUG Peer:512 - Message processor for peer 192.144.182.73:9889 failed to terminate

Eventually Network.shutdown() would exit, releasing synchronization
lock and awaking stuck Peer threads, which could then try to access
repository (now closed) causing further log spam.

Now it uses Network.getConnectedPeers to return duplicated
List<Peer>, minimizing lock time on this.connectedPeers.

Also made Peer main thread logging more informative when a IOException
occurs, as most situations are harmless EOF or connection reset by peer.
pull/67/head
catbref 5 years ago
parent
commit
7b51b1e88d
  1. 4
      src/main/java/org/qora/network/Network.java
  2. 15
      src/main/java/org/qora/network/Peer.java

4
src/main/java/org/qora/network/Network.java

@ -963,10 +963,8 @@ public class Network extends Thread {
}
// Close all peer connections
synchronized (this.connectedPeers) {
for (Peer peer : this.connectedPeers)
for (Peer peer : this.getConnectedPeers())
peer.shutdown();
}
}
}

15
src/main/java/org/qora/network/Peer.java

@ -1,6 +1,7 @@
package org.qora.network;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
@ -369,10 +370,20 @@ public class Peer extends Thread {
} catch (SocketTimeoutException e) {
this.disconnect("timeout");
} catch (IOException e) {
if (isStopping)
if (isStopping) {
// If isStopping is true then our shutdown() has already been called, so no need to call it again
LOGGER.debug(String.format("Peer %s stopping...", this));
else
return;
}
// More informative logging
if (e instanceof EOFException) {
this.disconnect("EOF");
} else if (e.getMessage().contains("onnection reset")) { // Can't import/rely on sun.net.ConnectionResetException
this.disconnect("Connection reset");
} else {
this.disconnect("I/O error");
}
} finally {
Thread.currentThread().setName("disconnected peer");
}

Loading…
Cancel
Save