如何在BaseProxy上调用方法时有效地使用asyncio?

Chr*_*oph 18 python python-asyncio python-multiprocessing

我正在开发一个应用程序,它使用LevelDB并使用多个长期存在的进程来执行不同的任务.

由于LevelDB只允许单个进程维护数据库连接,因此我们所有的数据库访问都通过特殊的数据库进程进行汇集.

要从另一个进程访问数据库,我们使用a BaseProxy.但是因为我们使用asyncio我们的代理不应该阻塞这些调用db进程然后最终从db读取的API.因此,我们使用执行程序在代理上实现API.

    loop = asyncio.get_event_loop()

    return await loop.run_in_executor(
        thread_pool_executor,
        self._callmethod,
        method_name,
        args,
    )
Run Code Online (Sandbox Code Playgroud)

尽管这工作得很好,我不知道是否有到包裹一个更好的选择_callmethod的通话BaseProxyThreadPoolExecutor.

我理解它的方式,BaseProxy调用DB进程是等待IO的教科书示例,因此使用线程这似乎是不必要的浪费.

在一个完美的世界中,我假设async _acallmethod存在,BaseProxy但不幸的是,API不存在.

因此,我的问题基本归结为:在使用时,BaseProxy是否有更有效的替代方法来运行这些跨进程调用ThreadPoolExecutor

Mar*_*ers 5

不幸的是,多处理库不适合转换为asyncio,如果必须使用它BaseProxy来处理IPC(进程间通信),那么您所拥有的就是最好的。

虽然库确实使用了阻塞I / O,但您不能轻易进入并重新处理阻塞部分以使用非阻塞原语。如果您坚持采用这种方法,则必须修补或重写该库的内部实现细节,但是作为内部实现细节,这些细节可能与Python点发行版本不同,从而使得任何修补程序都非常脆弱且容易中断。 Python升级。该_callmethod方法是涉及线程,套接字或管道连接以及序列化程序的深层抽象层次的一部分。请参阅multiprocessing/connection.pymultiprocessing/managers.py

所以在这里你的选择是坚持当前的做法(使用线程池执行人推BaseProxy._callmethod()到另一个线程)Ø [R使用ASYNCIO原语来实现自己的IPC解决方案。中央数据库访问进程将充当服务器,供其他进程使用套接字或命名管道,并使用针对客户端请求和服务器响应的商定序列化方案,以客户端身份连接到客户端。这是multiprocessing为您实现的,但是您将使用asyncio 以及最适合您的应用程序模式的任何序列化方案(例如,pickle,JSON,protobuffers或完全其他的东西)来实现自己的(简单)版本。