futu_opend/startup/mod.rs
1//! v1.4.110 P1-2 + Layer 3 A: daemon startup orchestrator.
2//!
3//! 旧 `async fn main()` 体 ~1267 LoC, 拆出来后 main.rs < 100 LoC.
4//! 本 orchestrator 把完整 startup 顺序 (args → config → auth → bridge →
5//! handlers → push dispatcher → REST/MCP/WS surface server) 切成 4 个 phase 子文件:
6//!
7//! - `phase1.rs` — tz / keys-pre-validate / logging / panic hook / metrics /
8//! listen_addr 计算 / 端口冲突探测
9//! - `phase2.rs` — bridge 构造 / 7-tier 密码解析 / `--reset-device` /
10//! `--verify-code` / bridge.initialize / `--setup-only` 早退 /
11//! dev-flag injection
12//! - `phase3.rs` — ApiServer 构造 / handler 注册 / WebSocket+gRPC broadcaster /
13//! push dispatcher 启动
14//! - `phase4.rs` — WS / REST / gRPC / Telnet server spawn / card_num expand /
15//! SIGHUP unified handler / TCP fail-closed gate / 主 `tokio::select!` 循环
16//!
17//! orchestrator (`run_daemon`) 只做 4 个 phase 串行调用, 不含业务逻辑.
18
19mod phase1;
20mod phase2;
21mod phase3;
22mod phase4;
23
24use anyhow::Result;
25
26use crate::config::RuntimeConfig;
27
28/// 完整 daemon startup orchestrator. 调用方在 main() 里:
29/// ```ignore
30/// let config = merge_config(args)?;
31/// startup::run_daemon(config, inject_auth_failure_every).await?
32/// ```
33pub async fn run_daemon(
34 config: RuntimeConfig,
35 inject_auth_failure_every: Option<u64>,
36) -> Result<()> {
37 let phase1 = phase1::run_phase1(&config).await?;
38 let phase2 =
39 phase2::run_phase2(&config, &phase1.listen_addr, inject_auth_failure_every).await?;
40 if phase2.setup_only_done {
41 // `--setup-only`: bridge.initialize Ok 已打印早退日志, 直接返回不启 server.
42 return Ok(());
43 }
44 let phase3 = phase3::run_phase3(
45 &config,
46 &phase2.bridge,
47 &phase1.listen_addr,
48 phase2.push_receiver,
49 );
50 phase4::run_phase4(&config, phase1, phase2.bridge, phase3).await
51}