Timeouts and Cancellations for Humans

说明: 原文出处Timeouts and cancellation for humans — njs blog (vorpus.org)。 译者以已经获得了原作者的允许以翻译该文章。 本文原作者为Nathaniel J. Smith,Trio库的作者,NumPy, PyPa相关项目的代码贡献者。 术语翻译说明:翻译内容可能混用,函数参数名会保留英文,常见词(如bug)不翻译。 primitive: 原语、底层函数 cancel scope: 取消域 cancel token: 取消令牌 timeout: 超时 deadline: 大家很习惯且考虑到翻译成截止时间比较啰嗦就不做翻译了。 shield: 没有想好如何翻译,就没有做翻译。 nursery: Trio中的一个启动子任务的系统,翻译成托儿所有点傻,就未做翻译。 其他翻译:见翻译说明 本文评论使用的是disqus 引言 你的代码可能完美无缺,但不幸的是外面的世界并不这么靠谱。有些时候,其他人的代码可能会崩溃或者卡住。网络会掉线,打印机会报错。你的代码也需要为这些情况做好准备。每当你从网络读取数据、尝试获取跨进程锁、或者发送一条HTTP请求,你至少要考虑到以下三种可能: 请求可能成功 请求可能失败 请求可能挂起。春去秋来,没有成功,没有失败,没有任何响应。 前面两种情况非常直观。最后一种情况你需要使用超时来处理。几乎每一处你与其他进程、系统通信的地方都需要设置超时,如果你没有设置超时,那就是一个潜在的bug。 说实话,如果你也像大多数开发者一样,那么你的代码可能会有很多因为缺失超时导致的bug,我的代码也是这样的。因为正确进行I/O操作非常常见且重要,你可能觉得任何一种编程环境都能为所有操作提供简单而健壮的设置超时的方法。但奇怪的是,事实并不如此。大多数带超时的API都非常单调且容易出错,以至于要求开发人员把这些弄对是不切实际的。所以别难过,你的代码有这些超时相关的bug并不是你的错,而是那些I/O库的错! 我目前正在写一个I/O库。和其他任何I/O库都不一样,这个I/O库的所有卖点是它痴迷于简单易用。我想让你能够在使用Trio时,能够简单而又正确地对任意I/O操作应用超时。但是,用户友好的超时API是一件很棘手的事。所以我会在这篇博客中深入讨论各种可能的设计,特别是那些给我提供灵感的设计。接下来我会介绍我想到的设计,以及为什么我会认为该设计是古老的”状态艺术”的一个切实优化。最后,我将会讨论为什么Trio库的思路为适应面更广,同时我将会给出一个不错的同步Python的原型实现。 那么超时处理有什么难的呢? 目录: 简单的超时机制不支持抽象 绝对的deadline是可组合的(但是用起来很麻烦) 取消令牌(Cancel tokens) 取消令牌封装了取消状态 取消令牌属于水平触发,可以根据你程序的需要来确定范围 实际上因为人类的懒惰取消令牌并不可靠 取消域: Trio关于超时和取消的人性化方案 取消域(Cancel scope)是如何工作的 我们需要在哪些地方检查取消? 一个逃逸口(escape hatch) 取消域与并发 小结 还有哪些地方可以从取消域中受益? 同步、单线程Python asyncio 其他语言 现在去修复你的超时bug! 注释 翻译说明 简单的超时机制不支持抽象 最简单的处理超时的方式无疑是给每个可能阻塞的函数加上timeout参数。在Python标准库中,你可以找到像threading....

February 7, 2023 · Author Nathaniel J. Smith, translated by Dennis