veilid/veilid-core/src/veilid_core.rs

213 lines
6.1 KiB
Rust
Raw Normal View History

2021-11-22 16:28:30 +00:00
use crate::attachment_manager::*;
use crate::dht::crypto::Crypto;
use crate::intf::*;
use crate::veilid_api::*;
use crate::veilid_config::*;
use crate::xx::*;
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
pub type StateChangeCallback = Arc<dyn Fn(VeilidStateChange) -> SystemPinBoxFuture<()>>;
} else {
pub type StateChangeCallback = Arc<dyn Fn(VeilidStateChange) -> SystemPinBoxFuture<()> + Send + Sync>;
}
}
#[derive(Debug)]
pub enum VeilidStateChange {
Attachment {
old_state: AttachmentState,
new_state: AttachmentState,
},
}
#[derive(Debug)]
pub enum VeilidState {
Attachment(AttachmentState),
}
pub struct VeilidCoreSetup {
pub state_change_callback: StateChangeCallback,
pub config_callback: ConfigCallback,
}
struct VeilidCoreInner {
config: Option<VeilidConfig>,
table_store: Option<TableStore>,
crypto: Option<Crypto>,
attachment_manager: Option<AttachmentManager>,
2021-12-08 03:09:45 +00:00
api: VeilidAPIWeak,
2021-11-22 16:28:30 +00:00
}
#[derive(Clone)]
pub struct VeilidCore {
inner: Arc<Mutex<VeilidCoreInner>>,
}
2021-11-27 17:44:21 +00:00
impl Default for VeilidCore {
fn default() -> Self {
Self::new()
}
}
2021-11-22 16:28:30 +00:00
impl VeilidCore {
fn new_inner() -> VeilidCoreInner {
VeilidCoreInner {
config: None,
table_store: None,
crypto: None,
attachment_manager: None,
2021-12-08 03:09:45 +00:00
api: VeilidAPIWeak::default(),
2021-11-22 16:28:30 +00:00
}
}
pub fn new() -> Self {
Self {
inner: Arc::new(Mutex::new(Self::new_inner())),
}
}
2021-12-08 03:09:45 +00:00
pub(crate) fn config(&self) -> VeilidConfig {
self.inner.lock().config.as_ref().unwrap().clone()
}
2021-11-22 16:28:30 +00:00
pub(crate) fn table_store(&self) -> TableStore {
self.inner.lock().table_store.as_ref().unwrap().clone()
}
pub(crate) fn crypto(&self) -> Crypto {
self.inner.lock().crypto.as_ref().unwrap().clone()
}
2021-12-08 03:09:45 +00:00
pub(crate) fn attachment_manager(&self) -> AttachmentManager {
self.inner
.lock()
.attachment_manager
.as_ref()
.unwrap()
.clone()
}
2021-11-22 16:28:30 +00:00
// internal startup
2021-12-08 03:09:45 +00:00
async fn internal_startup(
&self,
inner: &mut VeilidCoreInner,
setup: VeilidCoreSetup,
) -> Result<VeilidAPI, String> {
2021-11-22 16:28:30 +00:00
trace!("VeilidCore::internal_startup starting");
cfg_if! {
if #[cfg(target_os = "android")] {
if utils::android::ANDROID_GLOBALS.lock().is_none() {
error!("Android globals are not set up");
return Err("Android globals are not set up".to_owned());
}
}
}
// Set up config
trace!("VeilidCore::internal_startup init config");
let mut config = VeilidConfig::new();
config.init(setup.config_callback).await?;
2021-12-08 03:09:45 +00:00
inner.config = Some(config.clone());
2021-11-22 16:28:30 +00:00
// Set up tablestore
trace!("VeilidCore::internal_startup init tablestore");
let table_store = TableStore::new(config.clone());
table_store.init().await?;
2021-12-08 03:09:45 +00:00
inner.table_store = Some(table_store.clone());
2021-11-22 16:28:30 +00:00
// Set up crypto
trace!("VeilidCore::internal_startup init crypto");
let crypto = Crypto::new(config.clone(), table_store.clone());
crypto.init().await?;
2021-12-08 03:09:45 +00:00
inner.crypto = Some(crypto.clone());
2021-11-22 16:28:30 +00:00
// Set up attachment manager
trace!("VeilidCore::internal_startup init attachment manager");
let cb = setup.state_change_callback;
let attachment_manager =
AttachmentManager::new(config.clone(), table_store.clone(), crypto.clone());
attachment_manager
.init(Arc::new(
move |old_state: AttachmentState, new_state: AttachmentState| {
cb(VeilidStateChange::Attachment {
2021-11-27 17:44:21 +00:00
old_state,
new_state,
2021-11-22 16:28:30 +00:00
})
},
))
.await?;
2021-12-08 03:09:45 +00:00
inner.attachment_manager = Some(attachment_manager.clone());
2021-11-22 16:28:30 +00:00
// Set up the API
trace!("VeilidCore::internal_startup init API");
let this = self.clone();
2021-12-08 03:09:45 +00:00
let veilid_api = VeilidAPI::new(this);
inner.api = veilid_api.weak();
2021-11-22 16:28:30 +00:00
trace!("VeilidCore::internal_startup complete");
2021-12-08 03:09:45 +00:00
2021-11-22 16:28:30 +00:00
Ok(veilid_api)
}
// called once at the beginning to start the node
pub async fn startup(&self, setup: VeilidCoreSetup) -> Result<VeilidAPI, String> {
2021-12-08 03:09:45 +00:00
// See if we have an API started up already
let mut inner = self.inner.lock();
if inner.api.upgrade().is_some() {
// If so, return an error because we shouldn't try to do this more than once
return Err("Veilid API is started".to_owned());
}
2021-11-22 16:28:30 +00:00
// Ensure we never end up partially initialized
2021-12-08 03:09:45 +00:00
match self.internal_startup(&mut *inner, setup).await {
2021-11-22 16:28:30 +00:00
Ok(v) => Ok(v),
Err(e) => {
Self::internal_shutdown(&mut *inner).await;
2021-11-22 16:28:30 +00:00
Err(e)
}
}
}
async fn internal_shutdown(inner: &mut VeilidCoreInner) {
2021-11-22 16:28:30 +00:00
trace!("VeilidCore::internal_shutdown starting");
2021-12-08 03:09:45 +00:00
// Detach the API object
inner.api = VeilidAPIWeak::default();
2021-11-22 16:28:30 +00:00
// Shut down up attachment manager
if let Some(attachment_manager) = &inner.attachment_manager {
attachment_manager.terminate().await;
inner.attachment_manager = None;
}
// Shut down crypto
if let Some(crypto) = &inner.crypto {
crypto.terminate().await;
inner.crypto = None;
}
// Shut down tablestore
if let Some(table_store) = &inner.table_store {
table_store.terminate().await;
inner.table_store = None;
}
// Shut down config
if let Some(config) = &inner.config {
config.terminate().await;
inner.config = None;
}
trace!("VeilidCore::shutdown complete");
}
// stop the node gracefully because the veilid api was dropped
pub(crate) async fn shutdown(self) {
let mut inner = self.inner.lock();
2021-12-09 21:11:52 +00:00
Self::internal_shutdown(&mut *inner).await;
}
2021-11-22 16:28:30 +00:00
//
}