grapevine/src/main.rs
Charles Hall 5a490a4397
fix mod/use order
Yes, it does actually bother me, thanks for asking.
2024-10-03 15:28:24 -07:00

101 lines
2.7 KiB
Rust

// Avoid spurious warnings with --no-default-features, which isn't expected to
// work anyway
#![cfg_attr(not(any(feature = "sqlite", feature = "rocksdb")), allow(unused))]
use std::process::ExitCode;
use clap::Parser;
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))]
use tikv_jemallocator::Jemalloc;
use tracing::{error, info};
mod api;
mod cli;
mod config;
mod database;
mod error;
mod observability;
mod service;
mod utils;
pub(crate) use api::ruma_wrapper::{Ar, Ra};
pub(crate) use config::Config;
pub(crate) use service::{pdu::PduEvent, services, Services};
pub(crate) use utils::error::{Error, Result};
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))]
#[global_allocator]
static GLOBAL: Jemalloc = Jemalloc;
/// Returns the current version of the crate with extra info if supplied
///
/// Set the environment variable `GRAPEVINE_VERSION_EXTRA` to any UTF-8 string
/// to include it in parenthesis after the SemVer version. A common value are
/// git commit hashes.
fn version() -> String {
let cargo_pkg_version = env!("CARGO_PKG_VERSION");
match option_env!("GRAPEVINE_VERSION_EXTRA") {
Some(x) => format!("{cargo_pkg_version} ({x})"),
None => cargo_pkg_version.to_owned(),
}
}
#[derive(Debug, Clone, Copy)]
enum ApplicationState {
Ready,
Reloading,
Stopping,
}
fn set_application_state(state: ApplicationState) {
info!(?state, "Application state changed");
#[cfg(feature = "systemd")]
{
use sd_notify::NotifyState;
fn notify(states: &[NotifyState<'_>]) {
sd_notify::notify(false, states)
.expect("should be able to notify systemd");
}
match state {
ApplicationState::Ready => notify(&[NotifyState::Ready]),
ApplicationState::Reloading => {
let timespec = nix::time::clock_gettime(
nix::time::ClockId::CLOCK_MONOTONIC,
)
.expect("CLOCK_MONOTONIC should be usable");
let monotonic_usec =
timespec.tv_sec() * 1_000_000 + timespec.tv_nsec() / 1000;
notify(&[
NotifyState::Reloading,
NotifyState::Custom(&format!(
"MONOTONIC_USEC={monotonic_usec}",
)),
]);
}
ApplicationState::Stopping => notify(&[NotifyState::Stopping]),
};
}
}
#[tokio::main]
async fn main() -> ExitCode {
let args = cli::Args::parse();
let Err(e) = args.run().await else {
return ExitCode::SUCCESS;
};
eprintln!(
"Error: {}",
error::DisplayWithSources {
error: &e,
infix: "\n Caused by: "
}
);
ExitCode::FAILURE
}