Fixed Network Connection failure recovery.

http://issues.apache.org/activemq/browse/AMQ-802
http://issues.apache.org/activemq/browse/AMQ-805



git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@420723 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Hiram R. Chirino 2006-07-11 04:46:04 +00:00
parent 75fde7165e
commit ad2546fa8d
3 changed files with 252 additions and 225 deletions

View File

@ -53,9 +53,6 @@ public class DemandForwardingBridge extends DemandForwardingBridgeSupport {
ServiceSupport.dispose(this); ServiceSupport.dispose(this);
} }
} }
if (!disposed){
triggerLocalStartBridge();
}
} }
} }

View File

@ -70,14 +70,14 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
protected static final Log log = LogFactory.getLog(DemandForwardingBridge.class); protected static final Log log = LogFactory.getLog(DemandForwardingBridge.class);
protected final Transport localBroker; protected final Transport localBroker;
protected final Transport remoteBroker; protected final Transport remoteBroker;
protected IdGenerator idGenerator = new IdGenerator(); protected final IdGenerator idGenerator = new IdGenerator();
protected LongSequenceGenerator consumerIdGenerator = new LongSequenceGenerator(); protected final LongSequenceGenerator consumerIdGenerator = new LongSequenceGenerator();
protected ConnectionInfo localConnectionInfo; protected ConnectionInfo localConnectionInfo;
protected ConnectionInfo remoteConnectionInfo; protected ConnectionInfo remoteConnectionInfo;
protected SessionInfo localSessionInfo; protected SessionInfo localSessionInfo;
protected ProducerInfo producerInfo; protected ProducerInfo producerInfo;
protected String localBrokerName; protected String localBrokerName = "Unknown";
protected String remoteBrokerName; protected String remoteBrokerName = "Unknown";
protected String localClientId; protected String localClientId;
protected String userName; protected String userName;
protected String password; protected String password;
@ -87,22 +87,22 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
protected String name = "bridge"; protected String name = "bridge";
protected ConsumerInfo demandConsumerInfo; protected ConsumerInfo demandConsumerInfo;
protected int demandConsumerDispatched; protected int demandConsumerDispatched;
protected AtomicBoolean localBridgeStarted = new AtomicBoolean(false); protected final AtomicBoolean localBridgeStarted = new AtomicBoolean(false);
protected AtomicBoolean remoteBridgeStarted = new AtomicBoolean(false); protected final AtomicBoolean remoteBridgeStarted = new AtomicBoolean(false);
protected boolean disposed = false; protected boolean disposed = false;
protected BrokerId localBrokerId; protected BrokerId localBrokerId;
protected ActiveMQDestination[] excludedDestinations; protected ActiveMQDestination[] excludedDestinations;
protected ActiveMQDestination[] dynamicallyIncludedDestinations; protected ActiveMQDestination[] dynamicallyIncludedDestinations;
protected ActiveMQDestination[] staticallyIncludedDestinations; protected ActiveMQDestination[] staticallyIncludedDestinations;
protected ActiveMQDestination[] durableDestinations; protected ActiveMQDestination[] durableDestinations;
protected ConcurrentHashMap subscriptionMapByLocalId = new ConcurrentHashMap(); protected final ConcurrentHashMap subscriptionMapByLocalId = new ConcurrentHashMap();
protected ConcurrentHashMap subscriptionMapByRemoteId = new ConcurrentHashMap(); protected final ConcurrentHashMap subscriptionMapByRemoteId = new ConcurrentHashMap();
protected final BrokerId localBrokerPath[] = new BrokerId[] { null }; protected final BrokerId localBrokerPath[] = new BrokerId[] { null };
protected CountDownLatch startedLatch = new CountDownLatch(2); protected CountDownLatch startedLatch = new CountDownLatch(2);
protected boolean decreaseNetworkConsumerPriority; protected boolean decreaseNetworkConsumerPriority;
protected boolean shutDown;
protected int networkTTL = 1; protected int networkTTL = 1;
protected final AtomicBoolean remoteInterupted = new AtomicBoolean(false); protected final AtomicBoolean remoteInterupted = new AtomicBoolean(false);
protected final AtomicBoolean lastConnectSucceeded = new AtomicBoolean(false);
public DemandForwardingBridgeSupport(final Transport localBroker, final Transport remoteBroker) { public DemandForwardingBridgeSupport(final Transport localBroker, final Transport remoteBroker) {
@ -111,7 +111,6 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
} }
public void start() throws Exception { public void start() throws Exception {
log.info("Starting a network connection between "+localBroker+" and "+remoteBroker+" has been established.");
localBroker.setTransportListener(new DefaultTransportListener(){ localBroker.setTransportListener(new DefaultTransportListener(){
public void onCommand(Command command){ public void onCommand(Command command){
serviceLocalCommand(command); serviceLocalCommand(command);
@ -130,16 +129,23 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
serviceRemoteException(error); serviceRemoteException(error);
} }
public synchronized void transportInterupted(){ public void transportInterupted(){
//clear any subscriptions - to try and prevent the bridge from stalling the broker //clear any subscriptions - to try and prevent the bridge from stalling the broker
if( remoteInterupted.compareAndSet(false, true) ) { if( remoteInterupted.compareAndSet(false, true) ) {
log.warn("Outbound transport to " + remoteBrokerName + " interrupted ...");
log.debug("Outbound transport to " + remoteBrokerName + " interrupted.");
if( localBridgeStarted.get() ) {
clearDownSubscriptions(); clearDownSubscriptions();
synchronized( DemandForwardingBridgeSupport.this ) {
try{ try{
localBroker.oneway(localConnectionInfo.createRemoveCommand()); localBroker.oneway(localConnectionInfo.createRemoveCommand());
}catch(IOException e){ }catch(IOException e){
log.warn("Caught exception from local start",e); log.warn("Caught exception from local start",e);
} }
}
}
localBridgeStarted.set(false); localBridgeStarted.set(false);
remoteBridgeStarted.set(false); remoteBridgeStarted.set(false);
startedLatch = new CountDownLatch(2); startedLatch = new CountDownLatch(2);
@ -147,35 +153,33 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
} }
public synchronized void transportResumed(){ public void transportResumed(){
if( remoteInterupted.compareAndSet(true, false) ) { if( remoteInterupted.compareAndSet(true, false) ) {
//restart and static subscriptions - the consumer advisories will be replayed // We want to slow down false connects so that we don't get in a busy loop.
log.info("Outbound transport to " + remoteBrokerName + " resumed"); // False connects can occurr if you using SSH tunnels.
if( !lastConnectSucceeded.get() ) {
// try{ try {
// triggerLocalStartBridge(); log.debug("Previous connection was never fully established. Sleeping for second to avoid busy loop.");
// }catch(IOException e){ Thread.sleep(1000);
// log.warn("Caught exception from local start",e); } catch (InterruptedException e) {
// } Thread.currentThread().interrupt();
try{
// clear out the previous connection as it may have missed some consumer advisories.
remoteBroker.oneway(remoteConnectionInfo.createRemoveCommand());
triggerRemoteStartBridge();
}catch(IOException e){
log.warn("Caught exception from remote start",e);
} }
} }
lastConnectSucceeded.set(false);
log.debug("Outbound transport to " + remoteBrokerName + " resumed");
}
} }
}); });
localBroker.start(); localBroker.start();
remoteBroker.start(); remoteBroker.start();
// triggerLocalStartBridge();
try{
triggerRemoteStartBridge(); triggerRemoteStartBridge();
}catch(IOException e){
log.warn("Caught exception from remote start",e);
}
} }
protected void triggerLocalStartBridge() throws IOException { protected void triggerLocalStartBridge() throws IOException {
@ -184,7 +188,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
try{ try{
startLocalBridge(); startLocalBridge();
}catch(Exception e){ }catch(Exception e){
log.error("Failed to start network bridge: "+e,e); serviceLocalException(e);
} }
} }
}; };
@ -197,7 +201,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
try{ try{
startRemoteBridge(); startRemoteBridge();
}catch(Exception e){ }catch(Exception e){
log.error("Failed to start network bridge: "+e,e); serviceRemoteException(e);
} }
} }
}; };
@ -206,7 +210,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
protected void startLocalBridge() throws Exception { protected void startLocalBridge() throws Exception {
if(localBridgeStarted.compareAndSet(false,true)){ if(localBridgeStarted.compareAndSet(false,true)){
synchronized( this ) {
localConnectionInfo=new ConnectionInfo(); localConnectionInfo=new ConnectionInfo();
localConnectionInfo.setConnectionId(new ConnectionId(idGenerator.generateId())); localConnectionInfo.setConnectionId(new ConnectionId(idGenerator.generateId()));
localClientId="NC_"+remoteBrokerName+"_inbound"+name; localClientId="NC_"+remoteBrokerName+"_inbound"+name;
@ -220,13 +224,21 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
log.info("Network connection between "+localBroker+" and "+remoteBroker+"("+remoteBrokerName log.info("Network connection between "+localBroker+" and "+remoteBroker+"("+remoteBrokerName
+") has been established."); +") has been established.");
startedLatch.countDown(); startedLatch.countDown();
setupStaticDestinations(); setupStaticDestinations();
} }
} }
}
protected void startRemoteBridge() throws Exception { protected void startRemoteBridge() throws Exception {
if(remoteBridgeStarted.compareAndSet(false,true)){ if(remoteBridgeStarted.compareAndSet(false,true)) {
synchronized (this) {
if( remoteConnectionInfo!=null ) {
remoteBroker.oneway(remoteConnectionInfo.createRemoveCommand());
}
remoteConnectionInfo=new ConnectionInfo(); remoteConnectionInfo=new ConnectionInfo();
remoteConnectionInfo.setConnectionId(new ConnectionId(idGenerator.generateId())); remoteConnectionInfo.setConnectionId(new ConnectionId(idGenerator.generateId()));
@ -259,39 +271,30 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
destinationInfo.setPrefetchSize(prefetchSize); destinationInfo.setPrefetchSize(prefetchSize);
remoteBroker.oneway(destinationInfo); remoteBroker.oneway(destinationInfo);
startedLatch.countDown(); startedLatch.countDown();
if (!disposed){
triggerLocalStartBridge();
}
}
} }
} }
public void stop() throws Exception { public void stop() throws Exception {
shutDown = true;
doStop();
}
/**
* stop the bridge
* @throws Exception
*/
protected void doStop() throws Exception {
log.debug(" stopping "+localBrokerName+ " bridge to " + remoteBrokerName + " is disposed already ? "+disposed); log.debug(" stopping "+localBrokerName+ " bridge to " + remoteBrokerName + " is disposed already ? "+disposed);
if(!disposed){ if (!disposed) {
try{ try {
disposed=true; disposed = true;
remoteBridgeStarted.set(false); remoteBridgeStarted.set(false);
if(!shutDown){
remoteBroker.oneway(new ShutdownInfo());
if(localConnectionInfo!=null){
localBroker.oneway(localConnectionInfo.createRemoveCommand());
remoteBroker.oneway(remoteConnectionInfo.createRemoveCommand());
}
localBroker.oneway(new ShutdownInfo()); localBroker.oneway(new ShutdownInfo());
} remoteBroker.oneway(new ShutdownInfo());
localBroker.setTransportListener(null);
remoteBroker.setTransportListener(null); } catch (IOException e) {
}catch(IOException e){ log.debug("Caught exception stopping", e);
log.debug("Caught exception stopping",e); } finally {
}finally{ ServiceStopper ss = new ServiceStopper();
ServiceStopper ss=new ServiceStopper();
ss.stop(localBroker); ss.stop(localBroker);
ss.stop(remoteBroker); ss.stop(remoteBroker);
ss.throwFirstException(); ss.throwFirstException();
@ -300,27 +303,16 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
log.debug(localBrokerName+ " bridge to " + remoteBrokerName + " stopped"); log.debug(localBrokerName+ " bridge to " + remoteBrokerName + " stopped");
} }
protected void doStopLocal(){
try{
if(!shutDown){
if(localConnectionInfo!=null){
localBroker.oneway(localConnectionInfo.createRemoveCommand());
}
localBroker.oneway(new ShutdownInfo());
}
localBroker.setTransportListener(null);
}catch(IOException e){
log.debug("Caught exception stopping",e);
}finally{
ServiceStopper ss=new ServiceStopper();
ss.stop(localBroker);
localBridgeStarted.set(false);
}
}
protected void serviceRemoteException(Throwable error) { protected void serviceRemoteException(Throwable error) {
log.info("Network connection between "+localBroker+" and "+remoteBroker+" shutdown: "+error.getMessage(),error); if( !disposed ) {
ServiceSupport.dispose(this); log.info("Network connection between "+localBroker+" and "+remoteBroker+" shutdown due to a remote error: "+error);
log.debug("The remote Exception was: "+error, error);
new Thread() {
public void run() {
ServiceSupport.dispose(DemandForwardingBridgeSupport.this);
}
}.start();
}
} }
protected void serviceRemoteCommand(Command command) { protected void serviceRemoteCommand(Command command) {
@ -336,7 +328,10 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
demandConsumerDispatched=0; demandConsumerDispatched=0;
} }
}else if(command.isBrokerInfo()){ }else if(command.isBrokerInfo()){
lastConnectSucceeded.set(true);
serviceRemoteBrokerInfo(command); serviceRemoteBrokerInfo(command);
}else if(command.getClass() == ConnectionError.class ) { }else if(command.getClass() == ConnectionError.class ) {
ConnectionError ce = (ConnectionError) command; ConnectionError ce = (ConnectionError) command;
serviceRemoteException(ce.getException()); serviceRemoteException(ce.getException());
@ -344,6 +339,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
switch(command.getDataStructureType()){ switch(command.getDataStructureType()){
case KeepAliveInfo.DATA_STRUCTURE_TYPE: case KeepAliveInfo.DATA_STRUCTURE_TYPE:
case WireFormatInfo.DATA_STRUCTURE_TYPE: case WireFormatInfo.DATA_STRUCTURE_TYPE:
case ShutdownInfo.DATA_STRUCTURE_TYPE:
break; break;
default: default:
log.warn("Unexpected remote command: "+command); log.warn("Unexpected remote command: "+command);
@ -413,7 +409,10 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
ActiveMQTempDestination tempDest = (ActiveMQTempDestination) destInfo.getDestination(); ActiveMQTempDestination tempDest = (ActiveMQTempDestination) destInfo.getDestination();
tempDest.setConnectionId(localSessionInfo.getSessionId().getConnectionId()); tempDest.setConnectionId(localSessionInfo.getSessionId().getConnectionId());
} }
destInfo.setBrokerPath(appendToBrokerPath(destInfo.getBrokerPath(),getRemoteBrokerPath())); destInfo.setBrokerPath(appendToBrokerPath(destInfo.getBrokerPath(),getRemoteBrokerPath()));
log.debug("Replying destination control command: "+destInfo);
localBroker.oneway(destInfo); localBroker.oneway(destInfo);
} }
@ -424,8 +423,15 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
} }
protected void serviceLocalException(Throwable error) { protected void serviceLocalException(Throwable error) {
log.info("Network connection between "+localBroker+" and "+remoteBroker+" shutdown: "+error.getMessage(),error); if( !disposed ) {
ServiceSupport.dispose(this); log.info("Network connection between "+localBroker+" and "+remoteBroker+" shutdown due to a local error: "+error);
log.debug("The local Exception was:"+error,error);
new Thread() {
public void run() {
ServiceSupport.dispose(DemandForwardingBridgeSupport.this);
}
}.start();
}
} }
protected void addSubscription(DemandSubscription sub) throws IOException { protected void addSubscription(DemandSubscription sub) throws IOException {
@ -502,16 +508,6 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
remoteBroker.asyncRequest(message, callback); remoteBroker.asyncRequest(message, callback);
} }
// Ack on every message since we don't know if the broker is blocked due to memory
// usage and is waiting for an Ack to un-block him.
// Acking a range is more efficient, but also more prone to locking up a server
// Perhaps doing something like the following should be policy based.
// int dispatched = sub.incrementDispatched();
// if(dispatched>(sub.getLocalInfo().getPrefetchSize()*.75)){
// localBroker.oneway(new MessageAck(md,MessageAck.STANDARD_ACK_TYPE,dispatched));
// sub.setDispatched(0);
// }
} }
}else if(command.isBrokerInfo()){ }else if(command.isBrokerInfo()){
serviceLocalBrokerInfo(command); serviceLocalBrokerInfo(command);
@ -521,8 +517,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
// the local transport is just shutting down temporarily until the remote side // the local transport is just shutting down temporarily until the remote side
// is restored. // is restored.
if( !remoteInterupted.get() ) { if( !remoteInterupted.get() ) {
shutDown = true; stop();
doStop();
} }
}else if(command.getClass() == ConnectionError.class ) { }else if(command.getClass() == ConnectionError.class ) {
ConnectionError ce = (ConnectionError) command; ConnectionError ce = (ConnectionError) command;
@ -696,20 +691,6 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
this.networkTTL=networkTTL; this.networkTTL=networkTTL;
} }
/**
* @return Returns the shutDown.
*/
public boolean isShutDown() {
return shutDown;
}
/**
* @param shutDown The shutDown to set.
*/
public void setShutDown(boolean shutDown) {
this.shutDown=shutDown;
}
public static boolean contains(BrokerId[] brokerPath, BrokerId brokerId) { public static boolean contains(BrokerId[] brokerPath, BrokerId brokerId) {
if(brokerPath!=null){ if(brokerPath!=null){
for(int i=0;i<brokerPath.length;i++){ for(int i=0;i<brokerPath.length;i++){
@ -843,7 +824,8 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
} }
protected void clearDownSubscriptions() { protected void clearDownSubscriptions() {
subscriptionMapByLocalId.clear();
subscriptionMapByRemoteId.clear();
} }
protected abstract NetworkBridgeFilter createNetworkBridgeFilter(ConsumerInfo info) throws IOException; protected abstract NetworkBridgeFilter createNetworkBridgeFilter(ConsumerInfo info) throws IOException;

View File

@ -16,9 +16,11 @@
*/ */
package org.apache.activemq.network; package org.apache.activemq.network;
import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap; import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.command.DiscoveryEvent; import org.apache.activemq.command.DiscoveryEvent;
import org.apache.activemq.transport.Transport; import org.apache.activemq.transport.Transport;
import org.apache.activemq.transport.TransportFactory; import org.apache.activemq.transport.TransportFactory;
@ -28,10 +30,7 @@ import org.apache.activemq.transport.discovery.DiscoveryListener;
import org.apache.activemq.util.ServiceStopper; import org.apache.activemq.util.ServiceStopper;
import org.apache.activemq.util.ServiceSupport; import org.apache.activemq.util.ServiceSupport;
import java.io.IOException; import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
/** /**
* A network connector which uses a discovery agent to detect the remote brokers * A network connector which uses a discovery agent to detect the remote brokers
@ -58,6 +57,11 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
} }
public void onServiceAdd(DiscoveryEvent event) { public void onServiceAdd(DiscoveryEvent event) {
// Ignore events once we start stopping.
if( isStopped() || isStopping() )
return;
String url = event.getServiceName(); String url = event.getServiceName();
if (url != null) { if (url != null) {
@ -80,7 +84,7 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
URI connectUri = uri; URI connectUri = uri;
if (failover) { if (failover) {
try { try {
connectUri = new URI("failover:" + connectUri); connectUri = new URI("failover:(" + connectUri+")?maxReconnectDelay=1000");
} }
catch (URISyntaxException e) { catch (URISyntaxException e) {
log.warn("Could not create failover URI: " + connectUri); log.warn("Could not create failover URI: " + connectUri);
@ -90,22 +94,24 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
log.info("Establishing network connection between from " + localURI + " to " + connectUri); log.info("Establishing network connection between from " + localURI + " to " + connectUri);
Transport localTransport;
try {
localTransport = createLocalTransport();
}
catch (Exception e) {
log.warn("Could not connect to local URI: " + localURI + ": " + e, e);
return;
}
Transport remoteTransport; Transport remoteTransport;
try { try {
remoteTransport = TransportFactory.connect(connectUri); remoteTransport = TransportFactory.connect(connectUri);
} }
catch (Exception e) { catch (Exception e) {
ServiceSupport.dispose(localTransport); log.warn("Could not connect to remote URI: " + localURI + ": " + e.getMessage());
log.warn("Could not connect to remote URI: " + connectUri + ": " + e, e); log.debug("Connection failure exception: "+ e, e);
return;
}
Transport localTransport;
try {
localTransport = createLocalTransport();
}
catch (Exception e) {
ServiceSupport.dispose(remoteTransport);
log.warn("Could not connect to local URI: " + localURI + ": " + e.getMessage());
log.debug("Connection failure exception: "+ e, e);
return; return;
} }
@ -117,7 +123,13 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
catch (Exception e) { catch (Exception e) {
ServiceSupport.dispose(localTransport); ServiceSupport.dispose(localTransport);
ServiceSupport.dispose(remoteTransport); ServiceSupport.dispose(remoteTransport);
log.warn("Could not start network bridge between: " + localURI + " and: " + uri + " due to: " + e, e); log.warn("Could not start network bridge between: " + localURI + " and: " + uri + " due to: " + e);
log.debug("Start failure exception: "+ e, e);
try {
discoveryAgent.serviceFailed(event);
} catch (IOException e1) {
}
return; return;
} }
} }
@ -196,28 +208,52 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
if (conduitSubscriptions) { if (conduitSubscriptions) {
if (dynamicOnly) { if (dynamicOnly) {
result = new ConduitBridge(localTransport, remoteTransport) { result = new ConduitBridge(localTransport, remoteTransport) {
protected void serviceRemoteException(Exception error) { protected void serviceLocalException(Throwable error) {
super.serviceRemoteException(error);
try { try {
// Notify the discovery agent that the remote broker super.serviceLocalException(error);
// failed. } finally {
discoveryAgent.serviceFailed(event); fireServiceFailed();
}
}
protected void serviceRemoteException(Throwable error) {
try {
super.serviceRemoteException(error);
} finally {
fireServiceFailed();
}
}
public void fireServiceFailed() {
if( !isStopped() ) {
try {
discoveryAgent.serviceFailed(event);
} catch (IOException e) {
} }
catch (IOException e) {
} }
} }
}; };
} }
else { else {
result = new DurableConduitBridge(localTransport, remoteTransport) { result = new DurableConduitBridge(localTransport, remoteTransport) {
protected void serviceRemoteException(Exception error) { protected void serviceLocalException(Throwable error) {
super.serviceRemoteException(error);
try { try {
// Notify the discovery agent that the remote broker super.serviceLocalException(error);
// failed. } finally {
discoveryAgent.serviceFailed(event); fireServiceFailed();
}
}
protected void serviceRemoteException(Throwable error) {
try {
super.serviceRemoteException(error);
} finally {
fireServiceFailed();
}
}
public void fireServiceFailed() {
if( !isStopped() ) {
try {
discoveryAgent.serviceFailed(event);
} catch (IOException e) {
} }
catch (IOException e) {
} }
} }
}; };
@ -225,14 +261,26 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
} }
else { else {
result = new DemandForwardingBridge(localTransport, remoteTransport) { result = new DemandForwardingBridge(localTransport, remoteTransport) {
protected void serviceRemoteException(Exception error) { protected void serviceLocalException(Throwable error) {
super.serviceRemoteException(error);
try { try {
// Notify the discovery agent that the remote broker super.serviceLocalException(error);
// failed. } finally {
discoveryAgent.serviceFailed(event); fireServiceFailed();
}
}
protected void serviceRemoteException(Throwable error) {
try {
super.serviceRemoteException(error);
} finally {
fireServiceFailed();
}
}
public void fireServiceFailed() {
if( !isStopped() ) {
try {
discoveryAgent.serviceFailed(event);
} catch (IOException e) {
} }
catch (IOException e) {
} }
} }
}; };