mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-15 19:55:51 +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.
|
* 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 {
|
try {
|
||||||
conn = new NetworkConnection(address, params, bestHeight, 60000);
|
conn = new NetworkConnection(address, params, bestHeight, 60000);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new PeerException(ex);
|
||||||
} catch (ProtocolException 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.
|
* Runs in the peers network loop and manages communication with the peer.
|
||||||
*
|
*
|
||||||
* <p>connect() must be called first
|
* <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
|
// This should be called in the network loop thread for this peer
|
||||||
if (conn == null)
|
if (conn == null)
|
||||||
throw new RuntimeException("please call connect() first");
|
throw new RuntimeException("please call connect() first");
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
Message m = conn.readMessage();
|
Message m = conn.readMessage();
|
||||||
@ -130,25 +135,24 @@ public class Peer {
|
|||||||
log.warn("Received unhandled message: {}", m);
|
log.warn("Received unhandled message: {}", m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
if (e instanceof IOException && !running) {
|
disconnect();
|
||||||
|
if (!running) {
|
||||||
// This exception was expected because we are tearing down the socket as part of quitting.
|
// This exception was expected because we are tearing down the socket as part of quitting.
|
||||||
log.info("Shutting down peer loop");
|
log.info("Shutting down peer loop");
|
||||||
} else {
|
} else {
|
||||||
// We caught an unexpected exception.
|
throw new PeerException(e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
} catch (ProtocolException e) {
|
||||||
|
disconnect();
|
||||||
|
throw new PeerException(e);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
disconnect();
|
||||||
|
log.error("unexpected exception in peer loop", e);
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
disconnect();
|
||||||
conn.shutdown();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Ignore exceptions on shutdown, socket might be dead
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (this) {
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processBlock(Block m) throws IOException {
|
private void processBlock(Block m) throws IOException {
|
||||||
@ -383,7 +387,7 @@ public class Peer {
|
|||||||
if (chainHeight <= 0) {
|
if (chainHeight <= 0) {
|
||||||
// This should not happen because we shouldn't have given the user a Peer that is to another client-mode
|
// 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.
|
// 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();
|
int blocksToGet = chainHeight - blockChain.getChainHead().getHeight();
|
||||||
return blocksToGet;
|
return blocksToGet;
|
||||||
@ -398,6 +402,7 @@ public class Peer {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// This is the correct way to stop an IO bound loop
|
// This is the correct way to stop an IO bound loop
|
||||||
|
if (conn != null)
|
||||||
conn.shutdown();
|
conn.shutdown();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Don't care about this.
|
// 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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOError;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -242,17 +243,13 @@ public class PeerGroup {
|
|||||||
handleNewPeer(peer);
|
handleNewPeer(peer);
|
||||||
log.info("running " + peer);
|
log.info("running " + peer);
|
||||||
peer.run();
|
peer.run();
|
||||||
} catch (RuntimeException ex) {
|
} catch (PeerException ex) {
|
||||||
// do not propagate RuntimeException - log and try next peer
|
// do not propagate PeerException - log and try next peer
|
||||||
log.error("error while talking to peer", ex);
|
log.error("error while talking to peer", ex);
|
||||||
} finally {
|
} finally {
|
||||||
// In all cases, disconnect and put the address back on the queue.
|
// In all cases, disconnect and put the address back on the queue.
|
||||||
// We will retry this peer after all other peers have been tried.
|
// We will retry this peer after all other peers have been tried.
|
||||||
try {
|
|
||||||
peer.disconnect();
|
peer.disconnect();
|
||||||
} catch (RuntimeException ex) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
inactives.add(address);
|
inactives.add(address);
|
||||||
if (peers.remove(peer))
|
if (peers.remove(peer))
|
||||||
@ -273,7 +270,7 @@ public class PeerGroup {
|
|||||||
// Fatal error
|
// Fatal error
|
||||||
log.error("Block store corrupt?", e);
|
log.error("Block store corrupt?", e);
|
||||||
running = false;
|
running = false;
|
||||||
break;
|
throw new IOError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got here, we should retry this address because an error unrelated
|
// If we got here, we should retry this address because an error unrelated
|
||||||
|
Loading…
x
Reference in New Issue
Block a user