Files
continuwuity/src/main/mod.rs
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

137 lines
2.9 KiB
Rust
Raw Normal View History

2025-05-24 00:28:09 +01:00
#![type_length_limit = "49152"] //TODO: reduce me
2025-07-06 21:59:20 +01:00
use std::sync::{Arc, atomic::Ordering};
2025-05-24 00:28:09 +01:00
use conduwuit_core::{debug_info, error};
2025-07-06 21:59:20 +01:00
conduwuit_macros::introspect_crate! {}
2025-07-06 21:59:20 +01:00
mod clap;
2026-02-06 01:17:45 +00:00
mod deadlock;
2025-05-24 00:28:09 +01:00
mod logging;
mod mods;
mod panic;
2025-05-24 00:28:09 +01:00
mod restart;
mod runtime;
mod sentry;
mod server;
mod signal;
2025-07-06 21:59:20 +01:00
pub use conduwuit_core::{Error, Result};
2026-01-20 10:00:26 -05:00
use server::Server;
2025-07-06 21:59:20 +01:00
pub use crate::clap::Args;
pub fn run() -> Result<()> {
panic::init();
2025-07-06 21:59:20 +01:00
let args = clap::parse();
run_with_args(&args)
}
pub fn run_with_args(args: &Args) -> Result<()> {
2026-02-06 01:17:45 +00:00
// Spawn deadlock detection thread
deadlock::spawn();
2025-07-06 21:59:20 +01:00
let runtime = runtime::new(args)?;
let server = Server::new(args, Some(runtime.handle()))?;
runtime.spawn(signal::signal(server.clone()));
runtime.block_on(async_main(&server))?;
runtime::shutdown(&server, runtime);
#[cfg(unix)]
if server.server.restarting.load(Ordering::Acquire) {
restart::restart();
}
debug_info!("Exit");
Ok(())
}
/// Operate the server normally in release-mode static builds. This will start,
/// run and stop the server within the asynchronous runtime.
#[cfg(any(not(conduwuit_mods), not(feature = "conduwuit_mods")))]
#[tracing::instrument(
name = "main",
parent = None,
2026-01-04 03:04:37 +00:00
skip_all,
level = "info"
2025-07-06 21:59:20 +01:00
)]
async fn async_main(server: &Arc<Server>) -> Result<(), Error> {
extern crate conduwuit_router as router;
match router::start(&server.server).await {
| Ok(services) => server.services.lock().await.insert(services),
| Err(error) => {
error!("Critical error starting server: {error}");
return Err(error);
},
};
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);
}
if let Err(error) = router::stop(
server
.services
.lock()
.await
.take()
.expect("services initialized"),
)
.await
{
error!("Critical error stopping server: {error}");
return Err(error);
}
debug_info!("Exit runtime");
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(conduwuit_mods, feature = "conduwuit_mods"))]
async fn async_main(server: &Arc<Server>) -> Result<(), Error> {
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(())
}