Matthew Western created AMQCPP-525:
--------------------------------------
Summary: C++ client hangs when using the failover transport to
connect to a network of brokers
Key: AMQCPP-525
URL: https://issues.apache.org/jira/browse/AMQCPP-525
Project: ActiveMQ C++ Client
Issue Type: Bug
Components: Openwire
Affects Versions: 3.8.1
Environment: Centos 5.9, Active MQ C++ Test Listener
Reporter: Matthew Western
Assignee: Timothy Bish
Fix For: 3.8.2
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
form 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.
--
This message was sent by Atlassian JIRA
(v6.1#6144)