[英]Pyhon Pika how to use GeventConnection
提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文。
我们有几个从消息队列中使用的任务。 这些任务的运行时间取决于从数据库中获取一些数据。 因此,如果某些数据库请求需要很长时间,我们希望与Gevent合作,不要阻止程序。 我们正试图将它与Pika客户端结合起来,它有一些异步适配器,其中之一是用于 gevent 的: pika.adapters.gevent_connection.GeventConnection
。
我设置了一些玩具代码,它从一个由整数组成的 MQ 任务中消耗并将它们发布到另一个队列,同时为每个奇数休眠 4 秒:
# from gevent import monkey
# # Monkeypatch core python libraries to support asynchronous operations.
# monkey.patch_time()
import pika
from pika.adapters.gevent_connection import GeventConnection
from datetime import datetime
import time
def handle_delivery(unused_channel, method, header, body):
"""Called when we receive a message from RabbitMQ"""
print(f"Received: {body} at {datetime.now()}")
channel.basic_ack(method.delivery_tag)
num = int(body)
print(num)
if num % 2 != 0:
time.sleep(4)
channel.basic_publish(
exchange='my_test_exchange2',
routing_key='my_test_queue2',
body=body
)
print("Finished processing")
def on_connected(connection):
"""Called when we are fully connected to RabbitMQ"""
# Open a channel
connection.channel(on_open_callback=on_channel_open)
def on_channel_open(new_channel):
"""Called when our channel has opened"""
global channel
channel = new_channel
channel.basic_qos(prefetch_count=1)
channel.queue_declare(queue="my_queue_gevent5")
channel.exchange_declare("my_test_exchange2")
channel.queue_declare(queue="my_test_queue2")
channel.queue_bind(exchange="my_test_exchange2", queue="my_test_queue2")
channel.basic_consume("my_queue_gevent5", handle_delivery)
def start_loop(i):
conn = GeventConnection(pika.ConnectionParameters('localhost'), on_open_callback=on_connected)
conn.ioloop.start()
start_loop(1)
如果我在没有调用monkey.patch_time()
的情况下运行它,它可以正常工作,并且它会在my_test_queue2
上发布结果,但它会按顺序工作。 添加monkey.patch_time()
补丁后的预期行为是它仍然有效但同时发生。 但是,代码在调用time.sleep(4)
。 它处理并发布第一个 integer,即 0,然后当 if 子句被触发时卡在 1。 我究竟做错了什么?
在ChatGPT的帮助下,我设法让它工作了。 缺少一个gevent.spawn()
调用:
def handle_delivery(unused_channel, method, header, body):
print("Handling delivery")
gevent.spawn(process_message, method, body)
def process_message(method, body):
print(f"Received: {body} at {datetime.now()}")
channel.basic_ack(method.delivery_tag)
num = int(body)
print(num)
if num % 2 != 0:
time.sleep(4)
channel.basic_publish(
exchange='my_test_exchange2',
routing_key='my_test_queue2',
body=body
)
print("Finished processing")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.