[ 
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

        

Reply via email to