2025-09-27 12:05:38 +00:00
|
|
|
#![type_length_limit = "4096"] //TODO: reduce me
|
|
|
|
|
|
|
|
|
|
pub mod logging;
|
|
|
|
|
pub mod mods;
|
|
|
|
|
pub mod restart;
|
|
|
|
|
pub mod sentry;
|
|
|
|
|
pub mod server;
|
|
|
|
|
pub mod signals;
|
|
|
|
|
|
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
2025-10-01 02:41:24 +00:00
|
|
|
pub use tuwunel_core::runtime::shutdown;
|
|
|
|
|
use tuwunel_core::{Result, Runtime, debug_info, error, mod_ctor, mod_dtor, rustc_flags_capture};
|
|
|
|
|
use tuwunel_service::Services;
|
2025-09-27 12:05:38 +00:00
|
|
|
|
|
|
|
|
pub use self::server::Server;
|
|
|
|
|
|
|
|
|
|
mod_ctor! {}
|
|
|
|
|
mod_dtor! {}
|
|
|
|
|
rustc_flags_capture! {}
|
|
|
|
|
|
|
|
|
|
pub fn exec(server: &Arc<Server>, runtime: Runtime) -> Result {
|
|
|
|
|
run(server, &runtime)?;
|
|
|
|
|
shutdown(&server.server, runtime)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn run(server: &Arc<Server>, runtime: &Runtime) -> Result {
|
2025-10-01 02:41:24 +00:00
|
|
|
runtime.block_on(async_exec(server))
|
2025-09-27 12:05:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Operate the server normally in release-mode static builds. This will start,
|
|
|
|
|
/// run and stop the server within the asynchronous runtime.
|
|
|
|
|
#[tracing::instrument(
|
|
|
|
|
name = "main",
|
|
|
|
|
parent = None,
|
|
|
|
|
skip_all
|
|
|
|
|
)]
|
2025-10-01 02:41:24 +00:00
|
|
|
pub async fn async_exec(server: &Arc<Server>) -> Result {
|
|
|
|
|
let signals = server
|
|
|
|
|
.server
|
|
|
|
|
.runtime()
|
|
|
|
|
.spawn(signals::enable(server.clone()));
|
|
|
|
|
|
|
|
|
|
async_start(server).await?;
|
|
|
|
|
async_run(server).await?;
|
|
|
|
|
async_stop(server).await?;
|
|
|
|
|
signals.await?;
|
|
|
|
|
|
|
|
|
|
debug_info!("Exit runtime");
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(any(not(tuwunel_mods), not(feature = "tuwunel_mods")))]
|
|
|
|
|
pub async fn async_start(server: &Arc<Server>) -> Result<Arc<Services>> {
|
2025-09-27 12:05:38 +00:00
|
|
|
extern crate tuwunel_router as router;
|
|
|
|
|
|
2025-10-01 02:41:24 +00:00
|
|
|
Ok(match router::start(&server.server).await {
|
|
|
|
|
| Ok(services) => server
|
|
|
|
|
.services
|
|
|
|
|
.lock()
|
|
|
|
|
.await
|
|
|
|
|
.insert(services)
|
|
|
|
|
.clone(),
|
|
|
|
|
|
2025-09-27 12:05:38 +00:00
|
|
|
| Err(error) => {
|
|
|
|
|
error!("Critical error starting server: {error}");
|
|
|
|
|
return Err(error);
|
|
|
|
|
},
|
2025-10-01 02:41:24 +00:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Operate the server normally in release-mode static builds. This will start,
|
|
|
|
|
/// run and stop the server within the asynchronous runtime.
|
|
|
|
|
#[cfg(any(not(tuwunel_mods), not(feature = "tuwunel_mods")))]
|
|
|
|
|
pub async fn async_run(server: &Arc<Server>) -> Result {
|
|
|
|
|
extern crate tuwunel_router as router;
|
2025-09-27 12:05:38 +00:00
|
|
|
|
|
|
|
|
if let Err(error) = router::run(
|
|
|
|
|
server
|
|
|
|
|
.services
|
|
|
|
|
.lock()
|
|
|
|
|
.await
|
|
|
|
|
.as_ref()
|
|
|
|
|
.expect("services initialized"),
|
|
|
|
|
)
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
error!("Critical error running server: {error}");
|
|
|
|
|
return Err(error);
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-01 02:41:24 +00:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(any(not(tuwunel_mods), not(feature = "tuwunel_mods")))]
|
|
|
|
|
pub async fn async_stop(server: &Arc<Server>) -> Result {
|
|
|
|
|
extern crate tuwunel_router as router;
|
|
|
|
|
|
2025-09-27 12:05:38 +00:00
|
|
|
if let Err(error) = router::stop(
|
|
|
|
|
server
|
|
|
|
|
.services
|
|
|
|
|
.lock()
|
|
|
|
|
.await
|
|
|
|
|
.take()
|
|
|
|
|
.expect("services initialized"),
|
|
|
|
|
)
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
error!("Critical error stopping server: {error}");
|
|
|
|
|
return Err(error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Operate the server in developer-mode dynamic builds. This will start, run,
|
|
|
|
|
/// and hot-reload portions of the server as-needed before returning for an
|
|
|
|
|
/// actual shutdown. This is not available in release-mode or static builds.
|
|
|
|
|
#[cfg(all(tuwunel_mods, feature = "tuwunel_mods"))]
|
2025-10-01 02:41:24 +00:00
|
|
|
pub async fn async_exec(server: &Arc<Server>) -> Result {
|
2025-09-27 12:05:38 +00:00
|
|
|
let mut starts = true;
|
|
|
|
|
let mut reloads = true;
|
|
|
|
|
while reloads {
|
|
|
|
|
if let Err(error) = mods::open(server).await {
|
|
|
|
|
error!("Loading router: {error}");
|
|
|
|
|
return Err(error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let result = mods::run(server, starts).await;
|
|
|
|
|
if let Ok(result) = result {
|
|
|
|
|
(starts, reloads) = result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let force = !reloads || result.is_err();
|
|
|
|
|
if let Err(error) = mods::close(server, force).await {
|
|
|
|
|
error!("Unloading router: {error}");
|
|
|
|
|
return Err(error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Err(error) = result {
|
|
|
|
|
error!("{error}");
|
|
|
|
|
return Err(error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
debug_info!("Exit runtime");
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|