如何同时使用异步模块调用nameko服务 - python

我写这样的异步程序。永久运行循环启动4事件同时发生。每个事件将运行rpc服务。在nameko服务中,我使用time.sleep(10)实现该服务。

我很困惑为什么服务每10秒完成一次。我认为服务应同时完成。如何让工作同时完成?

def start_loop(loop):
    asyncio.set_event_loop(loop)
    loop.run_forever()


async def job(x):
    try:
        with ClusterRpcProxy(CONFIG) as rpc:
            res = rpc.helloworldService.helloworld(x)
            print(res)
    except Exception as e:
        print(f"{e}")


async def do_sleep(x, queue):
        try:
             await job(x)
             queue.put("ok")
        except Exception as e:
            print(f"{e}")


def consumer():
    asyncio.run_coroutine_threadsafe(do_sleep('10', queue), new_loop)
    asyncio.run_coroutine_threadsafe(do_sleep('11', queue), new_loop)
    asyncio.run_coroutine_threadsafe(do_sleep('12', queue), new_loop)
    asyncio.run_coroutine_threadsafe(do_sleep('13', queue), new_loop)


if __name__ == '__main__':
    print(time.ctime())
    new_loop = asyncio.new_event_loop()

    loop_thread = Thread(target=start_loop, args=(new_loop,))
    loop_thread.setDaemon(True)
    loop_thread.start()

    CONFIG = {'AMQP_URI': "amqp://guest:[email protected]"}
    queue = Queue()
    sema = asyncio.Semaphore(2)

    consumer_thread = Thread(target=consumer)
    consumer_thread.setDaemon(True)
    consumer_thread.start()

    while True:
        msg = queue.get()
        print("current:", time.ctime())

nameko rpc服务是:

class HelloWorld:
    name = 'helloworldService'

    @rpc
    def helloworld(self,str):
        time.sleep(10)
        return 'hello_'+str

输出结果如下:

hello_10
current: Sat Jan 26 13:04:57 2019
hello_11
current: Sat Jan 26 13:05:07 2019
hello_12
current: Sat Jan 26 13:05:17 2019
hello_13
current: Sat Jan 26 13:05:28 2019

参考方案

您必须使用可等待的睡眠,而不是不可等待的time.sleep()。因此,您的nameko RPC服务将如下所示:

import asyncio

class HelloWorld:
    name = 'helloworldService'

    @rpc
    async def helloworld(self,str):  # Note
        await asyncio.sleep(10)  # Note
        return 'hello_'+str

还有您的服务器代码:

async def job(x):
    try:
        with ClusterRpcProxy(CONFIG) as rpc:
            res = await rpc.helloworldService.helloworld(x)  # Note
            print(res)
    except Exception as e:
        print(f"{e}")

[注意]

但是您的RPC库也应该由asyncio实现。
这是一个异步asyncio RPC库(aiorpc)。

45码