veilid/veilid-core/src/core_context.rs

233 lines
7.8 KiB
Rust
Raw Normal View History

2022-02-06 21:18:42 -05:00
use crate::api_logger::*;
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 UpdateCallback = Arc<dyn Fn(VeilidUpdate) -> SystemPinBoxFuture<()>>;
} else {
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate) -> SystemPinBoxFuture<()> + Send + Sync>;
}
}
pub struct VeilidCoreContext {
pub config: VeilidConfig,
pub protected_store: ProtectedStore,
pub table_store: TableStore,
pub block_store: BlockStore,
pub crypto: Crypto,
pub attachment_manager: AttachmentManager,
2022-02-15 13:40:17 -05:00
pub update_callback: UpdateCallback,
2022-02-06 21:18:42 -05:00
}
impl VeilidCoreContext {
2022-02-09 09:47:36 -05:00
async fn new_with_config_callback(
update_callback: UpdateCallback,
config_callback: ConfigCallback,
) -> Result<VeilidCoreContext, VeilidAPIError> {
// Set up config from callback
trace!("VeilidCoreContext::new_with_config_callback init config");
let mut config = VeilidConfig::new();
if let Err(e) = config.init(config_callback).await {
return Err(VeilidAPIError::Internal { message: e });
}
Self::new_common(update_callback, config).await
}
async fn new_with_config_json(
update_callback: UpdateCallback,
config_json: String,
) -> Result<VeilidCoreContext, VeilidAPIError> {
// Set up config from callback
trace!("VeilidCoreContext::new_with_config_json init config");
let mut config = VeilidConfig::new();
if let Err(e) = config.init_from_json(config_json).await {
return Err(VeilidAPIError::Internal { message: e });
2022-02-06 21:18:42 -05:00
}
2022-02-09 09:47:36 -05:00
Self::new_common(update_callback, config).await
}
2022-02-06 21:18:42 -05:00
2022-02-09 09:47:36 -05:00
async fn new_common(
update_callback: UpdateCallback,
config: VeilidConfig,
) -> Result<VeilidCoreContext, VeilidAPIError> {
2022-02-06 21:18:42 -05:00
cfg_if! {
if #[cfg(target_os = "android")] {
if utils::android::ANDROID_GLOBALS.lock().is_none() {
error!("Android globals are not set up");
2022-02-09 09:47:36 -05:00
config.terminate().await;
2022-02-06 21:18:42 -05:00
return Err("Android globals are not set up".to_owned());
}
}
}
2022-02-09 09:47:36 -05:00
// Start up api logging
let api_log_level: VeilidConfigLogLevel = config.get().api_log_level;
if api_log_level != VeilidConfigLogLevel::Off {
ApiLogger::init(api_log_level.to_level_filter(), update_callback.clone());
for ig in crate::DEFAULT_LOG_IGNORE_LIST {
ApiLogger::add_filter_ignore_str(ig);
}
info!("Veilid API logging initialized");
2022-02-06 21:18:42 -05:00
}
// Set up protected store
trace!("VeilidCoreContext::new init protected store");
let protected_store = ProtectedStore::new(config.clone());
if let Err(e) = protected_store.init().await {
config.terminate().await;
ApiLogger::terminate();
2022-02-09 09:47:36 -05:00
return Err(VeilidAPIError::Internal { message: e });
2022-02-06 21:18:42 -05:00
}
// Init node id from config now that protected store is set up
if let Err(e) = config.init_node_id(protected_store.clone()).await {
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
2022-02-09 09:47:36 -05:00
return Err(VeilidAPIError::Internal { message: e });
2022-02-06 21:18:42 -05:00
}
// Set up tablestore
trace!("VeilidCoreContext::new init table store");
let table_store = TableStore::new(config.clone());
if let Err(e) = table_store.init().await {
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
2022-02-09 09:47:36 -05:00
return Err(VeilidAPIError::Internal { message: e });
2022-02-06 21:18:42 -05:00
}
// Set up crypto
trace!("VeilidCoreContext::new init crypto");
let crypto = Crypto::new(config.clone(), table_store.clone());
if let Err(e) = crypto.init().await {
table_store.terminate().await;
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
2022-02-09 09:47:36 -05:00
return Err(VeilidAPIError::Internal { message: e });
2022-02-06 21:18:42 -05:00
}
// Set up block store
trace!("VeilidCoreContext::new init block store");
let block_store = BlockStore::new(config.clone());
if let Err(e) = block_store.init().await {
crypto.terminate().await;
table_store.terminate().await;
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
2022-02-09 09:47:36 -05:00
return Err(VeilidAPIError::Internal { message: e });
2022-02-06 21:18:42 -05:00
}
// Set up attachment manager
trace!("VeilidCoreContext::new init attachment manager");
2022-02-15 13:40:17 -05:00
let update_callback_move = update_callback.clone();
2022-02-06 21:18:42 -05:00
let attachment_manager =
AttachmentManager::new(config.clone(), table_store.clone(), crypto.clone());
if let Err(e) = attachment_manager
.init(Arc::new(
move |_old_state: AttachmentState, new_state: AttachmentState| {
2022-02-15 13:40:17 -05:00
update_callback_move(VeilidUpdate::Attachment { state: new_state })
2022-02-06 21:18:42 -05:00
},
))
.await
{
block_store.terminate().await;
crypto.terminate().await;
table_store.terminate().await;
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
2022-02-09 09:47:36 -05:00
return Err(VeilidAPIError::Internal { message: e });
2022-02-06 21:18:42 -05:00
}
Ok(VeilidCoreContext {
config,
protected_store,
table_store,
block_store,
crypto,
attachment_manager,
2022-02-15 13:40:17 -05:00
update_callback,
2022-02-06 21:18:42 -05:00
})
}
async fn shutdown(self) {
trace!("VeilidCoreContext::terminate_core_context starting");
self.attachment_manager.terminate().await;
self.block_store.terminate().await;
self.crypto.terminate().await;
self.table_store.terminate().await;
self.protected_store.terminate().await;
self.config.terminate().await;
2022-02-15 13:40:17 -05:00
// send final shutdown update
(self.update_callback)(VeilidUpdate::Shutdown).await;
2022-02-06 21:18:42 -05:00
trace!("VeilidCoreContext::shutdown complete");
ApiLogger::terminate();
}
}
/////////////////////////////////////////////////////////////////////////////
static INITIALIZED: AsyncMutex<bool> = AsyncMutex::new(false);
2022-02-09 09:47:36 -05:00
pub async fn api_startup(
update_callback: UpdateCallback,
config_callback: ConfigCallback,
) -> Result<VeilidAPI, VeilidAPIError> {
// See if we have an API started up already
let mut initialized_lock = INITIALIZED.lock().await;
if *initialized_lock {
return Err(VeilidAPIError::AlreadyInitialized);
}
// Create core context
let context =
VeilidCoreContext::new_with_config_callback(update_callback, config_callback).await?;
// Return an API object around our context
let veilid_api = VeilidAPI::new(context);
*initialized_lock = true;
Ok(veilid_api)
}
pub async fn api_startup_json(
update_callback: UpdateCallback,
config_json: String,
) -> Result<VeilidAPI, VeilidAPIError> {
2022-02-06 21:18:42 -05:00
// See if we have an API started up already
let mut initialized_lock = INITIALIZED.lock().await;
if *initialized_lock {
return Err(VeilidAPIError::AlreadyInitialized);
}
// Create core context
2022-02-09 09:47:36 -05:00
let context = VeilidCoreContext::new_with_config_json(update_callback, config_json).await?;
2022-02-06 21:18:42 -05:00
// Return an API object around our context
let veilid_api = VeilidAPI::new(context);
*initialized_lock = true;
Ok(veilid_api)
}
pub async fn api_shutdown(context: VeilidCoreContext) {
let mut initialized_lock = INITIALIZED.lock().await;
context.shutdown().await;
*initialized_lock = false;
}