繁体   English   中英

Pyhon Pika如何使用GeventConnection

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM