prefectのブログで、AnyIOが紹介されている。
prefectの内部的な非同期処理では、AnyIOが積極的に使われているようだ。AnyIOについて少し調べてみたので、メモしておく。
AnyIO
AnyIOは非同期処理を行うためのPythonライブラリ。
AnyIO is an asynchronous networking and concurrency library that works on top of either asyncio or trio. It implements trio-like structured concurrency (SC) on top of asyncio and works in harmony with the native SC of trio itself.
最近ようやくPythonの非同期処理の標準ライブラリであるasyncioを触りだしたが、いろいろと足りていないと感じる部分も多い。
trioはそんな部分を補うために作られたOSSライブラリだ。
一方でAnyIOのドキュメントと冒頭のブログによると、AnyIOは、asyncioとtrioの両方と互換性を持たせつつ、より統合されたAPIを提供することを目指している。
AnyIOはAlex Grönholmという方がメインのメンテナーをしている。Pythonの非同期処理界隈では有名な方のようだ。
この手のライブラリはコアチームにメンテされていくのが理想的だ。だがAnyIOにはasyncioやtrioそれぞれの開発者がAnyIOにコントリビュートしているらしく、継続性について一つの安心材料になると感じている。
AnyIOの特徴
asyncioでは非同期のファイル処理やネットワーク処理を簡潔に行うための関数やAPIが提供されていない。
そのため、ファイル処理ではaiofile、ネットワーク処理ではhttpxやaiohttpなどのライブラリを利用することが多い。
AnyIOでは、非同期のファイル処理や高水準なネットワーク処理を行うためのAPIを提供している。詳細な比較はできてないが、aiofileやaiohttpなどのライブラリをカバーすることができそうだ。
また、スレッドやプロセスも扱えるし、タスクをグループ化し、きめ細かいキャンセル処理を行うことができる。
AnyIO offers the following functionality:
Task groups (nurseries in trio terminology)
High-level networking (TCP, UDP and UNIX sockets)
- Happy eyeballs algorithm for TCP connections (more robust than that of asyncio on Python 3.8)
- async/await style UDP sockets (unlike asyncio where you still have to use Transports and Protocols)
A versatile API for byte streams and object streams
Inter-task synchronization and communication (locks, conditions, events, semaphores, object streams)
Worker threads
Subprocesses
Asynchronous file I/O (using worker threads)
Signal handling
AnyIOが依存するパッケージもミニマムなものだ。 pyproject.tomlのdependenciesを見てみると、以下のようなものがある。
dependencies = [
"exceptiongroup >= 1.0.2; python_version < '3.11'",
"idna >= 2.8",
"sniffio >= 1.1",
"typing_extensions >= 4.5; python_version < '3.13'",
]
以下は比較的小さなPythonライブラリだ:
その他は、あくまでPythonの標準ライブラリを拡張するためのもので、Pythonのバージョンが進めば不要になるものだ。
どれも軽量な依存関係で、AnyIOはPure Pythonに近い状態で書かれている、と言えるだろう。
このように、AnyIOはシンプルかつ高機能な非同期処理ライブラリであり、今後自分のプロジェクトでも使ってみたいと思った。
補足: ファイルの非同期処理について
asyncioにおける、非同期なファイルIOのサポートについて、StackOverflowが参考になった。
次のことが言及されている:
- asyncioではファイルIOは直接的にはサポートしていない
- そもそも、多くのOSでは、OSレベルで非同期なファイルIOをサポートしていない
- Linuxの最近のバージョン(>=4.18?)や、Windowsはサポートしている模様
- Node.jsの非同期ファイルAPIも、内部的にはスレッドを使っている
- aiofileも、内部的にはスレッドを使っている
そのほか、OSの非同期ファイルIOについては、次の記事も参考になった。