pocket_tts_cli/server/
mod.rs1use anyhow::Result;
6use pocket_tts::TTSModel;
7
8use crate::commands::serve::{ServeArgs, print_endpoints};
9use crate::voice::resolve_voice;
10
11pub mod handlers;
12pub mod routes;
13pub mod state;
14
15pub async fn start_server(args: ServeArgs) -> Result<()> {
16 let _ = tracing_subscriber::fmt::try_init();
18
19 let model = if args.quantized {
21 #[cfg(feature = "quantized")]
22 {
23 TTSModel::load_quantized_with_params(
24 &args.variant,
25 args.temperature,
26 args.lsd_decode_steps,
27 args.eos_threshold,
28 )?
29 }
30 #[cfg(not(feature = "quantized"))]
31 {
32 anyhow::bail!("Quantization feature not enabled. Rebuild with --features quantized");
33 }
34 } else {
35 TTSModel::load_with_params(
36 &args.variant,
37 args.temperature,
38 args.lsd_decode_steps,
39 args.eos_threshold,
40 )?
41 };
42
43 println!(" ✓ Model loaded (sample rate: {}Hz)", model.sample_rate);
44
45 println!(" Loading default voice: {}...", args.voice);
47 let default_voice_state = resolve_voice(&model, Some(&args.voice))?;
48 println!(" ✓ Default voice ready");
49
50 let state = state::AppState::new(model, default_voice_state);
51 let app = routes::create_router(state);
52
53 let addr = format!("{}:{}", args.host, args.port);
54
55 print_endpoints(&args.host, args.port);
56
57 let listener = tokio::net::TcpListener::bind(&addr).await?;
58
59 axum::serve(listener, app)
60 .with_graceful_shutdown(shutdown_signal())
61 .await?;
62
63 println!(" 👋 Server stopped gracefully");
64
65 Ok(())
66}
67
68async fn shutdown_signal() {
70 let ctrl_c = async {
71 tokio::signal::ctrl_c()
72 .await
73 .expect("failed to install Ctrl+C handler");
74 };
75
76 #[cfg(unix)]
77 let terminate = async {
78 tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
79 .expect("failed to install signal handler")
80 .recv()
81 .await;
82 };
83
84 #[cfg(not(unix))]
85 let terminate = std::future::pending::<()>();
86
87 tokio::select! {
88 _ = ctrl_c => {
89 println!("\n ⚠️ Received Ctrl+C, shutting down...");
90 },
91 _ = terminate => {
92 println!("\n ⚠️ Received SIGTERM, shutting down...");
93 },
94 }
95}