From 356f4354dce3f97a4c08305730ecec548b6868c3 Mon Sep 17 00:00:00 2001 From: xfy Date: Thu, 18 Jun 2026 16:01:45 +0800 Subject: [PATCH] feat(main): run database migrations on server startup before listening main() is sync, so the async migrate::run() is driven by a dedicated multi-thread tokio runtime that is built, blocked-on, and dropped before dioxus::server::serve() starts its own runtime. This keeps the two runtimes from overlapping. --- src/main.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main.rs b/src/main.rs index fc51f4c..1b9558f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -206,6 +206,25 @@ fn main() { std::process::exit(1); } + // 启动前执行数据库迁移。阻塞:完成前不监听端口。 + // 失败直接 panic(expect),避免启动一个 schema 不一致的半残服务。 + // 多实例滚动发布时由咨询锁串行化,详见 src/db/migrate.rs。 + // + // main() 是同步函数,这里用一个独立的多线程 runtime 驱动迁移的异步逻辑, + // 完成后再交给 dioxus::server::serve() 启动它自己的 runtime。 + // 两个 runtime 不重叠,避免与 Dioxus 内部 runtime 产生交互。 + let migrate_rt = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .expect("failed to build migration runtime"); + migrate_rt.block_on(async { + db::migrate::run() + .await + .expect("Database migration failed on startup"); + }); + // 迁移 runtime 用完即弃,显式 drop 以在 serve() 前释放其线程资源。 + drop(migrate_rt); + // 启动 Dioxus 服务端,返回构建好的 Axum Router dioxus::server::serve(|| async move { use dioxus::server::{axum, DioxusRouterExt, ServeConfig};