mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 02:05:53 +00:00
Clean up exception handling in Peer/PeerGroup. Resolves issue 65
This commit is contained in:
parent
0d085606df
commit
dfad026523
@ -92,14 +92,16 @@ public class Peer {
|
||||
|
||||
/**
|
||||
* Connects to the peer.
|
||||
*
|
||||
* @throws PeerException when there is a temporary problem with the peer and we should retry later
|
||||
*/
|
||||
public void connect() {
|
||||
public void connect() throws PeerException {
|
||||
try {
|
||||
conn = new NetworkConnection(address, params, bestHeight, 60000);
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
throw new PeerException(ex);
|
||||
} catch (ProtocolException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
throw new PeerException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,13 +109,16 @@ public class Peer {
|
||||
* Runs in the peers network loop and manages communication with the peer.
|
||||
*
|
||||
* <p>connect() must be called first
|
||||
*
|
||||
* @throws PeerException when there is a temporary problem with the peer and we should retry later
|
||||
*/
|
||||
public void run() {
|
||||
public void run() throws PeerException {
|
||||
// This should be called in the network loop thread for this peer
|
||||
if (conn == null)
|
||||
throw new RuntimeException("please call connect() first");
|
||||
|
||||
running = true;
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
Message m = conn.readMessage();
|
||||
@ -130,25 +135,24 @@ public class Peer {
|
||||
log.warn("Received unhandled message: {}", m);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (e instanceof IOException && !running) {
|
||||
} catch (IOException e) {
|
||||
disconnect();
|
||||
if (!running) {
|
||||
// This exception was expected because we are tearing down the socket as part of quitting.
|
||||
log.info("Shutting down peer loop");
|
||||
} else {
|
||||
// We caught an unexpected exception.
|
||||
e.printStackTrace();
|
||||
throw new PeerException(e);
|
||||
}
|
||||
} catch (ProtocolException e) {
|
||||
disconnect();
|
||||
throw new PeerException(e);
|
||||
} catch (RuntimeException e) {
|
||||
disconnect();
|
||||
log.error("unexpected exception in peer loop", e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
conn.shutdown();
|
||||
} catch (IOException e) {
|
||||
// Ignore exceptions on shutdown, socket might be dead
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
running = false;
|
||||
}
|
||||
disconnect();
|
||||
}
|
||||
|
||||
private void processBlock(Block m) throws IOException {
|
||||
@ -383,7 +387,7 @@ public class Peer {
|
||||
if (chainHeight <= 0) {
|
||||
// This should not happen because we shouldn't have given the user a Peer that is to another client-mode
|
||||
// node. If that happens it means the user overrode us somewhere.
|
||||
throw new RuntimeException("Peer does not have block chain");
|
||||
return -1;
|
||||
}
|
||||
int blocksToGet = chainHeight - blockChain.getChainHead().getHeight();
|
||||
return blocksToGet;
|
||||
@ -398,7 +402,8 @@ public class Peer {
|
||||
}
|
||||
try {
|
||||
// This is the correct way to stop an IO bound loop
|
||||
conn.shutdown();
|
||||
if (conn != null)
|
||||
conn.shutdown();
|
||||
} catch (IOException e) {
|
||||
// Don't care about this.
|
||||
}
|
||||
|
36
src/com/google/bitcoin/core/PeerException.java
Normal file
36
src/com/google/bitcoin/core/PeerException.java
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
/**
|
||||
* Thrown when a problem occurs in communicating with a peer, and we should
|
||||
* retry.
|
||||
*/
|
||||
public class PeerException extends Exception {
|
||||
@SuppressWarnings("serial")
|
||||
public PeerException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public PeerException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public PeerException(String msg, Exception e) {
|
||||
super(msg, e);
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ import com.google.bitcoin.store.BlockStoreException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOError;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collections;
|
||||
@ -242,17 +243,13 @@ public class PeerGroup {
|
||||
handleNewPeer(peer);
|
||||
log.info("running " + peer);
|
||||
peer.run();
|
||||
} catch (RuntimeException ex) {
|
||||
// do not propagate RuntimeException - log and try next peer
|
||||
} catch (PeerException ex) {
|
||||
// do not propagate PeerException - log and try next peer
|
||||
log.error("error while talking to peer", ex);
|
||||
} finally {
|
||||
// In all cases, disconnect and put the address back on the queue.
|
||||
// We will retry this peer after all other peers have been tried.
|
||||
try {
|
||||
peer.disconnect();
|
||||
} catch (RuntimeException ex) {
|
||||
// ignore
|
||||
}
|
||||
peer.disconnect();
|
||||
|
||||
inactives.add(address);
|
||||
if (peers.remove(peer))
|
||||
@ -273,7 +270,7 @@ public class PeerGroup {
|
||||
// Fatal error
|
||||
log.error("Block store corrupt?", e);
|
||||
running = false;
|
||||
break;
|
||||
throw new IOError(e);
|
||||
}
|
||||
|
||||
// If we got here, we should retry this address because an error unrelated
|
||||
|
Loading…
x
Reference in New Issue
Block a user