[skip ci] cleanup tracing in prep for subnode separation

This commit is contained in:
Christien Rioux 2025-01-19 21:42:44 -05:00
parent 22634c48ec
commit 6337d445ed
7 changed files with 250 additions and 241 deletions

View File

@ -42,33 +42,23 @@ impl StartupShutdownContext {
}
#[allow(clippy::too_many_arguments)]
pub fn new_full(
config: VeilidConfig,
update_callback: UpdateCallback,
event_bus: EventBus,
protected_store: ProtectedStore,
table_store: TableStore,
#[cfg(feature = "unstable-blockstore")] block_store: BlockStore,
crypto: Crypto,
attachment_manager: AttachmentManager,
storage_manager: StorageManager,
) -> Self {
pub fn new_full(context: VeilidCoreContext) -> Self {
Self {
config,
update_callback,
event_bus: Some(event_bus),
protected_store: Some(protected_store),
table_store: Some(table_store),
config: context.config,
update_callback: context.update_callback,
event_bus: Some(context.event_bus),
protected_store: Some(context.protected_store),
table_store: Some(context.table_store),
#[cfg(feature = "unstable-blockstore")]
block_store: Some(block_store),
crypto: Some(crypto),
attachment_manager: Some(attachment_manager),
storage_manager: Some(storage_manager),
block_store: Some(context.block_store),
crypto: Some(context.crypto),
attachment_manager: Some(context.attachment_manager),
storage_manager: Some(context.storage_manager),
}
}
#[instrument(level = "trace", target = "core_context", err, skip_all)]
pub async fn startup(&mut self) -> EyreResult<()> {
pub async fn startup(mut self) -> EyreResult<VeilidCoreContext> {
info!("Veilid API starting up");
info!("init api tracing");
@ -174,33 +164,44 @@ impl StartupShutdownContext {
self.attachment_manager = Some(attachment_manager);
info!("Veilid API startup complete");
Ok(())
Ok(VeilidCoreContext {
config: self.config,
update_callback: self.update_callback,
event_bus: self.event_bus.unwrap(),
storage_manager: self.storage_manager.unwrap(),
protected_store: self.protected_store.unwrap(),
table_store: self.table_store.unwrap(),
#[cfg(feature = "unstable-blockstore")]
block_store: self.block_store.unwrap(),
crypto: self.crypto.unwrap(),
attachment_manager: self.attachment_manager.unwrap(),
})
}
#[instrument(level = "trace", target = "core_context", skip_all)]
pub async fn shutdown(&mut self) {
pub async fn shutdown(mut self) {
info!("Veilid API shutting down");
if let Some(attachment_manager) = &mut self.attachment_manager {
if let Some(attachment_manager) = self.attachment_manager.take() {
attachment_manager.terminate().await;
}
if let Some(storage_manager) = &mut self.storage_manager {
if let Some(storage_manager) = self.storage_manager.take() {
storage_manager.terminate().await;
}
#[cfg(feature = "unstable-blockstore")]
if let Some(block_store) = &mut self.block_store {
if let Some(block_store) = self.block_store.take() {
block_store.terminate().await;
}
if let Some(crypto) = &mut self.crypto {
if let Some(crypto) = self.crypto.take() {
crypto.terminate().await;
}
if let Some(table_store) = &mut self.table_store {
if let Some(table_store) = self.table_store.take() {
table_store.terminate().await;
}
if let Some(protected_store) = &mut self.protected_store {
if let Some(protected_store) = self.protected_store.take() {
protected_store.terminate().await;
}
if let Some(event_bus) = &mut self.event_bus {
if let Some(event_bus) = self.event_bus.take() {
event_bus.shutdown().await;
}
@ -228,12 +229,12 @@ pub struct VeilidCoreContext {
// Event bus
pub event_bus: EventBus,
// Services
pub storage_manager: StorageManager,
pub crypto: Crypto,
pub protected_store: ProtectedStore,
pub table_store: TableStore,
#[cfg(feature = "unstable-blockstore")]
pub block_store: BlockStore,
pub crypto: Crypto,
pub storage_manager: StorageManager,
pub attachment_manager: AttachmentManager,
}
@ -274,37 +275,13 @@ impl VeilidCoreContext {
}
}
let mut sc = StartupShutdownContext::new_empty(config.clone(), update_callback);
sc.startup().await.map_err(VeilidAPIError::generic)?;
Ok(VeilidCoreContext {
config: sc.config,
update_callback: sc.update_callback,
event_bus: sc.event_bus.unwrap(),
storage_manager: sc.storage_manager.unwrap(),
protected_store: sc.protected_store.unwrap(),
table_store: sc.table_store.unwrap(),
#[cfg(feature = "unstable-blockstore")]
block_store: sc.block_store.unwrap(),
crypto: sc.crypto.unwrap(),
attachment_manager: sc.attachment_manager.unwrap(),
})
let sc = StartupShutdownContext::new_empty(config.clone(), update_callback);
sc.startup().await.map_err(VeilidAPIError::generic)
}
#[instrument(level = "trace", target = "core_context", skip_all)]
async fn shutdown(self) {
let mut sc = StartupShutdownContext::new_full(
self.config.clone(),
self.update_callback.clone(),
self.event_bus,
self.protected_store,
self.table_store,
#[cfg(feature = "unstable-blockstore")]
self.block_store,
self.crypto,
self.attachment_manager,
self.storage_manager,
);
let sc = StartupShutdownContext::new_full(self);
sc.shutdown().await;
}
}
@ -312,7 +289,8 @@ impl VeilidCoreContext {
/////////////////////////////////////////////////////////////////////////////
lazy_static::lazy_static! {
static ref INITIALIZED: AsyncMutex<HashSet<(String,String)>> = AsyncMutex::new(HashSet::new());
static ref INITIALIZED: Mutex<HashSet<(String,String)>> = Mutex::new(HashSet::new());
static ref STARTUP_TABLE: AsyncTagLockTable<(String, String)> = AsyncTagLockTable::new();
}
/// Initialize a Veilid node.
@ -345,9 +323,11 @@ pub async fn api_startup(
})?;
let init_key = (program_name, namespace);
// Only allow one startup/shutdown per program_name+namespace combination simultaneously
let _tag_guard = STARTUP_TABLE.lock_tag(init_key.clone()).await;
// See if we have an API started up already
let mut initialized_lock = INITIALIZED.lock().await;
if initialized_lock.contains(&init_key) {
if INITIALIZED.lock().contains(&init_key) {
apibail_already_initialized!();
}
@ -358,7 +338,8 @@ pub async fn api_startup(
// Return an API object around our context
let veilid_api = VeilidAPI::new(context);
initialized_lock.insert(init_key);
// Add to the initialized set
INITIALIZED.lock().insert(init_key);
Ok(veilid_api)
}
@ -406,9 +387,11 @@ pub async fn api_startup_config(
let init_key = (program_name, namespace);
// Only allow one startup/shutdown per program_name+namespace combination simultaneously
let _tag_guard = STARTUP_TABLE.lock_tag(init_key.clone()).await;
// See if we have an API started up already
let mut initialized_lock = INITIALIZED.lock().await;
if initialized_lock.contains(&init_key) {
if INITIALIZED.lock().contains(&init_key) {
apibail_already_initialized!();
}
@ -418,20 +401,30 @@ pub async fn api_startup_config(
// Return an API object around our context
let veilid_api = VeilidAPI::new(context);
initialized_lock.insert(init_key);
// Add to the initialized set
INITIALIZED.lock().insert(init_key);
Ok(veilid_api)
}
#[instrument(level = "trace", target = "core_context", skip_all)]
pub async fn api_shutdown(context: VeilidCoreContext) {
let mut initialized_lock = INITIALIZED.lock().await;
pub(crate) async fn api_shutdown(context: VeilidCoreContext) {
let init_key = {
let config = context.config.get();
(config.program_name.clone(), config.namespace.clone())
};
// Only allow one startup/shutdown per program_name+namespace combination simultaneously
let _tag_guard = STARTUP_TABLE.lock_tag(init_key.clone()).await;
// See if we have an API started up already
if !INITIALIZED.lock().contains(&init_key) {
return;
}
// Shutdown the context
context.shutdown().await;
initialized_lock.remove(&init_key);
// Remove from the initialized set
INITIALIZED.lock().remove(&init_key);
}

View File

@ -2,7 +2,6 @@ use crate::core_context::*;
use crate::veilid_api::*;
use crate::*;
use core::fmt::Write;
use once_cell::sync::OnceCell;
use tracing_subscriber::*;
struct ApiTracingLayerInner {
@ -21,11 +20,10 @@ struct ApiTracingLayerInner {
/// with many copies of Veilid running.
#[derive(Clone)]
pub struct ApiTracingLayer {
inner: Arc<Mutex<Option<ApiTracingLayerInner>>>,
}
pub struct ApiTracingLayer {}
static API_LOGGER: OnceCell<ApiTracingLayer> = OnceCell::new();
static API_LOGGER_INNER: Mutex<Option<ApiTracingLayerInner>> = Mutex::new(None);
static API_LOGGER_ENABLED: AtomicBool = AtomicBool::new(false);
impl ApiTracingLayer {
/// Initialize an ApiTracingLayer singleton
@ -33,11 +31,7 @@ impl ApiTracingLayer {
/// This must be inserted into your tracing subscriber before you
/// call api_startup() or api_startup_json() if you are going to use api tracing.
pub fn init() -> ApiTracingLayer {
API_LOGGER
.get_or_init(|| ApiTracingLayer {
inner: Arc::new(Mutex::new(None)),
})
.clone()
ApiTracingLayer {}
}
fn new_inner() -> ApiTracingLayerInner {
@ -52,12 +46,7 @@ impl ApiTracingLayer {
namespace: String,
update_callback: UpdateCallback,
) -> VeilidAPIResult<()> {
let Some(api_logger) = API_LOGGER.get() else {
// Did not init, so skip this
return Ok(());
};
let mut inner = api_logger.inner.lock();
let mut inner = API_LOGGER_INNER.lock();
if inner.is_none() {
*inner = Some(Self::new_inner());
}
@ -70,6 +59,9 @@ impl ApiTracingLayer {
.unwrap()
.update_callbacks
.insert(key, update_callback);
API_LOGGER_ENABLED.store(true, Ordering::Release);
return Ok(());
}
@ -79,28 +71,29 @@ impl ApiTracingLayer {
namespace: String,
) -> VeilidAPIResult<()> {
let key = (program_name, namespace);
if let Some(api_logger) = API_LOGGER.get() {
let mut inner = api_logger.inner.lock();
if inner.is_none() {
apibail_not_initialized!();
}
if inner
.as_mut()
.unwrap()
.update_callbacks
.remove(&key)
.is_none()
{
apibail_not_initialized!();
}
if inner.as_mut().unwrap().update_callbacks.is_empty() {
*inner = None;
}
let mut inner = API_LOGGER_INNER.lock();
if inner.is_none() {
apibail_not_initialized!();
}
if inner
.as_mut()
.unwrap()
.update_callbacks
.remove(&key)
.is_none()
{
apibail_not_initialized!();
}
if inner.as_mut().unwrap().update_callbacks.is_empty() {
*inner = None;
API_LOGGER_ENABLED.store(false, Ordering::Release);
}
Ok(())
}
fn emit_log(&self, inner: &mut ApiTracingLayerInner, meta: &Metadata<'_>, message: String) {
fn emit_log(&self, meta: &'static Metadata<'static>, message: String) {
let level = *meta.level();
let target = meta.target();
let log_level = VeilidLogLevel::from_tracing_level(level);
@ -148,8 +141,10 @@ impl ApiTracingLayer {
backtrace,
}));
for cb in inner.update_callbacks.values() {
(cb)(log_update.clone());
if let Some(inner) = &mut *API_LOGGER_INNER.lock() {
for cb in inner.update_callbacks.values() {
(cb)(log_update.clone());
}
}
}
}
@ -159,17 +154,23 @@ pub struct SpanDuration {
end: Timestamp,
}
fn simplify_file(file: &str) -> String {
let path = std::path::Path::new(file);
let path_component_count = path.iter().count();
if path.ends_with("mod.rs") && path_component_count >= 2 {
let outpath: std::path::PathBuf = path.iter().skip(path_component_count - 2).collect();
outpath.to_string_lossy().to_string()
} else if let Some(filename) = path.file_name() {
filename.to_string_lossy().to_string()
} else {
file.to_string()
}
fn simplify_file(file: &'static str) -> &'static str {
file.static_transform(|file| {
let out = {
let path = std::path::Path::new(file);
let path_component_count = path.iter().count();
if path.ends_with("mod.rs") && path_component_count >= 2 {
let outpath: std::path::PathBuf =
path.iter().skip(path_component_count - 2).collect();
outpath.to_string_lossy().to_string()
} else if let Some(filename) = path.file_name() {
filename.to_string_lossy().to_string()
} else {
file.to_string()
}
};
out.to_static_str()
})
}
impl<S: Subscriber + for<'a> registry::LookupSpan<'a>> Layer<S> for ApiTracingLayer {
@ -179,47 +180,51 @@ impl<S: Subscriber + for<'a> registry::LookupSpan<'a>> Layer<S> for ApiTracingLa
id: &tracing::Id,
ctx: layer::Context<'_, S>,
) {
if let Some(_inner) = &mut *self.inner.lock() {
let mut new_debug_record = StringRecorder::new();
attrs.record(&mut new_debug_record);
if !API_LOGGER_ENABLED.load(Ordering::Acquire) {
// Optimization if api logger has no callbacks
return;
}
if let Some(span_ref) = ctx.span(id) {
let mut new_debug_record = StringRecorder::new();
attrs.record(&mut new_debug_record);
if let Some(span_ref) = ctx.span(id) {
span_ref
.extensions_mut()
.insert::<StringRecorder>(new_debug_record);
if crate::DURATION_LOG_FACILITIES.contains(&attrs.metadata().target()) {
span_ref
.extensions_mut()
.insert::<StringRecorder>(new_debug_record);
if crate::DURATION_LOG_FACILITIES.contains(&attrs.metadata().target()) {
span_ref
.extensions_mut()
.insert::<SpanDuration>(SpanDuration {
start: Timestamp::now(),
end: Timestamp::default(),
});
}
.insert::<SpanDuration>(SpanDuration {
start: Timestamp::now(),
end: Timestamp::default(),
});
}
}
}
fn on_close(&self, id: span::Id, ctx: layer::Context<'_, S>) {
if let Some(inner) = &mut *self.inner.lock() {
if let Some(span_ref) = ctx.span(&id) {
if let Some(span_duration) = span_ref.extensions_mut().get_mut::<SpanDuration>() {
span_duration.end = Timestamp::now();
let duration = span_duration.end.saturating_sub(span_duration.start);
let meta = span_ref.metadata();
self.emit_log(
inner,
meta,
format!(
" {}{}: duration={}",
span_ref
.parent()
.map(|p| format!("{}::", p.name()))
.unwrap_or_default(),
span_ref.name(),
format_opt_ts(Some(duration))
),
);
}
if !API_LOGGER_ENABLED.load(Ordering::Acquire) {
// Optimization if api logger has no callbacks
return;
}
if let Some(span_ref) = ctx.span(&id) {
if let Some(span_duration) = span_ref.extensions_mut().get_mut::<SpanDuration>() {
span_duration.end = Timestamp::now();
let duration = span_duration.end.saturating_sub(span_duration.start);
let meta = span_ref.metadata();
self.emit_log(
meta,
format!(
" {}{}: duration={}",
span_ref
.parent()
.map(|p| format!("{}::", p.name()))
.unwrap_or_default(),
span_ref.name(),
format_opt_ts(Some(duration))
),
);
}
}
}
@ -230,22 +235,26 @@ impl<S: Subscriber + for<'a> registry::LookupSpan<'a>> Layer<S> for ApiTracingLa
values: &tracing::span::Record<'_>,
ctx: layer::Context<'_, S>,
) {
if let Some(_inner) = &mut *self.inner.lock() {
if let Some(span_ref) = ctx.span(id) {
if let Some(debug_record) = span_ref.extensions_mut().get_mut::<StringRecorder>() {
values.record(debug_record);
}
if !API_LOGGER_ENABLED.load(Ordering::Acquire) {
// Optimization if api logger has no callbacks
return;
}
if let Some(span_ref) = ctx.span(id) {
if let Some(debug_record) = span_ref.extensions_mut().get_mut::<StringRecorder>() {
values.record(debug_record);
}
}
}
fn on_event(&self, event: &tracing::Event<'_>, _ctx: layer::Context<'_, S>) {
if let Some(inner) = &mut *self.inner.lock() {
let mut recorder = StringRecorder::new();
event.record(&mut recorder);
let meta = event.metadata();
self.emit_log(inner, meta, recorder.to_string());
if !API_LOGGER_ENABLED.load(Ordering::Acquire) {
// Optimization if api logger has no callbacks
return;
}
let mut recorder = StringRecorder::new();
event.record(&mut recorder);
let meta = event.metadata();
self.emit_log(meta, recorder.to_string());
}
}

View File

@ -36,7 +36,7 @@ impl Drop for VeilidAPIInner {
/// * Reply to `AppCall` RPCs.
#[derive(Clone, Debug)]
pub struct VeilidAPI {
pub(super) inner: Arc<Mutex<VeilidAPIInner>>,
inner: Arc<Mutex<VeilidAPIInner>>,
}
impl VeilidAPI {
@ -100,7 +100,7 @@ impl VeilidAPI {
if let Some(context) = &inner.context {
return Ok(context.table_store.clone());
}
Err(VeilidAPIError::not_initialized())
Err(VeilidAPIError::NotInitialized)
}
/// Get the ProtectedStore manager.
@ -109,7 +109,7 @@ impl VeilidAPI {
if let Some(context) = &inner.context {
return Ok(context.protected_store.clone());
}
Err(VeilidAPIError::not_initialized())
Err(VeilidAPIError::NotInitialized)
}
////////////////////////////////////////////////////////////////
@ -119,14 +119,14 @@ impl VeilidAPI {
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.clone());
}
Err(VeilidAPIError::not_initialized())
Err(VeilidAPIError::NotInitialized)
}
pub(crate) fn network_manager(&self) -> VeilidAPIResult<NetworkManager> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.network_manager());
}
Err(VeilidAPIError::not_initialized())
Err(VeilidAPIError::NotInitialized)
}
pub(crate) fn rpc_processor(&self) -> VeilidAPIResult<RPCProcessor> {
let inner = self.inner.lock();
@ -155,7 +155,12 @@ impl VeilidAPI {
if let Some(context) = &inner.context {
return Ok(context.block_store.clone());
}
Err(VeilidAPIError::not_initialized())
Err(VeilidAPIError::NotInitialized)
}
pub(crate) fn with_debug_cache<R, F: FnOnce(&mut DebugCache) -> R>(&self, callback: F) -> R {
let mut inner = self.inner.lock();
callback(&mut inner.debug_cache)
}
////////////////////////////////////////////////////////////////

View File

@ -852,7 +852,9 @@ impl VeilidAPI {
Ok("Connections purged".to_owned())
} else if args[0] == "routes" {
// Purge route spec store
self.inner.lock().debug_cache.imported_routes.clear();
self.with_debug_cache(|dc| {
dc.imported_routes.clear();
});
let rss = self.network_manager()?.routing_table().route_spec_store();
match rss.purge().await {
Ok(_) => Ok("Routes purged".to_owned()),
@ -1183,14 +1185,14 @@ impl VeilidAPI {
let out = match rss.release_route(route_id) {
true => {
// release imported
let mut inner = self.inner.lock();
let dc = &mut inner.debug_cache;
for (n, ir) in dc.imported_routes.iter().enumerate() {
if *ir == route_id {
dc.imported_routes.remove(n);
break;
self.with_debug_cache(|dc| {
for (n, ir) in dc.imported_routes.iter().enumerate() {
if *ir == route_id {
dc.imported_routes.remove(n);
break;
}
}
}
});
"Released".to_owned()
}
false => "Route does not exist".to_owned(),
@ -1326,11 +1328,12 @@ impl VeilidAPI {
.import_remote_private_route_blob(blob_dec)
.map_err(VeilidAPIError::generic)?;
let mut inner = self.inner.lock();
let dc = &mut inner.debug_cache;
let n = dc.imported_routes.len();
let out = format!("Private route #{} imported: {}", n, route_id);
dc.imported_routes.push(route_id);
let out = self.with_debug_cache(|dc| {
let n = dc.imported_routes.len();
let out = format!("Private route #{} imported: {}", n, route_id);
dc.imported_routes.push(route_id);
out
});
Ok(out)
}
@ -1484,9 +1487,9 @@ impl VeilidAPI {
};
// Save routing context for record
let mut inner = self.inner.lock();
let dc = &mut inner.debug_cache;
dc.opened_record_contexts.insert(*record.key(), rc);
self.with_debug_cache(|dc| {
dc.opened_record_contexts.insert(*record.key(), rc);
});
Ok(format!(
"Created: {} {}:{}\n{:?}",
@ -1529,9 +1532,9 @@ impl VeilidAPI {
};
// Save routing context for record
let mut inner = self.inner.lock();
let dc = &mut inner.debug_cache;
dc.opened_record_contexts.insert(*record.key(), rc);
self.with_debug_cache(|dc| {
dc.opened_record_contexts.insert(*record.key(), rc);
});
Ok(format!("Opened: {} : {:?}", key, record))
}
@ -2213,13 +2216,14 @@ TableDB Operations:
// Private route
let text = &text[1..];
let private_route =
if let Some(prid) = get_route_id(rss.clone(), false, true)(text) {
rss.best_remote_private_route(&prid)?
} else {
let mut inner = self.inner.lock();
let dc = &mut inner.debug_cache;
let n = get_number(text)?;
let private_route = if let Some(prid) =
get_route_id(rss.clone(), false, true)(text)
{
rss.best_remote_private_route(&prid)?
} else {
let n = get_number(text)?;
self.with_debug_cache(|dc| {
let prid = *dc.imported_routes.get(n)?;
let Some(private_route) = rss.best_remote_private_route(&prid) else {
// Remove imported route
@ -2227,8 +2231,9 @@ TableDB Operations:
info!("removed dead imported route {}", n);
return None;
};
private_route
};
Some(private_route)
})?
};
Some(Destination::private_route(
private_route,
@ -2273,14 +2278,11 @@ TableDB Operations:
key: &str,
arg: usize,
) -> VeilidAPIResult<(TypedKey, RoutingContext)> {
let mut inner = self.inner.lock();
let dc = &mut inner.debug_cache;
let key = match get_debug_argument_at(args, arg, context, key, get_dht_key_no_safety)
.ok()
.or_else(|| {
// If unspecified, use the most recent key opened or created
dc.opened_record_contexts.back().map(|kv| kv.0).copied()
self.with_debug_cache(|dc| dc.opened_record_contexts.back().map(|kv| kv.0).copied())
}) {
Some(k) => k,
None => {
@ -2289,7 +2291,9 @@ TableDB Operations:
};
// Get routing context for record
let Some(rc) = dc.opened_record_contexts.get(&key).cloned() else {
let Some(rc) = self.with_debug_cache(|dc| dc.opened_record_contexts.get(&key).cloned())
else {
apibail_missing_argument!("key is not opened", "key");
};

View File

@ -98,7 +98,10 @@ pub struct VeilidStateAttachment {
pub struct PeerTableData {
/// The node ids used by this peer
#[schemars(with = "Vec<String>")]
#[cfg_attr(all(target_arch = "wasm32", target_os = "unknown"), tsify(type = "string[]"))]
#[cfg_attr(
all(target_arch = "wasm32", target_os = "unknown"),
tsify(type = "string[]")
)]
pub node_ids: Vec<TypedKey>,
/// The peer's human readable address.
pub peer_address: String,
@ -167,7 +170,11 @@ pub struct VeilidValueChange {
/// An update from the veilid-core to the host application describing a change
/// to the internal state of the Veilid node.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[cfg_attr(all(target_arch = "wasm32", target_os = "unknown"), derive(Tsify), tsify(into_wasm_abi))]
#[cfg_attr(
all(target_arch = "wasm32", target_os = "unknown"),
derive(Tsify),
tsify(into_wasm_abi)
)]
#[serde(tag = "kind")]
pub enum VeilidUpdate {
Log(Box<VeilidLog>),
@ -184,7 +191,11 @@ from_impl_to_jsvalue!(VeilidUpdate);
/// A queriable state of the internals of veilid-core.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[cfg_attr(all(target_arch = "wasm32", target_os = "unknown"), derive(Tsify), tsify(into_wasm_abi))]
#[cfg_attr(
all(target_arch = "wasm32", target_os = "unknown"),
derive(Tsify),
tsify(into_wasm_abi)
)]
pub struct VeilidState {
pub attachment: Box<VeilidStateAttachment>,
pub network: Box<VeilidStateNetwork>,

View File

@ -53,21 +53,6 @@ impl<T> IoNetworkResultExt<T> for io::Result<T> {
fn into_network_result(self) -> io::Result<NetworkResult<T>> {
match self {
Ok(v) => Ok(NetworkResult::Value(v)),
// #[cfg(feature = "io_error_more")]
// Err(e) => match e.kind() {
// io::ErrorKind::TimedOut => Ok(NetworkResult::Timeout),
// io::ErrorKind::UnexpectedEof
// | io::ErrorKind::NotConnected
// | io::ErrorKind::BrokenPipe
// | io::ErrorKind::ConnectionAborted
// | io::ErrorKind::ConnectionRefused
// | io::ErrorKind::ConnectionReset
// | io::ErrorKind::HostUnreachable
// | io::ErrorKind::NetworkUnreachable => Ok(NetworkResult::NoConnection(e)),
// io::ErrorKind::AddrNotAvailable => Ok(NetworkResult::AlreadyExists(e)),
// _ => Err(e),
// },
// #[cfg(not(feature = "io_error_more"))]
Err(e) => io_error_kind_from_error(e),
}
}
@ -100,18 +85,6 @@ impl<T> FoldedNetworkResultExt<T> for io::Result<TimeoutOr<T>> {
match self {
Ok(TimeoutOr::Timeout) => Ok(NetworkResult::Timeout),
Ok(TimeoutOr::Value(v)) => Ok(NetworkResult::Value(v)),
// #[cfg(feature = "io_error_more")]
// Err(e) => match e.kind() {
// io::ErrorKind::TimedOut => Ok(NetworkResult::Timeout),
// io::ErrorKind::ConnectionAborted
// | io::ErrorKind::ConnectionRefused
// | io::ErrorKind::ConnectionReset
// | io::ErrorKind::HostUnreachable
// | io::ErrorKind::NetworkUnreachable => Ok(NetworkResult::NoConnection(e)),
// io::ErrorKind::AddrNotAvailable => Ok(NetworkResult::AlreadyExists(e)),
// _ => Err(e),
// },
// #[cfg(not(feature = "io_error_more"))]
Err(e) => io_error_kind_from_error(e),
}
}
@ -121,18 +94,6 @@ impl<T> FoldedNetworkResultExt<T> for io::Result<NetworkResult<T>> {
fn folded(self) -> io::Result<NetworkResult<T>> {
match self {
Ok(v) => Ok(v),
// #[cfg(feature = "io_error_more")]
// Err(e) => match e.kind() {
// io::ErrorKind::TimedOut => Ok(NetworkResult::Timeout),
// io::ErrorKind::ConnectionAborted
// | io::ErrorKind::ConnectionRefused
// | io::ErrorKind::ConnectionReset
// | io::ErrorKind::HostUnreachable
// | io::ErrorKind::NetworkUnreachable => Ok(NetworkResult::NoConnection(e)),
// io::ErrorKind::AddrNotAvailable => Ok(NetworkResult::AlreadyExists(e)),
// _ => Err(e),
// },
// #[cfg(not(feature = "io_error_more"))]
Err(e) => io_error_kind_from_error(e),
}
}

View File

@ -3,6 +3,9 @@ use super::*;
static STRING_TABLE: std::sync::LazyLock<Mutex<BTreeSet<&'static str>>> =
std::sync::LazyLock::new(|| Mutex::new(BTreeSet::new()));
static STRING_TRANSFORM_TABLE: std::sync::LazyLock<Mutex<HashMap<usize, &'static str>>> =
std::sync::LazyLock::new(|| Mutex::new(HashMap::new()));
pub trait ToStaticStr {
fn to_static_str(&self) -> &'static str;
}
@ -19,3 +22,26 @@ impl<T: AsRef<str>> ToStaticStr for T {
ss
}
}
pub trait StaticStrTransform {
fn static_transform<F: FnOnce(&'static str) -> &'static str>(
self,
transform: F,
) -> &'static str;
}
impl StaticStrTransform for &'static str {
fn static_transform<F: FnOnce(&'static str) -> &'static str>(
self,
transform: F,
) -> &'static str {
let key = self.as_ptr() as usize;
let mut transform_table = STRING_TRANSFORM_TABLE.lock();
if let Some(v) = transform_table.get(&key) {
return v;
}
let out = transform(self);
transform_table.insert(key, out);
out
}
}