简体   繁体   English

关闭/修改来自 FASTAPI 端点的现有 aio_pika 连接

[英]Close/modify an existing aio_pika connection from a FASTAPI endpoint

I am using aio_pika as a robust interface for rabbitmq.我使用 aio_pika 作为 rabbitmq 的健壮接口。 FASTAPI startup event creates an aio_pika channel and starts consuming a queue as seen below. FASTAPI 启动事件创建一个 aio_pika 通道并开始使用一个队列,如下所示。 What I need to do is have an endpoint that closes/modifies this connection that is already running.我需要做的是有一个端点来关闭/修改这个已经在运行的连接。 This allows another remote application close/modify this consumer.这允许另一个远程应用程序关闭/修改此使用者。

I want this endpoint, but I don't know how to pass an endpoint the swarm_connection which is already instantiated by the FASTAPI startup event.我想要这个端点,但我不知道如何将已经由 FASTAPI 启动事件实例化的 swarm_connection 传递给端点。

#The endpoint I need, but how to pass in swarm_connection?
@app.get("/close")
async def close_pika():
    swarm_connection.close()

Code I have so far that is working to start things up到目前为止,我正在努力启动的代码

@app.on_event("startup")
def startup():
    loop = asyncio.get_event_loop()
    asyncio.ensure_future(main(loop))

async def main(loop):
    #RabbitMQ
    swarm_connection = await aio_pika.connect_robust(host=host,
                                               port=5672,
                                               login=login,
                                               password=pass,
                                               loop=loop
                                               )
    # Creating channel
    swarm_channel = await swarm_connection.channel()
    # Maximum message count which will be processing at the same time.
    await swarm_channel.set_qos(prefetch_count = 1)

    org1_queue = await swarm_channel.declare_queue('org1', auto_delete=False, durable=True, arguments={'x-max-priority':1})
    await org1_queue.consume(solve_problem_test)

The asyncio.wait method can wait for the first of several async tasks to complete (if run with the argument return_when=asyncio.FIRST_COMPLETED ). asyncio.wait方法可以等待几个异步任务中的第一个完成(如果使用参数return_when=asyncio.FIRST_COMPLETED运行)。 So one idea would be use an asyncio.Event as a signal.所以一个想法是使用asyncio.Event作为信号。 Modify the last line in your main method to wait for either your queue or the event being set, and set the event in your /close endpoint.修改main方法中的最后一行以等待队列或设置的事件,然后在/close端点中设置事件。 Something along the lines of:类似于以下内容:

closing_connection = asyncio.Event()

@app.get("/close")
async def close_pika():
    closing_connection.set()

# ...
async def main(loop):
    # ...
    _, pending = await asyncio.wait(
        [org1_queue.consume(solve_problem_test), closing_connection.wait()],
        return_when=asyncio.FIRST_COMPLETED
    )
    for task in pending:
        task.cancel()

    # Here you can call swarm_connection.close() or whatever you need to do

The last part is to cancel whichever task was not awaited.最后一部分是取消任何未等待的任务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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