Closed GoogleCodeExporter closed 9 years ago
I'm not sure this is realistically possible. basic_consume issues a
basic.consume method to the broker and
associates a callback with the associated consumer key, but doesn't actually
process any messages.
Conversely, when you call wait() on a channel, any server-initiated message
gets handled, not just message
delivery for any specific consumer. This is a little easier to see if you call
basic_consume twice (with different
queues and callbacks) -- wait() will dispatch a message to either one,
depending on which queue receives a
message first.
Can you turn your loop inside out? Consider something like
def mainloop(chan):
msg = yield
while msg:
print msg.body
chan.basic_ack(msg.delivery_tag)
msg = yield
# ...
# Kick off generator
m = mainloop(chan)
m.next()
chan.basic_consume('q', callback=m.send)
would let you write your main loop in a mostly-imperative style.
Original comment by angrybal...@gmail.com
on 24 Dec 2009 at 4:36
Sorry, I'm not sure I clearly understand how that code would fit into the
context of my program. I've put together a code sample that I hope will make my
situation clearer:
#!/usr/bin/env python
from amqplib import client_0_8 as amqp
class Processor(object):
def __init__(self):
self.qhost = 'localhost'
self.qport = '5672'
self.uname = 'guest'
self.pwd = 'guest'
self.ssl = false
self.vhost = '/'
self.exch_name = 'fooX'
self.exch_type = 'direct'
self.queue_name = 'fooQ'
self.conn = amqp.Connection(userid=self.uname, password=self.pwd, host=self.qhost,
virtual_host=self.vhost, ssl=self.ssl)
self.chan = self.conn.channel()
self.chan.exchange_declare(self.exch_name, type=self.exch_type)
self.chan.queue_declare(self.qname)
self.chan.queue_bind(self.qname, self.exch_name)
def consume(self, callback):
self.chan.basic_consume(self.qname, callback=callback)
while True:
self.chan.wait()
class Munger(object):
def munge(self,msg):
if msg % 2 == 0:
yield msg
class Sender(object):
def run(self):
p = Processor(file='/tmp/msgs')
m = Munger()
for msg in p.consume(m.munge):
"""
I know this doesn't work right now. This
piece of the code should send 'msg' to another queue.
"""
pass
if __name__ == '__main__':
s = Sender()
s.run()
A couple of quick notes: Sender() in real life is a thread. Munger.munge()
actually parses the message and tries to put it in a database. Processor
doesn't look
much different from what you see here. The goal is that Processor and Munger
are actually pluggable -- so users can set things up such that Processor talks
to a
STOMP queue (that's already supported, actually), or Munge talks to MongoDB or
whatever. I hope to release the code as soon as I can get amqp working.
I've played with setting up an observer-like 'notify' in Processor and using
that as the callback for consume(), but it still doesn't get the msg back where
I need
it. I've thought of a couple of other things I might be able to do, but I
really haven't gotten to a solution. If your code example somehow fits
somewhere in here,
even if it forces me to rewrite large sections of my actual program, I'll do
it. I just need to understand. Appreciate your help and your work.
brian
Original comment by bkjo...@gmail.com
on 24 Dec 2009 at 5:03
Sorry, amqplib is not totally threadsafe. That's a big omission from the docs,
fixed in Rev 2c694206543d
You can however use it in a threaded program as long separate threads keep
separate Connection objects (and related Channel objects).
I agree that consuming without a callback is pointless, but it's pretty much
equivalent to redirecting a program's output to /dev/null, and I think is a
reasonable thing to do given no callback.
Original comment by barry.pe...@gmail.com
on 28 Mar 2011 at 9:33
Original issue reported on code.google.com by
bkjo...@gmail.com
on 24 Dec 2009 at 3:52