[
https://issues.apache.org/jira/browse/AMQ-3014?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13062640#comment-13062640
]
Timothy Bish commented on AMQ-3014:
-----------------------------------
Both tests seem to fail regardless of the patch being applied.
> DemandForwardingBridgeSupport can send BrokerInfo to remote transport before
> local broker ID is known.
> ------------------------------------------------------------------------------------------------------
>
> Key: AMQ-3014
> URL: https://issues.apache.org/jira/browse/AMQ-3014
> Project: ActiveMQ
> Issue Type: Bug
> Components: Broker, Transport
> Affects Versions: 5.4.1
> Reporter: Stirling Chow
> Attachments: NullBrokerIdTest.java, patch.txt
>
>
> Symptom
> ========
> We have a production system that involves a set of Brokers connected in a
> demand-forwarding Network-of-Brokers using HTTP-based bridges. Each Broker
> periodically scans its list of peer brokers by iterating over
> RegionBroker.getPeerBrokerInfos:
> public synchronized BrokerInfo[] getPeerBrokerInfos() {
> BrokerInfo[] result = new BrokerInfo[brokerInfos.size()];
> result = brokerInfos.toArray(result);
> return result;
> }
> This scanning code assumes that BrokerInfo.getBrokerId() is always non-null
> (since every broker should have an ID). However, we periodically noticed
> that BrokerInfo.getBrokerId() returned a NULL value, which was very
> unexpected.
> Cause
> ======
> We analyzed the DemandForwardingBridgeSupport and noticed that when the
> remote bridge/transport is started, it sends the local Broker's ID:
> protected void startRemoteBridge() throws Exception {
> ...
> brokerInfo.setBrokerId(this.localBrokerId);
> remoteBroker.oneway(brokerInfo);
> }
> The local Broker's ID is not initially known until it is received from the
> local transport and processed by
> DemandForwardingBridge.serviceLocalBrokerInfo(...):
> protected void serviceLocalBrokerInfo(Command command) throws
> InterruptedException {
> synchronized (brokerInfoMutex) {
> localBrokerId = ((BrokerInfo)command).getBrokerId();
> localBrokerPath[0] = localBrokerId;
> localBrokerIdKnownLatch.countDown();
> The local Broker's ID is dispatched asynchronously when the local transport
> is started, as seen in TransportConnection.start():
> public void start() throws Exception {
> starting = true;
> try {
> synchronized (this) {
> if (taskRunnerFactory != null) {
> taskRunner = taskRunnerFactory.createTaskRunner(this,
> "ActiveMQ Connection Dispatcher: "
> + getRemoteAddress());
> } else {
> taskRunner = null;
> }
> transport.start();
> active = true;
> dispatchAsync(connector.getBrokerInfo());
> Because of the asynchronous dispatch, the remote bridge may be started before
> the local Broker's ID is known. This would be particularly evident when the
> local broker is under load processing a lot of tasks.
> We've attached a unit test that demonstrates how a slow asynchronous dispatch
> on the local transport can cause the remote transport to transmit a null
> BrokerId.
> Solution
> ======
> DemandForwardingBridgeSupport already contains a localBrokerIdKnownLatch, so
> starting the remote transport should wait for this latch before accessing the
> local Broker's ID (see patch).
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira