我希望能够在向AMQP提交邮件时检测交换是否存在。
请考虑以下示例。
#!/usr/bin/python
import amqp
from time import sleep
conn = amqp.Connection(host="localhost:5672", userid="guest", password="guest", virtual_host="/")
outgoing = conn.channel()
message = amqp.Message("x")
while True:
print "publish message."
outgoing.basic_publish(message,exchange="non-existing",routing_key="fubar")
sleep(1)
此脚本将继续发布到交换,但如果交换不存在则不会引发任何错误。当交换存在时,消息到达。
#!/usr/bin/python
import amqp
from time import sleep
conn = amqp.Connection(host="localhost:5672", userid="guest", password="guest", virtual_host="/")
outgoing = conn.channel()
message = amqp.Message("x")
while True:
print "publish message."
outgoing.basic_publish(message,exchange="non-existing",routing_key="fubar")
outgoing.wait()
sleep(1)
当我添加outgoing.wait()时,会引发amqp.exceptions.NotFound,这就是我想要的。但问题是,如果在这种情况下交换存在,则消息到达但是outgoing.wait()阻止我的循环。 (我可以在一个单独的线程中运行outgoing.wait(),但我不想这样做。)
如何处理?
任何建议提示指示欢迎
谢谢,
杰
答案 0 :(得分:4)
如果要查明是否存在交换,请使用exchange_declare方法并将passive标志设置为True。将passive标志设置为True将阻止服务器尝试创建交换,而是在交换不存在时抛出错误。
import amqp
from amqp.exceptions import NotFound
conn = amqp.Connection(host="localhost:5672", userid="guest", password="guest",
virtual_host="/")
outgoing = conn.channel()
try:
outgoing.exchange_declare("fubar", "", passive=True)
except NotFound:
print "Exchange 'fubar' does not exist!"
如果您真正感兴趣的是确保在发布之前存在交换,请在进入发送循环之前声明它。如果交换已经存在,则不会发生任何事情如果交换不存在,则会创建。
import amqp
conn = amqp.Connection(host="localhost:5672", userid="guest", password="guest",
virtual_host="/")
outgoing = conn.channel()
outgoing.exchange_declare("fubar", "direct")
以下是您正在使用的amqp库中exchange_declare方法声明的链接:
https://github.com/celery/py-amqp/blob/master/amqp/channel.py#L460-L461
答案 1 :(得分:1)
不幸的是,需要阻止调用来检查basic_publish()中的异常。但是,您可以执行的操作是在进入异步循环之前运行阻塞调用一次:
# send a test message synchronously to see if the exchange exists
test_message = amqp.Message('exchange_test')
outgoing.basic_publish(test_message,exchange="non-existing",routing_key="fubar")
try:
outgoing.wait()
except amqp.exceptions.NotFound:
# could not find the exchange, so do something about it
exit()
while True:
# fairly certain the exchange exists now, run the async loop
print "publish message."
outgoing.basic_publish(message,exchange="non-existing",routing_key="fubar")
sleep(1)