QPID-7317: Fix hangs in qpid.messaging.

Hang is observed in processes using qpid.messaging with a thread blocked waiting
for the Selector to wake it, but no Selector.run thread.

This patch removes all the known ways that this hang can occur. Either we
function normally or immediately raise an exception and log to the
"qpid.messaging" logger a message starting with "qpid.messaging:"

The following issues are fixed:

1. The Selector.run() thread raises a fatal exception.

Use of qpid.messaging will re-raise the exception immediately, not hang.

2. The process forks, so child has no Selector thread.

https://issues.apache.org/jira/browse/QPID-5637 resets the Selector after a fork.
In addition we now:

- Close Selector.waiter: its file descriptors are shared with the parent which
  can cause havoc if they "steal" each other's wakeups.

- Replace Endpoint._lock in related endpoints with a BrokenLock. If the parent
  is holding locks when it forks, they remain locked forever in the child.
  BrokenLock.acquire() raises instead of hanging.

3. Selector.stop() called on atexit.

Selector.stop was registered via atexit, which could cause a hang if
qpid.messaging was used in a later-executing atexit function. That has been
removed, Selector.run() is in a daemon thread so there is no need for stop()

4. User calls Selector.stop() directly

There is no reason to do this for the default Selector used by qpid.messaging,
so for that case stop() is now ignored. It works as before for code that creates
its own qpid.Selector instances.
1 file changed
tree: 7cd14cdd8dc4845d9b6c08aaa78d0ec94515b611
  1. examples/
  2. mllib/
  3. qpid/
  4. qpid_tests/
  5. .gitignore
  6. LICENSE.txt
  7. MANIFEST.in
  8. NOTICE.txt
  9. qpid-python-test
  10. qpid-python-test-ant.xml
  11. qpid-python-test.bat
  12. README.md
  13. setup.py
README.md

Qpid Python

This distribution contains a Python client implementation and AMQP conformance tests for Apache Qpid.

You can read more about Qpid here:

http://qpid.apache.org

Documentation can be found here:

http://qpid.apache.org/documentation.html

Getting started

  1. Make sure the Qpid Python client libraries are on your PYTHONPATH. Extract the archive and add the local directory to your PYTHONPATH:

     $ tar -xf qpid-python-VERSION.tar.gz
     $ cd qpid-python-VERSION
     $ export PYTHONPATH=$PWD:$PYTHONPATH
    
  2. Make sure a broker is running.

  3. Run the ‘hello’ example from examples/api:

     $ cd examples/api
     $ ./hello
     Hello world!
    

Examples

The examples directory contains sample programs. See examples/README.txt for more information.

Running the tests

The tests directory contains a collection of unit tests for the Python client. The tests_0-10, tests_0-9, and tests_0-8 directories contain protocol-level conformance tests for brokers that speak the specified AMQP version.

The qpid-python-test script may be used to run these tests. It will by default run the Python unit tests and the 0-10 conformance tests:

  1. Run a broker on the default port.

  2. Run the tests:

     $ ./qpid-python-test
    

If you wish to run the 0-8 or 0-9 conformence tests, they may be selected as follows:

  1. Run a broker on the default port.

  2. Run the tests:

     $ ./qpid-python-test tests_0-8.*
    
     [or]
    
     $ ./qpid-python-test tests_0-9.*
    

See the qpid-python-test command-line help for for additional options:

$ ./qpid-python-test -h

Installation

Other Qpid components depend on Qpid Python for testing. You can use setup.py to install Qpid Python to a standard location:

# User-local install

$ python setup.py install --user
$ export PYTHONPATH=$HOME/.local/lib/python2.7/site-packages
$ export PATH=$HOME/.local/bin:$PATH

[or]

# System-wide install

$ sudo python setup.py install