Python 3.x 等待所有其他协同路由被阻止?

Python 3.x 等待所有其他协同路由被阻止?,python-3.x,pytest,python-asyncio,Python 3.x,Pytest,Python Asyncio,我正在尝试测试异步通信。交换安全消息的协议是: 发送信息,要求对方暂时停止 等待响应,直到超时 使用收到的NONCE发送加密消息 虽然以下代码在生产环境中工作,但测试起来确实很痛苦: import asyncio import pytest messages = [] async def send_request(message): global messages messages.append(message) class Node: def __init__(se

我正在尝试测试异步通信。交换安全消息的协议是:

  • 发送信息,要求对方暂时停止
  • 等待响应,直到超时
  • 使用收到的NONCE发送加密消息
  • 虽然以下代码在生产环境中工作,但测试起来确实很痛苦:

    import asyncio
    import pytest
    
    messages = []
    async def send_request(message):
        global messages
        messages.append(message)
    
    class Node:
        def __init__(self):
            self.nonce = asyncio.Future()
        def send_message(self, message):
            asyncio.create_task(send_request(message))
        def send_get_nonce(self):
            self.send_message("NONCE_GET")
        def receive_nonce(self, nonce):
            self.nonce.set_result(nonce)
        def send_encrypted_message(self):
            asyncio.create_task(self.send_encrypted_message_impl())
        async def send_encrypted_message_impl(self):
            self.send_get_nonce()
            nonce = await asyncio.wait_for(self.nonce, 3)
            self.send_message(f"ENCRYPTED_MESSAGE {nonce}")
    
    @pytest.mark.asyncio
    async def test_communication():
        global messages
    
        node = Node()
    
        node.send_encrypted_message()
        await asyncio.sleep(0)
        await asyncio.sleep(0)
        assert messages.pop() == "NONCE_GET"
    
        node.receive_nonce(123)
        await asyncio.sleep(0)
        await asyncio.sleep(0)
        await asyncio.sleep(0)
        assert messages.pop() == "ENCRYPTED_MESSAGE 123"
    
    
    每当我创建一个任务时,我都需要从测试主体中获得运行它的许可。有没有办法避免多次
    等待asyncio.sleep(0)
    调用?我最多要一个这样的电话

    我更愿意保持
    节点
    的接口非
    异步
    ,因为安全通信只是
    节点
    行为的一部分,大多数其他用例是简单的同步请求-响应交换。安全通信是一个例外,在我看来,不保证异步传播到所有其他组件


    我还不熟悉协同路由,所以可能我解决这个问题的整个方法都有缺陷,还有更好的方法吗?

    我不确定让接口非异步会有什么好处,因为调用方仍然必须在事件循环中运行。等待消息出现的正确方法是使用
    asyncio.Event
    ,在附加消息后,在
    send\u request
    中设置该事件。然后你可以在
    test_communication
    @user4815162342中通过不使接口异步来等待
    该事件,这样我就不必对链中的每个调用都进行
    awat
    。谢谢你提醒我关于
    事件的事
    ——这正是我想要的!