Open5
試行:1つのバイナリで異なるフレームワークを同時に動作できるか
まずは,actix-webを2つ同時に動かせるか
仮説:2つ非同期関数を用意して,joinhandleとかで両方待つようにするとできる
main.rs
use actix_web::{
web::{self, block},
App, HttpRequest, HttpServer,
};
use tracing_actix_web::TracingLogger;
// #[instrument]
async fn index(req: HttpRequest) -> &'static str {
println!("index");
"Hello world!"
}
async fn dopanic() -> &'static str {
println!("dopanic");
panic!("dopanic");
"dopanic"
}
#[tokio::main]
async fn main() -> std::io::Result<()> {
// 2つの非同期を実行し,joinでまつ
let (a, b) = tokio::join!(actix_body1(), actix_body2());
a?;
b?;
Ok(())
}
async fn actix_body1() -> std::io::Result<()> {
println!("actix_body1");
HttpServer::new(|| {
App::new()
// enable logger
.service(web::resource("/index.html").to(|| async { "Hello world!" }))
.service(web::resource("/").to(index))
.service(web::resource("/dopanic").to(dopanic))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
async fn actix_body2() -> std::io::Result<()> {
println!("actix_body2");
HttpServer::new(|| {
App::new()
// enable logger
.service(web::resource("/index.html").to(|| async { "Hello world!" }))
.service(web::resource("/").to(index))
.service(web::resource("/dopanic").to(dopanic))
})
.bind(("127.0.0.1", 8081))?
.run()
.await
}
成功 join!マクロで並べるとできた
3つ以上も可能だろう
パニックからのリカバリも問題なさそうだ
仮説:actix-webとpoiseという異なるフレームワークでも,同様に動作可能
dependanciesにactix-webとpoiseの両方を追加
tokio::main
マクロのところでエラー
エラーメッセージ
proc macro `main` not expanded: No proc-macros present for crate
マクロがないと言っている?(そんなはずはない)
何かが衝突している?
失敗
1つのクレートにまとめて突っ込んだのがよくないのか?
仮説:ワークスペースを使って分離することで解決できる可能性
tokio部分をcoreに,actixをactix_body,poiseをpoise_bodyにクレート分割
core
fn main() -> std::io::Result<()> {
// 2つの非同期を実行し,joinでまつ
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build().expect("runtime build failed")
.block_on(async {
// let (a, b) = tokio::join!(actix_body::body(), poise_body::body());
// a?;
// b?;
Ok(())
})
}
actix_body
use actix_web::{web, App, HttpRequest, HttpServer};
pub async fn body() -> std::io::Result<()> {
println!("actix_body1");
HttpServer::new(|| {
App::new()
// enable logger
.service(web::resource("/index.html").to(|| async { "Hello world!" }))
.service(web::resource("/").to(index))
.service(web::resource("/dopanic").to(dopanic))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
async fn index(_req: HttpRequest) -> &'static str {
println!("index");
"Hello world!"
}
async fn dopanic() -> &'static str {
println!("dopanic");
panic!("dopanic");
"dopanic"
}
poise_body
pub async fn body() -> std::io::Result<()> {
println!("poise_body");
Ok(())
}
- ワークスペースのメンバー coreのみ
- とおる
- coreとpoise
- とおらない
- coreとactix
- とおる
???
tokio::mainマクロがエラーでまくる
マクロの内容を自力で書く
-> コンパイルエラー
マクロの時と同じ
マクロと同じことを自力で書くメリットはなさそう
失敗
ダメみたいだ.
poise単体で別のクレートつくってテスト
通らない
エラーを軽く見てみたが,依存ライブラリをビルドしているときに,リンクに失敗している様子
error: linking with `cc` failed: exit status: 1
仮説: poise_body側に問題があり,そこを修正することで動作する可能性
そもそも現在のpoise_bodyは非常に単純な,ほぼprintlnのみのコードしかない
仮説破棄