【问题标题】:Is there any linter that detects blocking calls in an async function?是否有任何 linter 可以检测异步函数中的阻塞调用?
【发布时间】:2019-05-01 11:27:15
【问题描述】:

https://www.aeracode.org/2018/02/19/python-async-simplified/

如果你调用非阻塞同步函数不会毁了你的一天 函数,像这样:

def get_chat_id(name):
    return "chat-%s" % name

async def main():
    result = get_chat_id("django")

但是,如果您调用阻塞函数,例如 Django ORM,则 async 函数中的代码看起来相同,但现在是 可能会阻塞整个事件循环的危险代码,因为它不是 等待:

def get_chat_id(name):
    return Chat.objects.get(name=name).id

async def main():
    result = get_chat_id("django")

您可以看到拥有一个非阻塞函数是多么容易 如果程序员没有超级意识,“意外地”就会阻塞 所有调用它的东西。这就是为什么我建议你永远不要打电话 任何从异步函数同步的东西,但没有安全地执行, 或者事先不知道它是一个非阻塞标准库 函数,如os.path.join

所以我正在寻找一种方法来自动捕获此错误的实例。是否有任何用于 Python 的 linter 会将异步函数中的同步函数调用报告为违规?

我可以配置 Pylint 或 Flake8 来执行此操作吗?

我不一定介意它是否也捕捉到上面的第一种情况(这是无害的)。


更新:

正如米哈伊尔的回答所指出的那样,在某种程度上,我意识到这是一个愚蠢的问题。我们需要的是定义 linter 应该检测到的“危险同步函数”。

因此,出于这个问题的目的,我给出以下定义:

“危险的同步函数”是一种执行 IO 操作的函数。例如,这些操作必须由 gevent 进行猴子修补,或者必须包装在 async 函数中,以便事件循环可以进行上下文切换。

(我欢迎对此定义进行任何改进)

【问题讨论】:

  • 我们定义了“危险的同步函数”——它是任何def 定义的函数,需要很长时间(>0.05 秒)才能执行。不管是由于 I/O 还是由于其他原因(如繁重的计算)。无论如何,在运行之前都无法检测到这些变体:想象一下 eval() 随机字符串的代码 - 在真正执行它之前你无法预测会发生什么。
  • 不,由于在 cpu 上执行代码而需要很长时间的函数和由于等待 i/o 而需要很长时间的函数之间存在差异。我们在这里只关心后者,因为异步方法对前者毫无帮助
  • 异步方法根本无法帮助您使用 Django ORM,除非您完全重写它。我说得通吗?
  • 这个问题与 Django ORM 无关。但是由于 Django ORM a) 执行 I/O 并且 b) 不是通过异步调用的,所以这是我希望 linter 捕获的代码示例。换句话说 - 如果我错误地使用了 Django ORM 而不是 asyncpg 我想被警告。
  • 老实说,我不认为这是一个愚蠢的问题,如果确实有解决方案,这可能对其他人非常有帮助。我知道这很难确定。

标签: python-3.x python-asyncio pylint flake8


【解决方案1】:

所以我正在寻找一种方法来自动捕获此实例 错误。

让我们澄清一些事情:文章中讨论的错误是当您在某个 asyncio 协程中调用任何长时间运行的同步函数时(它可以是 I/O 阻塞调用或只是具有大量计算的纯 CPU 函数)。这是一个错误,因为它会阻塞整个事件循环,这会导致性能显着下降(更多关于它here 包括答案下方的 cmets)。

有没有办法自动捕捉这种情况?在运行时间之前 - 不,没有人可以预测特定功能是否需要 10 秒或 0.01 秒才能执行。在运行时它已经是built-in asyncio,您所要做的就是启用调试模式。

如果您担心某些同步功能会在长时间运行(在调试模式下的运行时可检测到)和短时运行(无法检测到)之间变化,只需使用 run_in_executor 在后台线程中执行函数 - 它会保证事件循环不会被屏蔽。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    相关资源
    最近更新 更多