3
0
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:
Miron Cuperman (devrandom) 2011-07-28 19:22:56 +00:00
parent 0d085606df
commit dfad026523
3 changed files with 65 additions and 27 deletions

View File

@ -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.
}

View 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);
}
}

View File

@ -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