You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@qpid.apache.org by "Justin Ross (JIRA)" <ji...@apache.org> on 2016/08/10 14:34:20 UTC
[jira] [Closed] (QPID-6836) qpid.messaging hangs in child forked
process
[ https://issues.apache.org/jira/browse/QPID-6836?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Justin Ross closed QPID-6836.
-----------------------------
> qpid.messaging hangs in child forked process
> --------------------------------------------
>
> Key: QPID-6836
> URL: https://issues.apache.org/jira/browse/QPID-6836
> Project: Qpid
> Issue Type: Bug
> Components: Python Client
> Affects Versions: 0.32
> Reporter: Brian Bouterse
>
> A python process that uses qpid.messaging and then forks causes qpid.messaing use in the child process to randomly hang. To reproduce:
> 1. in a python process instantiate a qpid.messaing client and call open()
> 2. Call os.fork()
> 3. Try to instantiate another qpid.messaging client and call open()
> 4. observe the child process is waiting on a file descriptor that is shared with the parent which will never wake up.
> Here is a potential reproducer with actual python code (from kgiusti):
> {code:none}
> #!/usr/bin/env python
> #
> # Licensed to the Apache Software Foundation (ASF) under one
> # or more contributor license agreements. See the NOTICE file
> # distributed with this work for additional information
> # regarding copyright ownership. The ASF licenses this file
> # to you under the Apache License, Version 2.0 (the
> # "License"); you may not use this file except in compliance
> # with the License. You may obtain a copy of the License at
> #
> # http://www.apache.org/licenses/LICENSE-2.0
> #
> # Unless required by applicable law or agreed to in writing,
> # software distributed under the License is distributed on an
> # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> # KIND, either express or implied. See the License for the
> # specific language governing permissions and limitations
> # under the License.
> #
> import optparse, time
> from qpid.messaging import *
> from qpid.util import URL
> from qpid.log import enable, DEBUG, WARN
> import os
> import sys
> def nameval(st):
> idx = st.find("=")
> if idx >= 0:
> name = st[0:idx]
> value = st[idx+1:]
> else:
> name = st
> value = None
> return name, value
> parser = optparse.OptionParser(usage="usage: %prog [options] ADDRESS [ CONTENT ... ]",
> description="Send messages to the supplied address.")
> parser.add_option("-b", "--broker", default="localhost",
> help="connect to specified BROKER (default %default)")
> parser.add_option("-r", "--reconnect", action="store_true",
> help="enable auto reconnect")
> parser.add_option("-i", "--reconnect-interval", type="float", default=3,
> help="interval between reconnect attempts")
> parser.add_option("-l", "--reconnect-limit", type="int",
> help="maximum number of reconnect attempts")
> parser.add_option("-c", "--count", type="int", default=1,
> help="stop after count messages have been sent, zero disables (default %default)")
> parser.add_option("-d", "--durable", action="store_true",
> help="make the message persistent")
> parser.add_option("-t", "--timeout", type="float", default=None,
> help="exit after the specified time")
> parser.add_option("-I", "--id", help="use the supplied id instead of generating one")
> parser.add_option("-S", "--subject", help="specify a subject")
> parser.add_option("-R", "--reply-to", help="specify reply-to address")
> parser.add_option("-P", "--property", dest="properties", action="append", default=[],
> metavar="NAME=VALUE", help="specify message property")
> parser.add_option("-M", "--map", dest="entries", action="append", default=[],
> metavar="KEY=VALUE",
> help="specify map entry for message body")
> parser.add_option("-v", dest="verbose", action="store_true",
> help="enable logging")
> opts, args = parser.parse_args()
> if opts.verbose:
> enable("qpid", DEBUG)
> else:
> enable("qpid", WARN)
> if opts.id is None:
> spout_id = str(uuid4())
> else:
> spout_id = opts.id
> if args:
> addr = args.pop(0)
> else:
> parser.error("address is required")
> content = None
> content_type = None
> if args:
> text = " ".join(args)
> else:
> text = None
> if opts.entries:
> content = {}
> if text:
> content["text"] = text
> for e in opts.entries:
> name, val = nameval(e)
> content[name] = val
> else:
> content = text
> # no entries were supplied, so assume text/plain for
> # compatibility with java (and other) clients
> content_type = "text/plain"
> import pdb
> conn = Connection(opts.broker,
> reconnect=opts.reconnect,
> reconnect_interval=opts.reconnect_interval,
> reconnect_limit=opts.reconnect_limit)
> conn.open()
> print("Conn open")
> pid = os.fork()
> if not pid:
> #child
> try:
> #pdb.set_trace()
> ssn = conn.session()
> snd = ssn.sender(addr)
> count = 0
> start = time.time()
> while (opts.count == 0 or count < opts.count) and \
> (opts.timeout is None or time.time() - start < opts.timeout):
> msg = Message(subject=opts.subject,
> reply_to=opts.reply_to,
> content=content)
> if opts.durable:
> msg.durable = True
> if content_type is not None:
> msg.content_type = content_type
> msg.properties["spout-id"] = "%s:%s" % (spout_id, count)
> for p in opts.properties:
> name, val = nameval(p)
> msg.properties[name] = val
> snd.send(msg)
> count += 1
> print msg
> except:
> print("booboo")
> os._exit(1)
> print("buh-bye")
> os._exit(0)
> else:
> status = os.wait()[1]
> #pdb.set_trace()
> conn.close()
> sys.exit(status)
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org