はじめに
PyO3/tokioというRustで実装されたPython3向けのasyncioイベントループをまわすライブラリがあります。
つい先日(2018.06.25頃)GitHubリポジトリがアーカイブされてしまいましたが、動かすためのメモを残しておきます。
インストール
$ git clone https://github.com/PyO3/tokio.git
$ cd tokio
$ make build
ここでエラーが出てしまうので、以下のプルリクエストのパッチをあててcargo update
します。
diff --git a/Cargo.toml b/Cargo.toml
index 24cfe67..047a979 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -29,7 +29,7 @@ tokio-signal = "0.1"
tokio-uds = "0.1"
[dependencies.pyo3]
-version = "^0.2.6"
+version = "^0.2.7"
features = ["python3"]
[dev-dependencies]
diff --git a/src/lib.rs b/src/lib.rs
index 39510b4..4186461 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -49,7 +49,7 @@ pub use server::create_server;
pub use client::create_connection;
-#[py::modinit("_tokio")]
+#[py::modinit(_tokio)]
/// Asyncio event loop based on tokio-rs
fn init_async_tokio(py: Python, m: &PyModule) -> PyResult<()> {
let _ = env_logger::init();
動かす
asyncio使ってHTTPアクセスできるaio-libs/aiohttpモジュールと組み合わせて使ってみます。
import aiohttp
import asyncio
import tokio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession() as session:
html = await fetch(session, 'http://python.org')
print(html[:100])
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
$ python tokiohttp.py
<!doctype html>
<!--[if lt IE 7]> <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9"> <![endif]-->
<!-
tokioのイベントループで動いてるかどうかわかりにくいので、ログ出力してみます。
$ RUST_LOG=debug python tokiohttp.py
DEBUG:tokio_core::reactor: adding a new I/O source
DEBUG:tokio_core::reactor: loop poll - 29.99µs
DEBUG:tokio_core::reactor: loop time - Instant { t: 1247017756623912 }
DEBUG:tokio_core::reactor: consuming notification queue
DEBUG:tokio_core::reactor: added a timeout: 0
DEBUG:tokio_core::reactor: scheduling direction for: 0
DEBUG:tokio_core::reactor: blocking
:
DEBUG:tokio_core::reactor: loop process - 1 events, 307.091µs
DEBUG:tokio_core::reactor: loop poll - 12.654µs
DEBUG:tokio_core::reactor: loop time - Instant { t: 1247018957546308 }
<!doctype html>
<!--[if lt IE 7]> <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9"> <![endif]-->
<!-
DEBUG:tokio_core::reactor: updating a timeout: 0
DEBUG:tokio_core::reactor::timeout_token: cancel timeout 0
DEBUG:tokio_core::reactor: cancel a timeout: 0
DEBUG:tokio_core::reactor: loop process - 2 events, 569.892µs
DEBUG:tokio_core::reactor: loop poll - 11.526µs
DEBUG:tokio_core::reactor: loop time - Instant { t: 1247018958135120 }
DEBUG:tokio_core::reactor: updating a timeout: 1
DEBUG:tokio_core::reactor::timeout_token: cancel timeout 1
DEBUG:tokio_core::reactor: cancel a timeout: 1
DEBUG:tokio_core::reactor: scheduling direction for: 1
DEBUG:tokio_core::reactor: blocking
DEBUG:tokio_core::reactor: consuming notification queue
DEBUG:tokio_core::reactor: dropping I/O source: 1
DEBUG:tokio_core::reactor: scheduling direction for: 2
DEBUG:tokio_core::reactor: blocking
DEBUG:tokio_core::reactor: consuming notification queue
DEBUG:tokio_core::reactor: scheduling direction for: 3
DEBUG:tokio_core::reactor: blocking
DEBUG:tokio_core::reactor: loop process - 5 events, 332.505µs
というような感じでした。