(wasm) Improved memory management, track by struct so drop works, use --weak-ref for wasm-bindgen
This commit is contained in:
parent
93963e9d08
commit
6b7301a963
@ -3,7 +3,7 @@ use super::*;
|
|||||||
|
|
||||||
#[wasm_bindgen()]
|
#[wasm_bindgen()]
|
||||||
pub struct VeilidRoutingContext {
|
pub struct VeilidRoutingContext {
|
||||||
id: u32,
|
inner_routing_context: Option<RoutingContext>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen()]
|
#[wasm_bindgen()]
|
||||||
@ -12,8 +12,10 @@ impl VeilidRoutingContext {
|
|||||||
/// Use one of the `VeilidRoutingContext.create___()` factory methods instead.
|
/// Use one of the `VeilidRoutingContext.create___()` factory methods instead.
|
||||||
/// @deprecated
|
/// @deprecated
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(id: u32) -> Self {
|
pub fn new() -> Self {
|
||||||
Self { id }
|
Self {
|
||||||
|
inner_routing_context: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
@ -24,8 +26,9 @@ impl VeilidRoutingContext {
|
|||||||
pub fn createWithoutPrivacy() -> APIResult<VeilidRoutingContext> {
|
pub fn createWithoutPrivacy() -> APIResult<VeilidRoutingContext> {
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
let routing_context = veilid_api.routing_context();
|
let routing_context = veilid_api.routing_context();
|
||||||
let id = add_routing_context(routing_context);
|
Ok(VeilidRoutingContext {
|
||||||
Ok(VeilidRoutingContext { id })
|
inner_routing_context: Some(routing_context),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn on sender privacy, enabling the use of safety routes.
|
/// Turn on sender privacy, enabling the use of safety routes.
|
||||||
@ -39,8 +42,9 @@ impl VeilidRoutingContext {
|
|||||||
pub fn createWithPrivacy() -> APIResult<VeilidRoutingContext> {
|
pub fn createWithPrivacy() -> APIResult<VeilidRoutingContext> {
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
let routing_context = veilid_api.routing_context().with_privacy()?;
|
let routing_context = veilid_api.routing_context().with_privacy()?;
|
||||||
let id = add_routing_context(routing_context);
|
Ok(VeilidRoutingContext {
|
||||||
Ok(VeilidRoutingContext { id })
|
inner_routing_context: Some(routing_context),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn on privacy using a custom `SafetySelection`
|
/// Turn on privacy using a custom `SafetySelection`
|
||||||
@ -51,16 +55,18 @@ impl VeilidRoutingContext {
|
|||||||
let routing_context = veilid_api
|
let routing_context = veilid_api
|
||||||
.routing_context()
|
.routing_context()
|
||||||
.with_custom_privacy(safety_selection)?;
|
.with_custom_privacy(safety_selection)?;
|
||||||
let id = add_routing_context(routing_context);
|
Ok(VeilidRoutingContext {
|
||||||
Ok(VeilidRoutingContext { id })
|
inner_routing_context: Some(routing_context),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use a specified `Sequencing` preference, with or without privacy.
|
/// Use a specified `Sequencing` preference, with or without privacy.
|
||||||
pub fn createWithSequencing(sequencing: Sequencing) -> APIResult<VeilidRoutingContext> {
|
pub fn createWithSequencing(sequencing: Sequencing) -> APIResult<VeilidRoutingContext> {
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
let routing_context = veilid_api.routing_context().with_sequencing(sequencing);
|
let routing_context = veilid_api.routing_context().with_sequencing(sequencing);
|
||||||
let id = add_routing_context(routing_context);
|
Ok(VeilidRoutingContext {
|
||||||
Ok(VeilidRoutingContext { id })
|
inner_routing_context: Some(routing_context),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
@ -115,6 +121,7 @@ impl VeilidRoutingContext {
|
|||||||
/// * `call_id` - specifies which call to reply to, and it comes from a VeilidUpdate::AppCall, specifically the VeilidAppCall::id() value.
|
/// * `call_id` - specifies which call to reply to, and it comes from a VeilidUpdate::AppCall, specifically the VeilidAppCall::id() value.
|
||||||
/// * `message` - is an answer blob to be returned by the remote node's RoutingContext::app_call() function, and may be up to 32768 bytes
|
/// * `message` - is an answer blob to be returned by the remote node's RoutingContext::app_call() function, and may be up to 32768 bytes
|
||||||
pub async fn appCallReply(call_id: String, message: String) -> APIResult<()> {
|
pub async fn appCallReply(call_id: String, message: String) -> APIResult<()> {
|
||||||
|
let message = unmarshall(message);
|
||||||
let call_id = match call_id.parse() {
|
let call_id = match call_id.parse() {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -124,9 +131,7 @@ impl VeilidRoutingContext {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
veilid_api
|
veilid_api.app_call_reply(call_id, message).await?;
|
||||||
.app_call_reply(call_id, message.into_bytes())
|
|
||||||
.await?;
|
|
||||||
APIRESULT_UNDEFINED
|
APIRESULT_UNDEFINED
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,9 +139,8 @@ impl VeilidRoutingContext {
|
|||||||
// Instance methods
|
// Instance methods
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
fn getRoutingContext(&self) -> APIResult<RoutingContext> {
|
fn getRoutingContext(&self) -> APIResult<RoutingContext> {
|
||||||
let rc = (*ROUTING_CONTEXTS).borrow();
|
let Some(routing_context) = &self.inner_routing_context else {
|
||||||
let Some(routing_context) = rc.get(&self.id) else {
|
return APIResult::Err(veilid_core::VeilidAPIError::generic("Unable to getRoutingContext instance. inner_routing_context is None."));
|
||||||
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("getRoutingContext", "id", self.id));
|
|
||||||
};
|
};
|
||||||
APIResult::Ok(routing_context.clone())
|
APIResult::Ok(routing_context.clone())
|
||||||
}
|
}
|
||||||
@ -150,12 +154,11 @@ impl VeilidRoutingContext {
|
|||||||
#[wasm_bindgen(skip_jsdoc)]
|
#[wasm_bindgen(skip_jsdoc)]
|
||||||
pub async fn appMessage(&self, target_string: String, message: String) -> APIResult<()> {
|
pub async fn appMessage(&self, target_string: String, message: String) -> APIResult<()> {
|
||||||
let routing_context = self.getRoutingContext()?;
|
let routing_context = self.getRoutingContext()?;
|
||||||
|
let message = unmarshall(message);
|
||||||
|
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
let target = veilid_api.parse_as_target(target_string).await?;
|
let target = veilid_api.parse_as_target(target_string).await?;
|
||||||
routing_context
|
routing_context.app_message(target, message).await?;
|
||||||
.app_message(target, message.into_bytes())
|
|
||||||
.await?;
|
|
||||||
APIRESULT_UNDEFINED
|
APIRESULT_UNDEFINED
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,15 +171,13 @@ impl VeilidRoutingContext {
|
|||||||
/// @returns an answer blob of up to `32768` bytes, base64Url encoded.
|
/// @returns an answer blob of up to `32768` bytes, base64Url encoded.
|
||||||
#[wasm_bindgen(skip_jsdoc)]
|
#[wasm_bindgen(skip_jsdoc)]
|
||||||
pub async fn appCall(&self, target_string: String, request: String) -> APIResult<String> {
|
pub async fn appCall(&self, target_string: String, request: String) -> APIResult<String> {
|
||||||
let request: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
let request: Vec<u8> = unmarshall(request);
|
||||||
.decode(&request.as_bytes())
|
|
||||||
.unwrap();
|
|
||||||
let routing_context = self.getRoutingContext()?;
|
let routing_context = self.getRoutingContext()?;
|
||||||
|
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
let target = veilid_api.parse_as_target(target_string).await?;
|
let target = veilid_api.parse_as_target(target_string).await?;
|
||||||
let answer = routing_context.app_call(target, request).await?;
|
let answer = routing_context.app_call(target, request).await?;
|
||||||
let answer = data_encoding::BASE64URL_NOPAD.encode(&answer);
|
let answer = marshall(&answer);
|
||||||
APIResult::Ok(answer)
|
APIResult::Ok(answer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use super::*;
|
|||||||
|
|
||||||
#[wasm_bindgen()]
|
#[wasm_bindgen()]
|
||||||
pub struct VeilidTableDB {
|
pub struct VeilidTableDB {
|
||||||
id: u32,
|
inner_table_db: Option<TableDB>,
|
||||||
tableName: String,
|
tableName: String,
|
||||||
columnCount: u32,
|
columnCount: u32,
|
||||||
}
|
}
|
||||||
@ -15,48 +15,35 @@ impl VeilidTableDB {
|
|||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(tableName: String, columnCount: u32) -> Self {
|
pub fn new(tableName: String, columnCount: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: 0,
|
inner_table_db: None,
|
||||||
tableName,
|
tableName,
|
||||||
columnCount,
|
columnCount,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getTableDB(&self) -> APIResult<TableDB> {
|
fn getTableDB(&self) -> APIResult<TableDB> {
|
||||||
let table_dbs = (*TABLE_DBS).borrow();
|
let Some(table_db) = &self.inner_table_db else {
|
||||||
let Some(table_db) = table_dbs.get(&self.id) else {
|
return APIResult::Err(veilid_core::VeilidAPIError::generic("Unable to getTableDB instance. Ensure you've called openTable()."));
|
||||||
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("getTableDB", "id", self.id));
|
|
||||||
};
|
};
|
||||||
APIResult::Ok(table_db.clone())
|
APIResult::Ok(table_db.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get or create the TableDB database table.
|
/// Get or create the TableDB database table.
|
||||||
/// This is called automatically when performing actions on the TableDB.
|
/// This is called automatically when performing actions on the TableDB.
|
||||||
pub async fn openTable(&mut self) -> APIResult<u32> {
|
pub async fn openTable(&mut self) -> APIResult<()> {
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
let tstore = veilid_api.table_store()?;
|
let tstore = veilid_api.table_store()?;
|
||||||
let table_db = tstore
|
let table_db = tstore
|
||||||
.open(&self.tableName, self.columnCount)
|
.open(&self.tableName, self.columnCount)
|
||||||
.await
|
.await
|
||||||
.map_err(veilid_core::VeilidAPIError::generic)?;
|
.map_err(veilid_core::VeilidAPIError::generic)?;
|
||||||
let new_id = add_table_db(table_db);
|
self.inner_table_db = Some(table_db);
|
||||||
self.id = new_id;
|
APIRESULT_UNDEFINED
|
||||||
APIResult::Ok(new_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Release the TableDB instance from memory.
|
|
||||||
pub fn releaseTable(&mut self) -> bool {
|
|
||||||
let mut tdbs = (*TABLE_DBS).borrow_mut();
|
|
||||||
let status = tdbs.remove(&self.id);
|
|
||||||
self.id = 0;
|
|
||||||
if status.is_none() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete this TableDB.
|
/// Delete this TableDB.
|
||||||
pub async fn deleteTable(&mut self) -> APIResult<bool> {
|
pub async fn deleteTable(&mut self) -> APIResult<bool> {
|
||||||
self.releaseTable();
|
self.inner_table_db = None;
|
||||||
|
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
let tstore = veilid_api.table_store()?;
|
let tstore = veilid_api.table_store()?;
|
||||||
@ -68,7 +55,7 @@ impl VeilidTableDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn ensureOpen(&mut self) {
|
async fn ensureOpen(&mut self) {
|
||||||
if self.id == 0 {
|
if self.inner_table_db.is_none() {
|
||||||
let _ = self.openTable().await;
|
let _ = self.openTable().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,14 +115,15 @@ impl VeilidTableDB {
|
|||||||
let table_db = self.getTableDB()?;
|
let table_db = self.getTableDB()?;
|
||||||
|
|
||||||
let transaction = table_db.transact();
|
let transaction = table_db.transact();
|
||||||
let transaction_id = add_table_db_transaction(transaction);
|
APIResult::Ok(VeilidTableDBTransaction {
|
||||||
APIResult::Ok(VeilidTableDBTransaction { id: transaction_id })
|
inner_transaction: Some(transaction),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct VeilidTableDBTransaction {
|
pub struct VeilidTableDBTransaction {
|
||||||
id: u32,
|
inner_transaction: Option<TableDBTransaction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@ -144,28 +132,19 @@ impl VeilidTableDBTransaction {
|
|||||||
/// Use `.createTransaction()` on an instance of `VeilidTableDB` instead.
|
/// Use `.createTransaction()` on an instance of `VeilidTableDB` instead.
|
||||||
/// @deprecated
|
/// @deprecated
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(id: u32) -> Self {
|
pub fn new() -> Self {
|
||||||
Self { id }
|
Self {
|
||||||
|
inner_transaction: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getTransaction(&self) -> APIResult<TableDBTransaction> {
|
fn getTransaction(&self) -> APIResult<TableDBTransaction> {
|
||||||
let transactions = (*TABLE_DB_TRANSACTIONS).borrow();
|
let Some(transaction) = &self.inner_transaction else {
|
||||||
let Some(transaction) = transactions.get(&self.id) else {
|
return APIResult::Err(veilid_core::VeilidAPIError::generic("Unable to getTransaction instance. inner_transaction is None."));
|
||||||
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("getTransaction", "id", &self.id));
|
|
||||||
};
|
};
|
||||||
APIResult::Ok(transaction.clone())
|
APIResult::Ok(transaction.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Releases the transaction from memory.
|
|
||||||
pub fn releaseTransaction(&mut self) -> bool {
|
|
||||||
let mut transactions = (*TABLE_DB_TRANSACTIONS).borrow_mut();
|
|
||||||
self.id = 0;
|
|
||||||
if transactions.remove(&self.id).is_none() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Commit the transaction. Performs all actions atomically.
|
/// Commit the transaction. Performs all actions atomically.
|
||||||
pub async fn commit(&self) -> APIResult<()> {
|
pub async fn commit(&self) -> APIResult<()> {
|
||||||
let transaction = self.getTransaction()?;
|
let transaction = self.getTransaction()?;
|
||||||
|
@ -37,7 +37,7 @@ if [[ "$1" == "release" ]]; then
|
|||||||
|
|
||||||
cargo build --target wasm32-unknown-unknown --release
|
cargo build --target wasm32-unknown-unknown --release
|
||||||
mkdir -p $OUTPUTDIR
|
mkdir -p $OUTPUTDIR
|
||||||
wasm-bindgen --out-dir $OUTPUTDIR --target web $INPUTDIR/veilid_wasm.wasm
|
wasm-bindgen --out-dir $OUTPUTDIR --target web --weak-refs $INPUTDIR/veilid_wasm.wasm
|
||||||
wasm-strip $OUTPUTDIR/veilid_wasm_bg.wasm
|
wasm-strip $OUTPUTDIR/veilid_wasm_bg.wasm
|
||||||
else
|
else
|
||||||
OUTPUTDIR=../target/wasm32-unknown-unknown/debug/pkg
|
OUTPUTDIR=../target/wasm32-unknown-unknown/debug/pkg
|
||||||
@ -45,7 +45,7 @@ else
|
|||||||
|
|
||||||
RUSTFLAGS="-O -g $RUSTFLAGS" cargo build --target wasm32-unknown-unknown
|
RUSTFLAGS="-O -g $RUSTFLAGS" cargo build --target wasm32-unknown-unknown
|
||||||
mkdir -p $OUTPUTDIR
|
mkdir -p $OUTPUTDIR
|
||||||
wasm-bindgen --out-dir $OUTPUTDIR --target web --keep-debug --debug $INPUTDIR/veilid_wasm.wasm
|
wasm-bindgen --out-dir $OUTPUTDIR --target web --weak-refs --keep-debug --debug $INPUTDIR/veilid_wasm.wasm
|
||||||
./wasm-sourcemap.py $OUTPUTDIR/veilid_wasm_bg.wasm -o $OUTPUTDIR/veilid_wasm_bg.wasm.map --dwarfdump $DWARFDUMP
|
./wasm-sourcemap.py $OUTPUTDIR/veilid_wasm_bg.wasm -o $OUTPUTDIR/veilid_wasm_bg.wasm.map --dwarfdump $DWARFDUMP
|
||||||
# wasm-strip $OUTPUTDIR/veilid_wasm_bg.wasm
|
# wasm-strip $OUTPUTDIR/veilid_wasm_bg.wasm
|
||||||
fi
|
fi
|
||||||
|
Loading…
Reference in New Issue
Block a user