异步编程
2016 年 9 月 29 日,我们按每周四发布的节奏发布了 Home Assistant 0.29。这个版本由 本 主导,对 Core 进行了全面的异步化改造。
旧版 Core 的架构类似于“传统”的多线程应用。每个非线程安全的资源(例如实体状态)都由锁保护。这会带来大量等待和潜在竞争,因为任务往往需要等到资源释放后才能继续执行。
新的 Core 基于 Python 内置的 asyncio 模块。现在,Core API 对象不再允许任意线程直接访问,而是统一限制在一个称为“事件循环”的专用线程中。所有组件都会把自身的工作调度为由事件循环执行的任务。这样可以保证同一时刻只运行一个任务,因此不再需要加锁。
这种设计的主要挑战在于阻塞 I/O。如果某个任务执行阻塞 I/O,整个事件循环都会停下来;而大多数第三方 Python 库默认都会这样工作。例如,当向设备请求新信息时,Core 会一直停住,直到设备返回响应。为了解决这个问题,任务可以在等待响应时主动挂起自己,并在结果可用后重新排队,由事件循环继续处理。
要让任务能够挂起,调用链上的所有代码都必须支持异步。这实际上意味着,设备集成所依赖的库也都需要支持异步。由于这在现实中不可能一次性全部完成,我们提供了 100% 兼容的 API,方便现有集成逐步迁移。
这些兼容 API 的工作方式是:在其他线程中调度任务,并阻塞该线程,直到事件循环处理完任务。

