refactor main task stack through service mgr
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
b8baa1223d
commit
5be679e17b
4 changed files with 93 additions and 41 deletions
|
@ -1,8 +1,10 @@
|
|||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use axum_server::Handle as ServerHandle;
|
||||
use tokio::sync::broadcast::{self, Sender};
|
||||
use tracing::{debug, error, info};
|
||||
use tokio::{
|
||||
sync::broadcast::{self, Sender},
|
||||
task::JoinHandle,
|
||||
};
|
||||
|
||||
extern crate conduit_admin as admin;
|
||||
extern crate conduit_core as conduit;
|
||||
|
@ -10,14 +12,14 @@ extern crate conduit_service as service;
|
|||
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use conduit::{debug_info, trace, Error, Result, Server};
|
||||
use conduit::{debug, debug_info, error, info, trace, Error, Result, Server};
|
||||
|
||||
use crate::{layers, serve};
|
||||
use crate::serve;
|
||||
|
||||
/// Main loop base
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn run(server: Arc<Server>) -> Result<(), Error> {
|
||||
let app = layers::build(&server)?;
|
||||
pub(crate) async fn run(server: Arc<Server>) -> Result<()> {
|
||||
debug!("Start");
|
||||
|
||||
// Install the admin room callback here for now
|
||||
admin::init().await;
|
||||
|
@ -29,8 +31,16 @@ pub(crate) async fn run(server: Arc<Server>) -> Result<(), Error> {
|
|||
.runtime()
|
||||
.spawn(signal(server.clone(), tx.clone(), handle.clone()));
|
||||
|
||||
// Serve clients
|
||||
let res = serve::serve(&server, app, handle, tx.subscribe()).await;
|
||||
let mut listener = server
|
||||
.runtime()
|
||||
.spawn(serve::serve(server.clone(), handle.clone(), tx.subscribe()));
|
||||
|
||||
// Focal point
|
||||
debug!("Running");
|
||||
let res = tokio::select! {
|
||||
res = &mut listener => res.map_err(Error::from).unwrap_or_else(Err),
|
||||
res = service::services().poll() => handle_services_poll(&server, res, listener).await,
|
||||
};
|
||||
|
||||
// Join the signal handler before we leave.
|
||||
sigs.abort();
|
||||
|
@ -39,16 +49,16 @@ pub(crate) async fn run(server: Arc<Server>) -> Result<(), Error> {
|
|||
// Remove the admin room callback
|
||||
admin::fini().await;
|
||||
|
||||
debug_info!("Finished");
|
||||
debug_info!("Finish");
|
||||
res
|
||||
}
|
||||
|
||||
/// Async initializations
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn start(server: Arc<Server>) -> Result<(), Error> {
|
||||
pub(crate) async fn start(server: Arc<Server>) -> Result<()> {
|
||||
debug!("Starting...");
|
||||
|
||||
service::init(&server).await?;
|
||||
service::start(&server).await?;
|
||||
|
||||
#[cfg(feature = "systemd")]
|
||||
sd_notify::notify(true, &[sd_notify::NotifyState::Ready]).expect("failed to notify systemd of ready state");
|
||||
|
@ -59,12 +69,12 @@ pub(crate) async fn start(server: Arc<Server>) -> Result<(), Error> {
|
|||
|
||||
/// Async destructions
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn stop(_server: Arc<Server>) -> Result<(), Error> {
|
||||
pub(crate) async fn stop(_server: Arc<Server>) -> Result<()> {
|
||||
debug!("Shutting down...");
|
||||
|
||||
// Wait for all completions before dropping or we'll lose them to the module
|
||||
// unload and explode.
|
||||
service::fini().await;
|
||||
service::stop().await;
|
||||
|
||||
debug!("Cleaning up...");
|
||||
|
||||
|
@ -108,3 +118,21 @@ async fn handle_shutdown(server: &Arc<Server>, tx: &Sender<()>, handle: &axum_se
|
|||
handle.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_services_poll(
|
||||
server: &Arc<Server>, result: Result<()>, listener: JoinHandle<Result<()>>,
|
||||
) -> Result<()> {
|
||||
debug!("Service manager finished: {result:?}");
|
||||
|
||||
if server.running() {
|
||||
if let Err(e) = server.shutdown() {
|
||||
error!("Failed to send shutdown signal: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = listener.await {
|
||||
error!("Client listener task finished with error: {e}");
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
|
|
@ -4,23 +4,23 @@ mod unix;
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::Router;
|
||||
use axum_server::Handle as ServerHandle;
|
||||
use conduit::{Error, Result, Server};
|
||||
use conduit::{Result, Server};
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
use crate::layers;
|
||||
|
||||
/// Serve clients
|
||||
pub(super) async fn serve(
|
||||
server: &Arc<Server>, app: Router, handle: ServerHandle, shutdown: broadcast::Receiver<()>,
|
||||
) -> Result<(), Error> {
|
||||
pub(super) async fn serve(server: Arc<Server>, handle: ServerHandle, shutdown: broadcast::Receiver<()>) -> Result<()> {
|
||||
let config = &server.config;
|
||||
let addrs = config.get_bind_addrs();
|
||||
let app = layers::build(&server)?;
|
||||
|
||||
if cfg!(unix) && config.unix_socket_path.is_some() {
|
||||
unix::serve(server, app, shutdown).await
|
||||
unix::serve(&server, app, shutdown).await
|
||||
} else if config.tls.is_some() {
|
||||
tls::serve(server, app, handle, addrs).await
|
||||
tls::serve(&server, app, handle, addrs).await
|
||||
} else {
|
||||
plain::serve(server, app, handle, addrs).await
|
||||
plain::serve(&server, app, handle, addrs).await
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue