kakts-log

programming について調べたことを整理していきます

rust 非同期I/Oライブラリのtokio でasync fnを使う際にrt-multi-threadを有効にする

概要

rustで 非同期I/Oライブラリのtokioを使って、async fnを利用する際、実行時に下記エラーとなった際の対処法をまとめます。

error: The default runtime flavor is multi_thread, but the rt-multi-thread feature is disabled.

今回は簡単なweb apiを実装する際を例に挙げます。

コード

Cargo.toml

[package]
name = "web-api"
version = "0.1.0"
edition = "2021"

[dependencies]
axum = "0.8.0"
tokio = "1.42.0"

axumというwebフレームワークと、tokioという非同期I/Oライブラリを使って、3000番ポートでリクエストを受け付ける簡単なサーバを実装します。

src/main.rs

use axum::{
    routing::get,
    Router,
};

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(|| async { "Hello, World!" }));

    // port 3000でリクエストを待ち受ける
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

この際、main()関数は asyncキーワードと #[tokio::main] 属性を記述しています。

このコードを起動時に、先ほど説明した通り、下記エラーになりました。

error: The default runtime flavor is `multi_thread`, but the `rt-multi-thread` feature is disabled.
 --> src/main.rs:6:1
  |
6 | #[tokio::main]
  | ^^^^^^^^^^^^^^
  |
  = note: this error originates in the attribute macro `tokio::main` (in Nightly builds, run with -Z macro-backtrace for more info)

エラーを読んでみると、 tokioを利用する際にはランタイムフレーバーを選ぶことができますが、デフォルトだとmulti_thread というフレーバーになっているようです。
このフレーバーを使う際は、 tokiort-multi-threadというフィーチャーフラグを有効にする必要がありますが、上述したコード・tomlの設定だとそれが無効になっているようでした。

tokioのフィーチャーフラグで rt-multi-thread 機能を有効にする

Cargo.tomlのtokiofeatures項目で tokioのフィーチャーフラグの有効・無効の設定ができます。

docs.rs

設定例

tokio = { version = "1", features = ["rt", "net"] }

tokiort-multi-thread 機能を有効にするには、 rt-multi-threadというフィーチャーフラグを有効にする必要があります。

rt-multi-thread: Enables the heavier, multi-threaded, work-stealing scheduler.

他にも複数の機能があるのですが、それらをまとめて有効にする際には fullを指定してあげれば他の機能も全て有効にできるようです。

full: Enables all features listed below except test-util and tracing.

そのため、今回発生したエラーに関しては、 Cargo.tomlでfeaturesにfullrt-multi-thread を指定してあげることで マルチスレッドの機能が利用でき、解決できます。

tokio = { version = "1.42.0", features = ["full"]}

もしくは

tokio = { version = "1.42.0", features = ["rt-multi-thread"]}

となります。 実運用においては、必要な機能だけ使えるようにする方が良いので、rt-multi-threadの指定がベターかと思います。

github.com