Bug 614344 - qpid python client [high level API] reconnect not fully functional (reconnect from url list)
Summary: qpid python client [high level API] reconnect not fully functional (reconnect...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise MRG
Classification: Red Hat
Component: python-qpid
Version: Development
Hardware: All
OS: Linux
high
high
Target Milestone: 1.3
: ---
Assignee: messaging-bugs
QA Contact: Frantisek Reznicek
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-07-14 07:52 UTC by Frantisek Reznicek
Modified: 2015-11-16 01:12 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2010-10-20 11:33:39 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Frantisek Reznicek 2010-07-14 07:52:27 UTC
Description of problem:

Bug 614054 describes issue in qpid client reconnect when url list is get from failover exchange.

When url is specified in the qpid.messagin.Connection(reconnect_urls=) then
on python-qpid-0.7.946106-4 ... python-qpid-0.7.946106-6 you will trigger bug 613912.

This defect report describes reconnect from given url list on python-qpid-0.7.946106-7 which was tested due to bug 614054 retest request.

When qpid python client specifies qpid.messagin.Connection(reconnect_urls=) parameter as simple list of urls.

Now if list of urls are just list of hosts 
  {'reconnect_urls': ['dhcp-26-227', 'dhcp-27-226']}
then python client crashes with (detailed on the bottom):
  qpid.messaging.exceptions.InternalError: Traceback (most recent call last):
  ...
  TypeError: an integer is required

when tried list of hosts with explicitly specified ports:
  {'reconnect_urls': ['dhcp-26-227:5672', 'dhcp-27-226:5672']
everything's fine.

So the issue is that qpid python client does not use default port in the reconnection url list if ports are missing. This should be the case because pydoc qpid.messaging.Connection claims:

  qpid.messaging.Connection = class Connection(Endpoint)
  |  A Connection manages a group of L{Sessions<Session>} and connects
  |  them with a remote endpoint.
  |
  |  Methods defined here:
  |
  |  __init__(self, url=None, **options)
  |      Creates a connection. A newly created connection must be connected
  |      with the Connection.connect() method before it can be used.
  |
  |      @type url: str
  |      @param url: [ <username> [ / <password> ] @ ] <host> [ : <port> ]
  |      @type host: str
  |      @param host: the name or ip address of the remote host (overriden by url)
    ...
  |      @type reconnect_urls: list[str]
  |      @param reconnect_urls: list of backup hosts specified as urls


Version-Release number of selected component (if applicable):
python-qpid-0.7.946106-7

How reproducible:
100%

Steps to Reproduce:
1. start brokers on A and B
2. from B issue command
  cat ./msgs.in | ../spout --address "addr1; {create: sender, delete: \
    receiver}"   --broker A --reconnect --reconnect-interval 3 \
    --reconnect-limit 10   --reconnect-urls A,B
3. from B issue command and in the middle stop(exit) the broker on A
  ../drain.py --address "addr1; {create: sender, delete: receiver}" \
    --broker A   --reconnect --reconnect-interval 2 --reconnect-limit 5 \
    --reconnect-urls A,B --print "%(C)s"> msgs.out

4. Check exit code and correctless&completeness of rx data
  echo $? ; ls -lA ./msgs.* ; diff ./msgs.in msgs.out | head
  
Clients used above are in https://bugzilla.redhat.com/attachment.cgi?id=431389
See additional notes below...

Actual results:
Qpid python client reconnect does not work for all supported url forms.

Expected results:
Qpid python client reconnect should be functional for all supported url forms.


Additional info:

[root@dhcp-27-226 test]# cat ./msgs.in | ../spout --address "addr1; {create: sender, delete: receiver}"   --broker dhcp-26-227 --reconnect --reconnect-interval 3 --reconnect-limit 10   --reconnect-urls dhcp-26-227,dhcp-27-226
[root@dhcp-27-226 test]# ../drain.py --address "addr1; {create: sender, delete: receiver}" --broker dhcp-26-227   --reconnect --reconnect-interval 2 --reconnect-limit 5   --reconnect-urls dhcp-26-227,dhcp-27-226 --print "%(C)s"> msgs.out
DEBUG: {'reconnect_urls': ['dhcp-26-227', 'dhcp-27-226']}
[root@dhcp-27-226 test]# ls -lA ./msgs.* ; diff ./msgs.in msgs.out | head
-rw-rw-r-- 1 root root 106935 Jul 13 16:43 ./msgs.in
-rw-rw-r-- 1 root root 106935 Jul 14 09:20 ./msgs.out
[root@dhcp-27-226 test]# cat ./msgs.in | ../spout --address "addr1; {create: sender, delete: receiver}"   --broker dhcp-26-227 --reconnect --reconnect-interval 3 --reconnect-limit 10   --reconnect-urls dhcp-26-227,dhcp-27-226
[root@dhcp-27-226 test]# ../drain.py --address "addr1; {create: sender, delete: receiver}" --broker dhcp-26-227   --reconnect --reconnect-interval 2 --reconnect-limit 5   --reconnect-urls dhcp-26-227,dhcp-27-226 --print "%(C)s"> msgs.out
DEBUG: {'reconnect_urls': ['dhcp-26-227', 'dhcp-27-226']}

<<broker on dhcp-26-227 exited>>

2010-07-14 09:20:33,673 WARNING recoverable error[attempt 0]: (104, 'Connection reset by peer')
2010-07-14 09:20:33,673 WARNING sleeping 2 seconds
2010-07-14 09:20:35,673 WARNING trying: dhcp-26-227:5672
2010-07-14 09:20:35,675 WARNING recoverable error[attempt 1]: (111, 'Connection refused')
2010-07-14 09:20:35,675 WARNING trying: dhcp-26-227:None
Traceback (most recent call last):
  File "../drain.py", line 114, in ?
    msg = rcv.fetch(timeout=timeout)
  File "<string>", line 6, in fetch
  File "/usr/lib/python2.4/site-packages/qpid/messaging/endpoints.py", line 1005, in fetch
    self._ecwait(lambda: not self.draining)
  File "/usr/lib/python2.4/site-packages/qpid/messaging/endpoints.py", line 50, in _ecwait
    result = self._ewait(lambda: self.closed or predicate(), timeout)
  File "/usr/lib/python2.4/site-packages/qpid/messaging/endpoints.py", line 957, in _ewait
    result = self.session._ewait(lambda: self.error or predicate(), timeout)
  File "/usr/lib/python2.4/site-packages/qpid/messaging/endpoints.py", line 550, in _ewait
    result = self.connection._ewait(lambda: self.error or predicate(), timeout)
  File "/usr/lib/python2.4/site-packages/qpid/messaging/endpoints.py", line 194, in _ewait
    self.check_error()
  File "/usr/lib/python2.4/site-packages/qpid/messaging/endpoints.py", line 187, in check_error
    raise self.error
qpid.messaging.exceptions.InternalError: Traceback (most recent call last):
  File "/usr/lib/python2.4/site-packages/qpid/messaging/driver.py", line 467, in dispatch
    self.connect()
  File "/usr/lib/python2.4/site-packages/qpid/messaging/driver.py", line 488, in connect
    self._transport = trans(host, port)
  File "/usr/lib/python2.4/site-packages/qpid/messaging/transports.py", line 27, in __init__
    self.socket = connect(host, port)
  File "/usr/lib/python2.4/site-packages/qpid/util.py", line 43, in connect
    sock.connect((host, port))
  File "<string>", line 1, in connect
TypeError: an integer is required

[root@dhcp-27-226 test]# rpm -q python-qpid
python-qpid-0.7.946106-7.el5

Comment 1 Frantisek Reznicek 2010-07-29 13:57:18 UTC
The issue has been fixed, tested on RHEL 4.8 / 5.5 / 6.0beta i386 / x86_64 on
packages:
python-qpid-0.7.946106-9.el4/5/6
qpid-cpp-server-0.7.946106-10.el4/5
qpid-cpp-server-0.7.946106-5.el6.i686

-> VERIFIED


Note You need to log in before you can comment on or make changes to this bug.