LoginSignup
5
2

More than 5 years have passed since last update.

PyO3/tokioでPythonのイベントループをまわす

Posted at

はじめに

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

というような感じでした。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2