https://issues.apache.org/jira/browse/AMQ-3696 - start broker asynchronously since hanging in start() method leads to problems with stopping slaves in osgi

git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1362950 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Bosanac Dejan 2012-07-18 13:43:09 +00:00
parent bf62dc88c1
commit 7f89b33aa4
2 changed files with 98 additions and 48 deletions

View File

@ -115,6 +115,9 @@ public class StartCommand extends AbstractCommand {
BrokerService broker = BrokerFactory.createBroker(configURI);
brokers.add(broker);
broker.start();
if (!broker.waitUntilStarted()) {
throw broker.getStartException();
}
}
/**

View File

@ -221,6 +221,10 @@ public class BrokerService implements Service {
private int offlineDurableSubscriberTaskSchedule = 300000;
private DestinationFilter virtualConsumerDestinationFilter;
private final Object persistenceAdapterLock = new Object();
private boolean persistenceAdapterStarted = false;
private Exception startException = null;
static {
String localHostName = "localhost";
try {
@ -517,6 +521,29 @@ public class BrokerService implements Service {
startManagementContext();
}
startPersistenceAdapter();
startBroker();
startedLatch.countDown();
} catch (Exception e) {
LOG.error("Failed to start ActiveMQ JMS Message Broker (" + getBrokerName() + ", " + brokerId + "). Reason: " + e, e);
try {
if (!stopped.get()) {
stop();
}
} catch (Exception ex) {
LOG.warn("Failed to stop broker after failure in start ", ex);
}
throw e;
} finally {
MDC.remove("activemq.broker");
}
}
private void startPersistenceAdapter() throws Exception {
new Thread() {
@Override
public void run() {
try {
getPersistenceAdapter().setUsageManager(getProducerSystemUsage());
getPersistenceAdapter().setBrokerName(getBrokerName());
LOG.info("Using Persistence Adapter: " + getPersistenceAdapter());
@ -524,6 +551,28 @@ public class BrokerService implements Service {
deleteAllMessages();
}
getPersistenceAdapter().start();
} catch (Exception e) {
startException = e;
} finally {
synchronized (persistenceAdapterLock) {
persistenceAdapterLock.notifyAll();
}
}
}
}.start();
}
private void startBroker() throws Exception {
new Thread() {
@Override
public void run() {
try {
synchronized (persistenceAdapterLock) {
persistenceAdapterLock.wait();
}
if (startException != null) {
return;
}
slave = false;
startDestinations();
addShutdownHook();
@ -539,7 +588,7 @@ public class BrokerService implements Service {
managedBroker.setContextBroker(broker);
adminView.setBroker(managedBroker);
}
BrokerRegistry.getInstance().bind(getBrokerName(), this);
BrokerRegistry.getInstance().bind(getBrokerName(), BrokerService.this);
// see if there is a MasterBroker service and if so, configure
// it and start it.
for (Service service : services) {
@ -548,7 +597,7 @@ public class BrokerService implements Service {
service.start();
}
}
if (!isSlave() && (this.masterConnector == null || isShutdownOnMasterFailure() == false)) {
if (!isSlave() && (masterConnector == null || isShutdownOnMasterFailure() == false)) {
startAllConnectors();
}
if (!stopped.get()) {
@ -565,20 +614,11 @@ public class BrokerService implements Service {
LOG.info("ActiveMQ JMS Message Broker (" + getBrokerName() + ", " + brokerId + ") started");
getBroker().brokerServiceStarted();
checkSystemUsageLimits();
startedLatch.countDown();
} catch (Exception e) {
LOG.error("Failed to start ActiveMQ JMS Message Broker (" + getBrokerName() + ", " + brokerId + "). Reason: " + e, e);
try {
if (!stopped.get()) {
stop();
startException = e;
}
} catch (Exception ex) {
LOG.warn("Failed to stop broker after failure in start ", ex);
}
throw e;
} finally {
MDC.remove("activemq.broker");
}
}.start();
}
/**
@ -783,6 +823,9 @@ public class BrokerService implements Service {
boolean waitSucceeded = false;
while (isStarted() && !stopped.get() && !waitSucceeded) {
try {
if (startException != null) {
return waitSucceeded;
}
waitSucceeded = startedLatch.await(100L, TimeUnit.MILLISECONDS);
} catch (InterruptedException ignore) {
}
@ -2718,4 +2761,8 @@ public class BrokerService implements Service {
return isUseVirtualTopics() && destination.isQueue() &&
getVirtualTopicConsumerDestinationFilter().matches(destination);
}
public Exception getStartException() {
return startException;
}
}