Skip to content

Commit

Permalink
refactor!: backend and MessageEndpoint (#500)
Browse files Browse the repository at this point in the history
    Rename client to provider
    Rename ServerMessage to ServiceMessage
    Add abstract layer of Backend
    Add macro utils to handle js_sys::Function
    Backend should not hold a processor
    Backend should only call APIs via provider which holding function request
    Added extension back
  • Loading branch information
RyanKung authored Dec 9, 2023
1 parent 83dfb92 commit b866f1c
Show file tree
Hide file tree
Showing 36 changed files with 1,111 additions and 389 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ resolver = "2"
members = ["core", "transport", "node", "rpc", "derive"]

[workspace.package]
version = "0.4.1"
version = "0.4.2"
edition = "2021"
license = "GPL-3.0"
authors = ["RND <[email protected]>"]
Expand Down
4 changes: 3 additions & 1 deletion core/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pub const DEFAULT_TTL_MS: u64 = 300 * 1000;
pub const MAX_TTL_MS: u64 = DEFAULT_TTL_MS * 10;
pub const TS_OFFSET_TOLERANCE_MS: u128 = 3000;
pub const DEFAULT_SESSION_TTL_MS: u64 = 30 * 24 * 3600 * 1000;
/// 60k
pub const TRANSPORT_MTU: usize = 60000;
pub const TRANSPORT_MAX_SIZE: usize = TRANSPORT_MTU * 16;
/// 60M
pub const TRANSPORT_MAX_SIZE: usize = TRANSPORT_MTU * 1000;
pub const VNODE_DATA_MAX_LEN: usize = 1024;
8 changes: 1 addition & 7 deletions core/src/dht/did.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,7 @@ impl BiasId {

impl PartialOrd for BiasId {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if other.bias != self.bias {
let did: Did = other.into();
let bid = BiasId::new(self.bias, did);
self.did.partial_cmp(&bid.did)
} else {
self.did.partial_cmp(&other.did)
}
Some(self.cmp(other))
}
}

Expand Down
14 changes: 12 additions & 2 deletions core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ pub enum Error {
#[error("Message decryption failed")]
MessageDecryptionFailed(ecies::SecpError),

#[error("message too large, consider use ChunkList")]
MessageTooLarge,
#[error("Message has {0} bytes which is too large")]
MessageTooLarge(usize),

#[cfg(feature = "wasm")]
#[error("Cannot get property {0} from JsValue")]
Expand All @@ -362,6 +362,9 @@ pub enum Error {

#[error("Transport error: {0}")]
Transport(#[from] rings_transport::error::Error),

#[error("External Javascript error: {0}")]
JsError(String),
}

#[cfg(feature = "wasm")]
Expand All @@ -370,3 +373,10 @@ impl From<Error> for wasm_bindgen::JsValue {
wasm_bindgen::JsValue::from_str(&err.to_string())
}
}

#[cfg(feature = "wasm")]
impl From<js_sys::Error> for Error {
fn from(err: js_sys::Error) -> Self {
Error::JsError(err.to_string().into())
}
}
3 changes: 2 additions & 1 deletion core/src/message/protocols/relay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl MessageRelay {

// Prevent infinite loop
if has_infinite_loop(&self.path) {
tracing::error!("Infinite path detected {:?}", self.path);
return Err(Error::InfiniteRelayPath);
}

Expand Down Expand Up @@ -136,7 +137,7 @@ where T: PartialEq + std::fmt::Debug {
let p2 = path.iter().rev().skip(indexes[1]);
let p3 = path.iter().rev().skip(indexes[2]);

let lens = vec![
let lens = [
indexes[1] - indexes[0],
indexes[2] - indexes[1],
path.len() - indexes[2],
Expand Down
10 changes: 9 additions & 1 deletion core/src/message/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ pub struct SyncVNodeWithSuccessor {
}

/// MessageType use to customize message, will be handle by `custom_message` method.
#[derive(Debug, Deserialize, Serialize, Clone)]
#[derive(Deserialize, Serialize, Clone)]
pub struct CustomMessage(pub Vec<u8>);

/// MessageType enum Report contain FindSuccessorSend.
Expand Down Expand Up @@ -242,3 +242,11 @@ impl Message {
Ok(Message::CustomMessage(CustomMessage(msg.to_vec())))
}
}

impl std::fmt::Debug for CustomMessage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CustomMessage")
.field("size", &self.0.len())
.finish()
}
}
4 changes: 2 additions & 2 deletions core/src/storage/persistence/idb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ where
.filter_map(|(k, v)| {
Some((
K::from_str(k.as_string().unwrap().as_str()).ok()?,
js_value::deserialize::<DataStruct<V>>(&v).unwrap().data,
js_value::deserialize::<DataStruct<V>>(v).unwrap().data,
))
})
.collect::<Vec<(K, V)>>())
Expand Down Expand Up @@ -260,7 +260,7 @@ impl PersistenceStorageOperation for IDBStorage {
tracing::debug!("entries: {:?}", entries);

if let Some((_k, value)) = entries.first() {
let data_entry: DataStruct<serde_json::Value> = js_value::deserialize(&value)?;
let data_entry: DataStruct<serde_json::Value> = js_value::deserialize(value)?;
store
.delete(&JsValue::from(&data_entry.key))
.await
Expand Down
14 changes: 7 additions & 7 deletions core/src/swarm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,10 @@ impl PayloadSender for Swarm {
let data = payload.to_bincode()?;
if data.len() > TRANSPORT_MAX_SIZE {
tracing::error!("Message is too large: {:?}", payload);
return Err(Error::MessageTooLarge);
return Err(Error::MessageTooLarge(data.len()));
}

if data.len() > TRANSPORT_MTU {
let result = if data.len() > TRANSPORT_MTU {
let chunks = ChunkList::<TRANSPORT_MTU>::from(&data);
for chunk in chunks {
let data =
Expand All @@ -358,11 +358,11 @@ impl PayloadSender for Swarm {
conn.send_message(TransportMessage::Custom(data.to_vec()))
.await?;
}
}

let result = conn
.send_message(TransportMessage::Custom(data.to_vec()))
.await;
Ok(())
} else {
conn.send_message(TransportMessage::Custom(data.to_vec()))
.await
};

tracing::debug!(
"Sent {:?}, to node {:?}",
Expand Down
2 changes: 1 addition & 1 deletion core/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::swarm::Swarm;
#[cfg(feature = "wasm")]
pub mod wasm;

#[cfg(all(not(feature = "wasm")))]
#[cfg(not(feature = "wasm"))]
pub mod default;

#[allow(dead_code)]
Expand Down
1 change: 1 addition & 0 deletions core/src/tests/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::swarm::Swarm;
use crate::swarm::SwarmBuilder;

mod test_channel;
mod test_fn_macro;
mod test_ice_servers;
mod test_idb_storage;
mod test_utils;
Expand Down
46 changes: 46 additions & 0 deletions core/src/tests/wasm/test_fn_macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use js_sys::Array;
use js_sys::Function;
use wasm_bindgen::JsValue;
use wasm_bindgen_test::wasm_bindgen_test;

use crate::utils::js_func;

#[wasm_bindgen_test]
async fn test_fn_generator() {
let js_code_args = "a, b, c, d";
let js_code_body = r#"
try {
return new Promise((resolve, reject) => {
const ret = a + b + c + d
if (ret !== "hello world") {
reject(`a: ${a}, b: ${b}, c: ${c}, d: ${d} -> ret: ${ret}`)
} else {
resolve(ret)
}
})
} catch(e) {
return e
}
"#;
let func = Function::new_with_args(js_code_args, js_code_body);
let native_func = js_func::of4::<String, String, String, String>(&func);
let a = "hello".to_string();
let b = " ".to_string();
let c = "world".to_string();
let d = "".to_string();
native_func(a, b, c, d).await.unwrap();
}

#[wasm_bindgen_test]
async fn test_try_into() {
let a = "hello".to_string();
let b = " ".to_string();
let c = "world".to_string();
let p: Vec<JsValue> = vec![
a.try_into().unwrap(),
b.try_into().unwrap(),
c.try_into().unwrap(),
];
let array = Array::from_iter(p.into_iter());
assert_eq!(array.to_vec().len(), 3, "{:?}", array.to_vec());
}
95 changes: 92 additions & 3 deletions core/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,99 @@ pub mod js_value {
}

/// From JsValue to serde
pub fn deserialize<T: DeserializeOwned>(obj: &(impl Into<JsValue> + Clone)) -> Result<T> {
let value: JsValue = (*obj).clone().into();
serde_wasm_bindgen::from_value(value).map_err(Error::SerdeWasmBindgenError)
pub fn deserialize<T: DeserializeOwned>(obj: impl Into<JsValue>) -> Result<T> {
serde_wasm_bindgen::from_value(obj.into()).map_err(Error::SerdeWasmBindgenError)
}
}

#[cfg(feature = "wasm")]
pub mod js_func {
/// This macro will generate a wrapper for mapping a js_sys::Function with type fn(T, T, T, T) -> Promise<()>
/// to native function
/// # Example:
/// For macro calling: of!(of2, a: T0, b: T1);
/// Will generate code:
/// ```rust
/// pub fn of2<'a, 'b: 'a, T0: TryInto<JsValue> + Clone, T1: TryInto<JsValue> + Clone>(
/// func: &Function,
/// ) -> Box<dyn Fn(T0, T1) -> Pin<Box<dyn Future<Output = Result<()>> + 'b>>>
/// where
/// T0: 'b,
/// T1: 'b,
/// T0::Error: Debug,
/// T1::Error: Debug,
/// {
/// let func = func.clone();
/// Box::new(
/// move |a: T0, b: T1| -> Pin<Box<dyn Future<Output = Result<()>>>> {
/// let func = func.clone();
/// Box::pin(async move {
/// let func = func.clone();
/// let params = js_sys::Array::new();
/// let a: JsValue = a
/// .clone()
/// .try_into()
/// .map_err(|_| Error::JsError(format!("{:?}", e)));
/// params.push(&a);
/// let b: JsValue = b
/// .clone()
/// .try_into()
/// .map_err(|_| Error::JsError(format!("{:?}", e)));
/// params.push(&b);
/// JsFuture::from(js_sys::Promise::from(
/// func.apply(&JsValue::NULL, &params).map_err(|e| {
/// Error::JsError(js_sys::Error::from(e).to_string().into())
/// })?,
/// ))
/// .await
/// .map_err(|e| Error::JsError(js_sys::Error::from(e).to_string().into()))?;
/// Ok(())
/// })
/// },
/// )
/// }
/// ```
#[macro_export]
macro_rules! of {
($func: ident, $($name:ident: $type: ident),+$(,)?) => {
pub fn $func<'a, 'b: 'a, $($type: TryInto<wasm_bindgen::JsValue> + Clone),+>(
func: &js_sys::Function,
) -> Box<dyn Fn($($type),+) -> std::pin::Pin<Box<dyn std::future::Future<Output = $crate::error::Result<()>> + 'b>>>
where $($type::Error: std::fmt::Debug),+,
$($type: 'b),+
{
let func = func.clone();
Box::new(
move |$($name: $type,)+| -> std::pin::Pin<Box<dyn std::future::Future<Output = $crate::error::Result<()>>>> {
let func = func.clone();
Box::pin(async move {
let func = func.clone();
let params = js_sys::Array::new();
$(
let $name: wasm_bindgen::JsValue = $name.clone().try_into().map_err(|e| $crate::error::Error::JsError(format!("{:?}", e)))?;
params.push(&$name);
)+
wasm_bindgen_futures::JsFuture::from(js_sys::Promise::from(
func.apply(
&wasm_bindgen::JsValue::NULL,
&params
)
.map_err(|e| $crate::error::Error::from(js_sys::Error::from(e)))?,
))
.await
.map_err(|e| $crate::error::Error::from(js_sys::Error::from(e)))?;
Ok(())
})
},
)
}
}
}

of!(of1, a: T0);
of!(of2, a: T0, b: T1);
of!(of3, a: T0, b: T1, c: T2);
of!(of4, a: T0, b: T1, c: T2, d: T3);
}

#[cfg(feature = "wasm")]
Expand Down
10 changes: 5 additions & 5 deletions examples/ffi/rings.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,22 @@ def on_inbound(payload):
return


def create_client(rings_node, acc):
def create_provider(rings_node, acc):
callback = rings_node.new_callback(on_inbound)
client = rings_node.new_client_with_callback(
provider = rings_node.new_provider_with_callback(
"stun://stun.l.google.com".encode(),
10,
acc.address.encode(),
"eip191".encode(),
signer,
ffi.addressof(callback),
)
return client
return provider


if __name__ == "__main__":
rings_node = ffi.dlopen(f"./target/debug/librings_node.{extension}")
rings_node.init_logging(rings_node.Debug)

client = create_client(rings_node, acc)
print(client)
provider = create_provider(rings_node, acc)
print(provider)
Loading

0 comments on commit b866f1c

Please sign in to comment.