ActiveMQ C++ Client
  1. ActiveMQ C++ Client
  2. AMQCPP-525

C++ client hangs when using the failover transport to connect to a network of brokers

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.8.1
    • Fix Version/s: 3.8.2, 3.9.0
    • Component/s: Openwire
    • Labels:
      None
    • Environment:

      Centos 5.9, ActiveMQ 5.9.0, ActiveMQ CPP Library 3.8.1 C++ Test Listener

      Description

      I have a network of three brokers on three different hosts each with nio transport connectors as follows (host 1 below, hosts 2 and 3 follow the same pattern):

      <transportConnector name="openwire-client"
      uri="nio://host1.somedomain.com:44320"
      updateClusterClients="true"
      rebalanceClusterClients="true"
      updateClusterClientsOnRemove="true"
      />

      I modified the ActiveMQ C++ example Listener (Listener.cpp) with the following broker URL:

      failover:(tcp://host1.somedomain.com:44320)

      The Listener hangs in connection->start() and never establishes a connection with any of the three brokers.

      I put debug into FailoverTransport.cpp and discovered that the URIs received from the three brokers are being used verbatim by the C++ client - i.e. it tries to rebalance/reconnect using the nio scheme in the URIs received from the broker transport connector configuration.

      The C++ client has no handling for the nio scheme and so continually iterates though the URI pool but never establishes a connection to any of the URIs, hence the hang.

      According to the ActiveMQ website "Configuring Transports" documentation if the nio transport is specified in a URI used by an OpenWire client, it should simply instantiate the normal tcp transport, but this handling seems to be missing from the C++ client.

      I put a quick fix into the FailoverTransport::updateURIs() method to convert any URI received from a broker with a scheme of "nio" to the same URI but with a scheme of "tcp" and then the client successfully connected to one of the brokers:

      Pointer<Iterator<URI> > setIter(set.iterator());
      while (setIter->hasNext()) {
      URI value = setIter->next();
      if (value.getScheme() == "nio")

      { std::cout << "Found NIO scheme, changing to TCP" << std::endl; URI newValue = URI("tcp", value.getAuthority(), value.getPath(), value.getQuery(), value.getFragment()); value = newValue; }

      this->impl->updated->addURI(value);
      }

      This is obviously not an appropriate solution for the production code, but it does serve to demonstrate the issue.

        Activity

        Hide
        Timothy Bish added a comment -

        Added aliased factory entries for NIO and NIO+SSL

        Show
        Timothy Bish added a comment - Added aliased factory entries for NIO and NIO+SSL
        Hide
        Matthew Western added a comment -

        Excellent, thank you !

        Show
        Matthew Western added a comment - Excellent, thank you !

          People

          • Assignee:
            Timothy Bish
            Reporter:
            Matthew Western
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development