debugging

This commit is contained in:
John Smith 2023-05-21 22:16:27 +01:00
parent f31044e8a3
commit f54a6fcf31
19 changed files with 139 additions and 88 deletions

View File

@ -1,5 +1,6 @@
#!/bin/bash #!/bin/bash
ID=$(xcrun simctl create test-iphone com.apple.CoreSimulator.SimDeviceType.iPhone-14-Pro com.apple.CoreSimulator.SimRuntime.iOS-16-1 2>/dev/null) RUNTIME=$(xcrun simctl runtime list -j | jq '.[].runtimeIdentifier' -r | head -1)
ID=$(xcrun simctl create test-iphone com.apple.CoreSimulator.SimDeviceType.iPhone-14-Pro $RUNTIME 2>/dev/null)
xcrun simctl boot $ID xcrun simctl boot $ID
xcrun simctl bootstatus $ID xcrun simctl bootstatus $ID
echo Simulator ID is $ID echo Simulator ID is $ID

View File

@ -122,5 +122,5 @@ if [ "$BREW_USER" == "" ]; then
BREW_USER=`whoami` BREW_USER=`whoami`
fi fi
fi fi
sudo -H -u $BREW_USER brew install capnp cmake wabt llvm protobuf openjdk@11 sudo -H -u $BREW_USER brew install capnp cmake wabt llvm protobuf openjdk@11 jq
sudo gem install cocoapods sudo gem install cocoapods

View File

@ -70,6 +70,7 @@ impl ServicesContext {
trace!("init protected store"); trace!("init protected store");
let protected_store = ProtectedStore::new(self.config.clone()); let protected_store = ProtectedStore::new(self.config.clone());
if let Err(e) = protected_store.init().await { if let Err(e) = protected_store.init().await {
error!("failed to init protected store: {}", e);
self.shutdown().await; self.shutdown().await;
return Err(e); return Err(e);
} }
@ -79,6 +80,7 @@ impl ServicesContext {
trace!("init table store"); trace!("init table store");
let table_store = TableStore::new(self.config.clone()); let table_store = TableStore::new(self.config.clone());
if let Err(e) = table_store.init().await { if let Err(e) = table_store.init().await {
error!("failed to init table store: {}", e);
self.shutdown().await; self.shutdown().await;
return Err(e); return Err(e);
} }
@ -92,6 +94,7 @@ impl ServicesContext {
protected_store.clone(), protected_store.clone(),
); );
if let Err(e) = crypto.init().await { if let Err(e) = crypto.init().await {
error!("failed to init crypto: {}", e);
self.shutdown().await; self.shutdown().await;
return Err(e); return Err(e);
} }
@ -101,6 +104,7 @@ impl ServicesContext {
trace!("init block store"); trace!("init block store");
let block_store = BlockStore::new(self.config.clone()); let block_store = BlockStore::new(self.config.clone());
if let Err(e) = block_store.init().await { if let Err(e) = block_store.init().await {
error!("failed to init block store: {}", e);
self.shutdown().await; self.shutdown().await;
return Err(e); return Err(e);
} }
@ -116,6 +120,7 @@ impl ServicesContext {
self.block_store.clone().unwrap(), self.block_store.clone().unwrap(),
); );
if let Err(e) = storage_manager.init().await { if let Err(e) = storage_manager.init().await {
error!("failed to init storage manager: {}", e);
self.shutdown().await; self.shutdown().await;
return Err(e); return Err(e);
} }
@ -133,6 +138,7 @@ impl ServicesContext {
crypto, crypto,
); );
if let Err(e) = attachment_manager.init(update_callback).await { if let Err(e) = attachment_manager.init(update_callback).await {
error!("failed to init attachment manager: {}", e);
self.shutdown().await; self.shutdown().await;
return Err(e); return Err(e);
} }

View File

@ -45,11 +45,14 @@ impl TableStore {
} }
pub(crate) async fn terminate(&self) { pub(crate) async fn terminate(&self) {
assert!( let inner = self.inner.lock();
self.inner.lock().opened.is_empty(), if !inner.opened.is_empty() {
"all open databases should have been closed" panic!(
"all open databases should have been closed: {:?}",
inner.opened
); );
} }
}
pub(crate) fn on_table_db_drop(&self, table: String) { pub(crate) fn on_table_db_drop(&self, table: String) {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();

View File

@ -55,13 +55,13 @@ impl TableDB {
} }
/// Get the total number of columns in the TableDB /// Get the total number of columns in the TableDB
pub fn get_column_count(&self) -> EyreResult<u32> { pub fn get_column_count(&self) -> VeilidAPIResult<u32> {
let db = &self.unlocked_inner.database; let db = &self.unlocked_inner.database;
db.num_columns().wrap_err("failed to get column count: {}") db.num_columns().map_err(VeilidAPIError::from)
} }
/// Get the list of keys in a column of the TableDB /// Get the list of keys in a column of the TableDB
pub async fn get_keys(&self, col: u32) -> EyreResult<Vec<Box<[u8]>>> { pub async fn get_keys(&self, col: u32) -> VeilidAPIResult<Vec<Box<[u8]>>> {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let mut out: Vec<Box<[u8]>> = Vec::new(); let mut out: Vec<Box<[u8]>> = Vec::new();
db.iter(col, None, |kv| { db.iter(col, None, |kv| {
@ -69,7 +69,7 @@ impl TableDB {
Ok(Option::<()>::None) Ok(Option::<()>::None)
}) })
.await .await
.wrap_err("failed to get keys for column")?; .map_err(VeilidAPIError::from)?;
Ok(out) Ok(out)
} }
@ -80,15 +80,15 @@ impl TableDB {
} }
/// Store a key with a value in a column in the TableDB. Performs a single transaction immediately. /// Store a key with a value in a column in the TableDB. Performs a single transaction immediately.
pub async fn store(&self, col: u32, key: &[u8], value: &[u8]) -> EyreResult<()> { pub async fn store(&self, col: u32, key: &[u8], value: &[u8]) -> VeilidAPIResult<()> {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let mut dbt = db.transaction(); let mut dbt = db.transaction();
dbt.put(col, key, value); dbt.put(col, key, value);
db.write(dbt).await.wrap_err("failed to store key") db.write(dbt).await.map_err(VeilidAPIError::generic)
} }
/// Store a key in rkyv format with a value in a column in the TableDB. Performs a single transaction immediately. /// Store a key in rkyv format with a value in a column in the TableDB. Performs a single transaction immediately.
pub async fn store_rkyv<T>(&self, col: u32, key: &[u8], value: &T) -> EyreResult<()> pub async fn store_rkyv<T>(&self, col: u32, key: &[u8], value: &T) -> VeilidAPIResult<()>
where where
T: RkyvSerialize<DefaultVeilidRkyvSerializer>, T: RkyvSerialize<DefaultVeilidRkyvSerializer>,
{ {
@ -97,30 +97,30 @@ impl TableDB {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let mut dbt = db.transaction(); let mut dbt = db.transaction();
dbt.put(col, key, v.as_slice()); dbt.put(col, key, v.as_slice());
db.write(dbt).await.wrap_err("failed to store key") db.write(dbt).await.map_err(VeilidAPIError::generic)
} }
/// Store a key in json format with a value in a column in the TableDB. Performs a single transaction immediately. /// Store a key in json format with a value in a column in the TableDB. Performs a single transaction immediately.
pub async fn store_json<T>(&self, col: u32, key: &[u8], value: &T) -> EyreResult<()> pub async fn store_json<T>(&self, col: u32, key: &[u8], value: &T) -> VeilidAPIResult<()>
where where
T: serde::Serialize, T: serde::Serialize,
{ {
let v = serde_json::to_vec(value)?; let v = serde_json::to_vec(value).map_err(VeilidAPIError::internal)?;
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let mut dbt = db.transaction(); let mut dbt = db.transaction();
dbt.put(col, key, v.as_slice()); dbt.put(col, key, v.as_slice());
db.write(dbt).await.wrap_err("failed to store key") db.write(dbt).await.map_err(VeilidAPIError::generic)
} }
/// Read a key from a column in the TableDB immediately. /// Read a key from a column in the TableDB immediately.
pub async fn load(&self, col: u32, key: &[u8]) -> EyreResult<Option<Vec<u8>>> { pub async fn load(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<Vec<u8>>> {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
db.get(col, key).await.wrap_err("failed to get key") db.get(col, key).await.map_err(VeilidAPIError::from)
} }
/// Read an rkyv key from a column in the TableDB immediately /// Read an rkyv key from a column in the TableDB immediately
pub async fn load_rkyv<T>(&self, col: u32, key: &[u8]) -> EyreResult<Option<T>> pub async fn load_rkyv<T>(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<T>>
where where
T: RkyvArchive, T: RkyvArchive,
<T as RkyvArchive>::Archived: <T as RkyvArchive>::Archived:
@ -128,33 +128,33 @@ impl TableDB {
<T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>, <T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>,
{ {
let out = match self.load(col, key).await? { let out = match self.load(col, key).await? {
Some(v) => from_rkyv(v)?, Some(v) => Some(from_rkyv(v)?),
None => None, None => None,
}; };
Ok(out) Ok(out)
} }
/// Read an serde-json key from a column in the TableDB immediately /// Read an serde-json key from a column in the TableDB immediately
pub async fn load_json<T>(&self, col: u32, key: &[u8]) -> EyreResult<Option<T>> pub async fn load_json<T>(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<T>>
where where
T: for<'de> serde::Deserialize<'de>, T: for<'de> serde::Deserialize<'de>,
{ {
let out = match self.load(col, key).await? { let out = match self.load(col, key).await? {
Some(v) => serde_json::from_slice(&v)?, Some(v) => Some(serde_json::from_slice(&v).map_err(VeilidAPIError::internal)?),
None => None, None => None,
}; };
Ok(out) Ok(out)
} }
/// Delete key with from a column in the TableDB /// Delete key with from a column in the TableDB
pub async fn delete(&self, col: u32, key: &[u8]) -> EyreResult<Option<Vec<u8>>> { pub async fn delete(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<Vec<u8>>> {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let old_value = db.delete(col, key).await.wrap_err("failed to delete key")?; let old_value = db.delete(col, key).await.map_err(VeilidAPIError::from)?;
Ok(old_value) Ok(old_value)
} }
/// Delete rkyv key with from a column in the TableDB /// Delete rkyv key with from a column in the TableDB
pub async fn delete_rkyv<T>(&self, col: u32, key: &[u8]) -> EyreResult<Option<T>> pub async fn delete_rkyv<T>(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<T>>
where where
T: RkyvArchive, T: RkyvArchive,
<T as RkyvArchive>::Archived: <T as RkyvArchive>::Archived:
@ -162,21 +162,21 @@ impl TableDB {
<T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>, <T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>,
{ {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let old_value = match db.delete(col, key).await.wrap_err("failed to delete key")? { let old_value = match db.delete(col, key).await.map_err(VeilidAPIError::from)? {
Some(v) => from_rkyv(v)?, Some(v) => Some(from_rkyv(v)?),
None => None, None => None,
}; };
Ok(old_value) Ok(old_value)
} }
/// Delete serde-json key with from a column in the TableDB /// Delete serde-json key with from a column in the TableDB
pub async fn delete_json<T>(&self, col: u32, key: &[u8]) -> EyreResult<Option<T>> pub async fn delete_json<T>(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<T>>
where where
T: for<'de> serde::Deserialize<'de>, T: for<'de> serde::Deserialize<'de>,
{ {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let old_value = match db.delete(col, key).await.wrap_err("failed to delete key")? { let old_value = match db.delete(col, key).await.map_err(VeilidAPIError::from)? {
Some(v) => serde_json::from_slice(&v)?, Some(v) => Some(serde_json::from_slice(&v).map_err(VeilidAPIError::internal)?),
None => None, None => None,
}; };
Ok(old_value) Ok(old_value)
@ -219,18 +219,18 @@ impl TableDBTransaction {
} }
/// Commit the transaction. Performs all actions atomically. /// Commit the transaction. Performs all actions atomically.
pub async fn commit(self) -> EyreResult<()> { pub async fn commit(self) -> VeilidAPIResult<()> {
let dbt = { let dbt = {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
inner inner
.dbt .dbt
.take() .take()
.ok_or_else(|| eyre!("transaction already completed"))? .ok_or_else(|| VeilidAPIError::generic("transaction already completed"))?
}; };
let db = self.db.unlocked_inner.database.clone(); let db = self.db.unlocked_inner.database.clone();
db.write(dbt) db.write(dbt)
.await .await
.wrap_err("commit failed, transaction lost") .map_err(|e| VeilidAPIError::generic(format!("commit failed, transaction lost: {}", e)))
} }
/// Rollback the transaction. Does nothing to the TableDB. /// Rollback the transaction. Does nothing to the TableDB.
@ -246,7 +246,7 @@ impl TableDBTransaction {
} }
/// Store a key in rkyv format with a value in a column in the TableDB /// Store a key in rkyv format with a value in a column in the TableDB
pub fn store_rkyv<T>(&self, col: u32, key: &[u8], value: &T) -> EyreResult<()> pub fn store_rkyv<T>(&self, col: u32, key: &[u8], value: &T) -> VeilidAPIResult<()>
where where
T: RkyvSerialize<DefaultVeilidRkyvSerializer>, T: RkyvSerialize<DefaultVeilidRkyvSerializer>,
{ {
@ -257,11 +257,11 @@ impl TableDBTransaction {
} }
/// Store a key in rkyv format with a value in a column in the TableDB /// Store a key in rkyv format with a value in a column in the TableDB
pub fn store_json<T>(&self, col: u32, key: &[u8], value: &T) -> EyreResult<()> pub fn store_json<T>(&self, col: u32, key: &[u8], value: &T) -> VeilidAPIResult<()>
where where
T: serde::Serialize, T: serde::Serialize,
{ {
let v = serde_json::to_vec(value)?; let v = serde_json::to_vec(value).map_err(VeilidAPIError::internal)?;
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
inner.dbt.as_mut().unwrap().put(col, key, v.as_slice()); inner.dbt.as_mut().unwrap().put(col, key, v.as_slice());
Ok(()) Ok(())

View File

@ -1,10 +1,10 @@
use super::*; use super::*;
use crate::intf::table_db::TableDBInner; use crate::intf::table_db::TableDBUnlockedInner;
pub use crate::intf::table_db::{TableDB, TableDBTransaction}; pub use crate::intf::table_db::{TableDB, TableDBTransaction};
use keyvaluedb_web::*; use keyvaluedb_web::*;
struct TableStoreInner { struct TableStoreInner {
opened: BTreeMap<String, Weak<Mutex<TableDBInner>>>, opened: BTreeMap<String, Weak<TableDBUnlockedInner>>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -95,7 +95,7 @@ impl TableStore {
}; };
} }
} }
let db = Database::open(table_name.clone(), column_count) let db = Database::open(table_name.clone(), column_count, false)
.await .await
.wrap_err("failed to open tabledb")?; .wrap_err("failed to open tabledb")?;
trace!( trace!(

View File

@ -538,7 +538,7 @@ impl BucketEntryInner {
} }
} }
pub fn set_our_node_info_ts(&mut self, routing_domain: RoutingDomain, seen_ts: Timestamp) { pub fn set_seen_our_node_info_ts(&mut self, routing_domain: RoutingDomain, seen_ts: Timestamp) {
match routing_domain { match routing_domain {
RoutingDomain::LocalNetwork => { RoutingDomain::LocalNetwork => {
self.local_network.last_seen_our_node_info_ts = seen_ts; self.local_network.last_seen_our_node_info_ts = seen_ts;

View File

@ -142,7 +142,10 @@ impl RoutingTable {
.latency .latency
.as_ref() .as_ref()
.map(|l| { .map(|l| {
format!("{:.2}ms", timestamp_to_secs(l.average.as_u64())) format!(
"{:.2}ms",
timestamp_to_secs(l.average.as_u64()) * 1000.0
)
}) })
.unwrap_or_else(|| "???.??ms".to_string()) .unwrap_or_else(|| "???.??ms".to_string())
}) })

View File

@ -324,11 +324,11 @@ impl RoutingTable {
let dbx = tdb.transact(); let dbx = tdb.transact();
if let Err(e) = dbx.store_rkyv(0, b"serialized_bucket_map", &serialized_bucket_map) { if let Err(e) = dbx.store_rkyv(0, b"serialized_bucket_map", &serialized_bucket_map) {
dbx.rollback(); dbx.rollback();
return Err(e); return Err(e.into());
} }
if let Err(e) = dbx.store_rkyv(0, b"all_entry_bytes", &all_entry_bytes) { if let Err(e) = dbx.store_rkyv(0, b"all_entry_bytes", &all_entry_bytes) {
dbx.rollback(); dbx.rollback();
return Err(e); return Err(e.into());
} }
dbx.commit().await?; dbx.commit().await?;
Ok(()) Ok(())

View File

@ -170,8 +170,8 @@ pub trait NodeRefBase: Sized {
) -> bool { ) -> bool {
self.operate(|_rti, e| e.has_seen_our_node_info_ts(routing_domain, our_node_info_ts)) self.operate(|_rti, e| e.has_seen_our_node_info_ts(routing_domain, our_node_info_ts))
} }
fn set_our_node_info_ts(&self, routing_domain: RoutingDomain, seen_ts: Timestamp) { fn set_seen_our_node_info_ts(&self, routing_domain: RoutingDomain, seen_ts: Timestamp) {
self.operate_mut(|_rti, e| e.set_our_node_info_ts(routing_domain, seen_ts)); self.operate_mut(|_rti, e| e.set_seen_our_node_info_ts(routing_domain, seen_ts));
} }
fn network_class(&self, routing_domain: RoutingDomain) -> Option<NetworkClass> { fn network_class(&self, routing_domain: RoutingDomain) -> Option<NetworkClass> {
self.operate(|_rt, e| e.node_info(routing_domain).map(|n| n.network_class())) self.operate(|_rt, e| e.node_info(routing_domain).map(|n| n.network_class()))

View File

@ -557,11 +557,18 @@ impl RoutingTableInner {
.map(|nr| nr.same_bucket_entry(&entry)) .map(|nr| nr.same_bucket_entry(&entry))
.unwrap_or(false); .unwrap_or(false);
if e.needs_ping(cur_ts, is_our_relay) { if e.needs_ping(cur_ts, is_our_relay) {
debug!("needs_ping: {}", e.best_node_id());
return true; return true;
} }
// If we need a ping because this node hasn't seen our latest node info, then do it // If we need a ping because this node hasn't seen our latest node info, then do it
if let Some(own_node_info_ts) = own_node_info_ts { if let Some(own_node_info_ts) = own_node_info_ts {
if !e.has_seen_our_node_info_ts(routing_domain, own_node_info_ts) { if !e.has_seen_our_node_info_ts(routing_domain, own_node_info_ts) {
//xxx remove this when we fix
debug!(
"!has_seen_our_node_info_ts: {} own_node_info_ts={}",
e.best_node_id(),
own_node_info_ts
);
return true; return true;
} }
} }

View File

@ -1350,7 +1350,8 @@ impl RPCProcessor {
// Update the 'seen our node info' timestamp to determine if this node needs a // Update the 'seen our node info' timestamp to determine if this node needs a
// 'node info update' ping // 'node info update' ping
if let Some(sender_nr) = &opt_sender_nr { if let Some(sender_nr) = &opt_sender_nr {
sender_nr.set_our_node_info_ts(routing_domain, operation.target_node_info_ts()); sender_nr
.set_seen_our_node_info_ts(routing_domain, operation.target_node_info_ts());
} }
// Make the RPC message // Make the RPC message

View File

@ -154,7 +154,15 @@ impl StorageManagerInner {
async fn load_metadata(&mut self) -> EyreResult<()> { async fn load_metadata(&mut self) -> EyreResult<()> {
if let Some(metadata_db) = &self.metadata_db { if let Some(metadata_db) = &self.metadata_db {
self.offline_subkey_writes = metadata_db.load_rkyv(0, b"offline_subkey_writes").await?.unwrap_or_default(); self.offline_subkey_writes = match metadata_db.load_rkyv(0, b"offline_subkey_writes").await {
Ok(v) => v.unwrap_or_default(),
Err(_) => {
if let Err(e) = metadata_db.delete(0,b"offline_subkey_writes").await {
debug!("offline_subkey_writes format changed, clearing: {}", e);
}
Default::default()
}
}
} }
Ok(()) Ok(())
} }

View File

@ -110,10 +110,7 @@ pub async fn test_store_delete_load(ts: TableStore) {
); );
assert_eq!(db.load(2, b"baz").await.unwrap(), Some(b"QWERTY".to_vec())); assert_eq!(db.load(2, b"baz").await.unwrap(), Some(b"QWERTY".to_vec()));
assert_eq!( assert_eq!(db.delete(1, b"bar").await.unwrap(), Some(b"FNORD".to_vec()));
db.delete(1, b"bar").await.unwrap(),
Some(b"QWERTYUIOP".to_vec())
);
assert_eq!(db.delete(1, b"bar").await.unwrap(), None); assert_eq!(db.delete(1, b"bar").await.unwrap(), None);
assert!( assert!(
db.delete(4, b"bar").await.is_err(), db.delete(4, b"bar").await.is_err(),

View File

@ -221,3 +221,36 @@ impl VeilidAPIError {
} }
} }
} }
pub type VeilidAPIResult<T> = Result<T, VeilidAPIError>;
impl From<std::io::Error> for VeilidAPIError {
fn from(e: std::io::Error) -> Self {
match e.kind() {
std::io::ErrorKind::TimedOut => VeilidAPIError::timeout(),
std::io::ErrorKind::ConnectionRefused => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::ConnectionReset => VeilidAPIError::no_connection(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::HostUnreachable => VeilidAPIError::no_connection(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::NetworkUnreachable => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::ConnectionAborted => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::NotConnected => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::AddrInUse => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::AddrNotAvailable => VeilidAPIError::no_connection(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::NetworkDown => VeilidAPIError::no_connection(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::ReadOnlyFilesystem => VeilidAPIError::internal(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::NotSeekable => VeilidAPIError::internal(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::FilesystemQuotaExceeded => VeilidAPIError::internal(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::Deadlock => VeilidAPIError::internal(e.to_string()),
std::io::ErrorKind::Unsupported => VeilidAPIError::internal(e.to_string()),
std::io::ErrorKind::OutOfMemory => VeilidAPIError::internal(e.to_string()),
_ => VeilidAPIError::generic(e.to_string()),
}
}
}

View File

@ -122,14 +122,14 @@ impl<E: Debug + fmt::Display> std::error::Error for VeilidRkyvError<E> {}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pub fn to_rkyv<T>(value: &T) -> EyreResult<Vec<u8>> pub fn to_rkyv<T>(value: &T) -> VeilidAPIResult<Vec<u8>>
where where
T: RkyvSerialize<DefaultVeilidRkyvSerializer>, T: RkyvSerialize<DefaultVeilidRkyvSerializer>,
{ {
let mut serializer = DefaultVeilidRkyvSerializer::default(); let mut serializer = DefaultVeilidRkyvSerializer::default();
serializer serializer
.serialize_value(value) .serialize_value(value)
.wrap_err("failed to serialize object")?; .map_err(|e| VeilidAPIError::generic(format!("failed to serialize object: {}", e)))?;
Ok(serializer Ok(serializer
.into_inner() .into_inner()
.into_serializer() .into_serializer()
@ -137,7 +137,7 @@ where
.to_vec()) .to_vec())
} }
pub fn from_rkyv<T>(bytes: Vec<u8>) -> EyreResult<T> pub fn from_rkyv<T>(bytes: Vec<u8>) -> VeilidAPIResult<T>
where where
T: RkyvArchive, T: RkyvArchive,
<T as RkyvArchive>::Archived: <T as RkyvArchive>::Archived:
@ -145,7 +145,7 @@ where
<T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>, <T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>,
{ {
rkyv::check_archived_root::<T>(&bytes) rkyv::check_archived_root::<T>(&bytes)
.map_err(|e| eyre!("checkbytes failed: {}", e))? .map_err(|e| VeilidAPIError::generic(format!("checkbytes failed: {}", e)))?
.deserialize(&mut VeilidSharedDeserializeMap::default()) .deserialize(&mut VeilidSharedDeserializeMap::default())
.map_err(|e| eyre!("failed to deserialize: {}", e)) .map_err(|e| VeilidAPIError::generic(format!("failed to deserialize: {}", e)))
} }

View File

@ -32,4 +32,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 73d2f470b1d889e27fcfda1d6e6efec66f98af3f PODFILE CHECKSUM: 73d2f470b1d889e27fcfda1d6e6efec66f98af3f
COCOAPODS: 1.11.3 COCOAPODS: 1.12.1

View File

@ -33,7 +33,7 @@ lazy_static! {
Mutex::new(BTreeMap::new()); Mutex::new(BTreeMap::new());
} }
async fn get_veilid_api() -> Result<veilid_core::VeilidAPI, veilid_core::VeilidAPIError> { async fn get_veilid_api() -> veilid_core::VeilidAPIResult<veilid_core::VeilidAPI> {
let api_lock = VEILID_API.lock().await; let api_lock = VEILID_API.lock().await;
api_lock api_lock
.as_ref() .as_ref()
@ -41,7 +41,7 @@ async fn get_veilid_api() -> Result<veilid_core::VeilidAPI, veilid_core::VeilidA
.ok_or(veilid_core::VeilidAPIError::NotInitialized) .ok_or(veilid_core::VeilidAPIError::NotInitialized)
} }
async fn take_veilid_api() -> Result<veilid_core::VeilidAPI, veilid_core::VeilidAPIError> { async fn take_veilid_api() -> veilid_core::VeilidAPIResult<veilid_core::VeilidAPI> {
let mut api_lock = VEILID_API.lock().await; let mut api_lock = VEILID_API.lock().await;
api_lock api_lock
.take() .take()
@ -55,7 +55,7 @@ async fn take_veilid_api() -> Result<veilid_core::VeilidAPI, veilid_core::Veilid
define_string_destructor!(free_string); define_string_destructor!(free_string);
// Utility types for async API results // Utility types for async API results
type APIResult<T> = Result<T, veilid_core::VeilidAPIError>; type APIResult<T> = veilid_core::VeilidAPIResult<T>;
const APIRESULT_VOID: APIResult<()> = APIResult::Ok(()); const APIRESULT_VOID: APIResult<()> = APIResult::Ok(());
// Parse target // Parse target
@ -791,7 +791,7 @@ pub extern "C" fn table_db_get_keys(port: i64, id: u32, col: u32) {
table_db.clone() table_db.clone()
}; };
let keys = table_db.get_keys(col).await.map_err(veilid_core::VeilidAPIError::generic)?; let keys = table_db.get_keys(col).await?;
let out: Vec<String> = keys.into_iter().map(|k| BASE64URL_NOPAD.encode(&k)).collect(); let out: Vec<String> = keys.into_iter().map(|k| BASE64URL_NOPAD.encode(&k)).collect();
APIResult::Ok(out) APIResult::Ok(out)
}); });
@ -839,7 +839,7 @@ pub extern "C" fn table_db_transaction_commit(port: i64, id: u32) {
tdbt.clone() tdbt.clone()
}; };
tdbt.commit().await.map_err(veilid_core::VeilidAPIError::generic)?; tdbt.commit().await?;
APIRESULT_VOID APIRESULT_VOID
}); });
} }
@ -938,7 +938,7 @@ pub extern "C" fn table_db_store(port: i64, id: u32, col: u32, key: FfiStr, valu
table_db.clone() table_db.clone()
}; };
table_db.store(col, &key, &value).await.map_err(veilid_core::VeilidAPIError::generic)?; table_db.store(col, &key, &value).await?;
APIRESULT_VOID APIRESULT_VOID
}); });
} }
@ -960,7 +960,7 @@ pub extern "C" fn table_db_load(port: i64, id: u32, col: u32, key: FfiStr) {
table_db.clone() table_db.clone()
}; };
let out = table_db.load(col, &key).await.map_err(veilid_core::VeilidAPIError::generic)?; let out = table_db.load(col, &key).await?;
let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x)); let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x));
APIResult::Ok(out) APIResult::Ok(out)
}); });
@ -984,7 +984,7 @@ pub extern "C" fn table_db_delete(port: i64, id: u32, col: u32, key: FfiStr) {
table_db.clone() table_db.clone()
}; };
let out = table_db.delete(col, &key).await.map_err(veilid_core::VeilidAPIError::generic)?; let out = table_db.delete(col, &key).await?;
let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x)); let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x));
APIResult::Ok(out) APIResult::Ok(out)
}); });

View File

@ -719,19 +719,21 @@ pub fn table_db_get_column_count(id: u32) -> u32 {
#[wasm_bindgen()] #[wasm_bindgen()]
pub fn table_db_get_keys(id: u32, col: u32) -> Promise { pub fn table_db_get_keys(id: u32, col: u32) -> Promise {
wrap_api_future_json(async move { wrap_api_future_json(async move {
let table_db = {
let table_dbs = (*TABLE_DBS).borrow(); let table_dbs = (*TABLE_DBS).borrow();
let Some(table_db) = table_dbs.get(&id) else { let Some(table_db) = table_dbs.get(&id) else {
return None; return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("table_db_store", "id", id));
}; };
let Ok(keys) = table_db.clone().get_keys(col) else { table_db.clone()
return None;
}; };
let keys = table_db.clone().get_keys(col).await?;
let out: Vec<String> = keys let out: Vec<String> = keys
.into_iter() .into_iter()
.map(|k| data_encoding::BASE64URL_NOPAD.encode(&k)) .map(|k| data_encoding::BASE64URL_NOPAD.encode(&k))
.collect(); .collect();
APIResult::Ok(Some(out)) APIResult::Ok(out)
}); })
} }
fn add_table_db_transaction(tdbt: veilid_core::TableDBTransaction) -> u32 { fn add_table_db_transaction(tdbt: veilid_core::TableDBTransaction) -> u32 {
@ -775,9 +777,7 @@ pub fn table_db_transaction_commit(id: u32) -> Promise {
tdbt.clone() tdbt.clone()
}; };
tdbt.commit() tdbt.commit().await?;
.await
.map_err(veilid_core::VeilidAPIError::generic)?;
APIRESULT_UNDEFINED APIRESULT_UNDEFINED
}) })
} }
@ -856,10 +856,7 @@ pub fn table_db_store(id: u32, col: u32, key: String, value: String) -> Promise
table_db.clone() table_db.clone()
}; };
table_db table_db.store(col, &key, &value).await?;
.store(col, &key, &value)
.await
.map_err(veilid_core::VeilidAPIError::generic)?;
APIRESULT_UNDEFINED APIRESULT_UNDEFINED
}) })
} }
@ -878,9 +875,7 @@ pub fn table_db_load(id: u32, col: u32, key: String) -> Promise {
table_db.clone() table_db.clone()
}; };
let out = table_db let out = table_db.load(col, &key).await?;
.load(col, &key)
.map_err(veilid_core::VeilidAPIError::generic)?;
let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x)); let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x));
APIResult::Ok(out) APIResult::Ok(out)
}) })
@ -900,10 +895,7 @@ pub fn table_db_delete(id: u32, col: u32, key: String) -> Promise {
table_db.clone() table_db.clone()
}; };
let out = table_db let out = table_db.delete(col, &key).await?;
.delete(col, &key)
.await
.map_err(veilid_core::VeilidAPIError::generic)?;
let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x)); let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x));
APIResult::Ok(out) APIResult::Ok(out)
}) })