[
https://issues.apache.org/jira/browse/QPID-5637?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13984433#comment-13984433
]
Justin Ross commented on QPID-5637:
-----------------------------------
Speaking to the bigger issue (and not the specific patch that's offered here;
that seems fine), mixing threading and forking in an application with our
python api is going to be a problem. Addressing it is going to be a big job,
and it might be too big.
http://bugs.python.org/issue6721
http://stackoverflow.com/questions/12984003/status-of-mixing-multiprocessing-and-threading-in-python
http://rachelbythebay.com/w/2011/06/07/forked/
> qpid.messaging Issues With Forking
> ----------------------------------
>
> Key: QPID-5637
> URL: https://issues.apache.org/jira/browse/QPID-5637
> Project: Qpid
> Issue Type: Bug
> Components: Python Client
> Affects Versions: 0.24
> Reporter: Brian Bouterse
> Priority: Blocker
> Fix For: 0.18, 0.22, 0.24, 0.26, 0.27
>
> Attachments: celery_worker_output.txt, pid_aware_selector.patch,
> tasks.py
>
>
> qpid.messaging has an issue with forking in the following situation.
> 1. A parent Python process imports and uses qpid.messaging to connect to a a
> Qpid broker
> 2. The parent process forks a child process
> 3. The child process imports qpid.messaging and tries to connect to a Qpid
> broker.
> I expected to see the child process use qpid.messaging normally as it would
> if it weren't forked in the way described above. Instead, the server
> receives the opening of a TCP socket, but the client never sends the AMQP
> protocol announcement.
> [Forking bring child descriptors with
> it|http://man7.org/linux/man-pages/man2/fork.2.html]. I expected the file
> descriptors on the parent and the child to be the same, and to reference the
> same socket, so I expect qpid.messaging to work without any modification.
> Surprisingly, it does not.
> There is at least one place where I do understand how this can be avoided.
> One of the issues is that the file descriptors registered by the Selector
> object inside of qpid.messaging are stale after the fork. The Selector
> object uses a singleton pattern to provide a reference to the same Selector
> object no matter how many times you call it. This selector object already
> has registered file descriptors with the filesystem, which allow the selector
> to read/write data in an I/O efficient manner. See the attached
> [pid_aware_selector.patch] for an example of this.
> The [pid_aware_selector.patch] does allow communication to flow, but queue
> creation and deletion sometimes fail in strange ways. For instance, in the
> child process, code that creates a queue, reads information about that queue
> next. The queue was created, yet the read says that the queue can't be
> found. Very strange. You can see those things fail using the following
> example:
> 1. clone our fork of kombu: `git clone [email protected]:pulp/kombu.git`
> 2. Change into the kombu folder `cd kombu`
> 3. Switch to the branch containing the qpid code: `git checkout
> pulp-dep-3.0.15-with-qpid`
> 4. Install kombu onto your system or virtualenv (I do it systemwide using
> sudo): `sudo python setup.py develop`
> 5. install celery version 3.1.11. I do it using pip. `sudo pip install
> celery==3.1.11`
> 6. Install qpid.messaging and qpidtoollibs. One way I do it is systemwide
> using pip. `sudo pip install qpid-tools qpid-python`
> 7. Start up qpidd (We've been testing with 0.24 and auth off). `sudo -u
> qpidd qpidd --auth=no`
> 8. Put the attached file tasks.py into a directory
> 9. Open two terminals and change their working directory to be the same as
> step 8.
> 10. In one one terminal start the celery worker `celery worker -A
> tasks --loglevel=INFO -c1`
> 11. In the other terminal dispatch 10 tasks `python tasks.py`
> You should see exceptions raised similar to those in the attached file
> [celery_worker_output.txt]
> Note, that the code on the pulp-dep-3.0.15-with-qpid branch of kombu monkey
> patches qpid.messaging with the selector patch referenced above, and also one
> or two other bugfix patches. You can see that [monkey patching done
> here|https://github.com/pulp/kombu/blob/pulp-dep-3.0.15-with-qpid/kombu/transport/qpid.py#L45].
> This should have no implications on this issue, but I want to be explicit
> about it.
> A potential fix: Celery supports a callback after child processes are
> forked, allowing the call to cleanup/reset exactly these types of things. I
> could wire up that callback if such a thing existed on qpid.messaging. For
> testing purposes, you could put a call to this cleanup method in the
> 'sometask' code before the call to controller.inspect().active_queues().
> This would be similar in timing to a post fork cleanup/reset call.
> Note: the original connection and associated senders/receivers/sessions are
> still in use by the parent process, so calling close() is not the right thing
> to do either. It's like the connection needs to be forgotten, and the file
> descriptors unregistered from the child process.
--
This message was sent by Atlassian JIRA
(v6.2#6252)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]