chore: lib-dispatch wasm build (#4307)

* chore: lib-dispatch wasm build

* chore: add wasm crate

* chore: add wasm demo

* chore: fix test
This commit is contained in:
Nathan.fooo
2024-01-06 00:37:26 +08:00
committed by GitHub
parent ecbc2601c4
commit 89370b4a55
11 changed files with 85 additions and 77 deletions

View File

@ -12,9 +12,9 @@ futures-channel = "0.3.26"
futures.workspace = true
futures-util = "0.3.26"
bytes = {version = "1.4", features = ["serde"]}
tokio = { workspace = true, features = ["full"] }
tokio = { workspace = true, features = ["rt", "sync"] }
nanoid = "0.4.0"
thread-id = "3.3.0"
dyn-clone = "1.0"
derivative = "2.2.0"
serde_json = { workspace = true, optional = true }
@ -23,17 +23,24 @@ serde_repr = { workspace = true, optional = true }
validator = "0.16.1"
tracing.workspace = true
parking_lot = "0.12"
#optional crate
bincode = { version = "1.3", optional = true}
protobuf = { workspace = true, optional = true }
getrandom = { version = "0.2", optional = true }
wasm-bindgen = { version = "0.2.89", optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
thread-id = "3.3.0"
[dev-dependencies]
tokio = { workspace = true, features = ["full"] }
tokio = { workspace = true, features = ["rt"] }
futures-util = "0.3.26"
[features]
default = ["use_protobuf", ]
default = ["use_protobuf"]
use_serde = ["bincode", "serde_json", "serde", "serde_repr"]
use_protobuf= ["protobuf"]
single_thread = []
wasm_build = ["getrandom/js", "wasm-bindgen"]
[lib]
crate-type = ["cdylib", "rlib"]

View File

@ -16,51 +16,51 @@ use crate::{
service::{AFPluginServiceFactory, Service},
};
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub trait AFConcurrent {}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
impl<T> AFConcurrent for T where T: ?Sized {}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub trait AFConcurrent: Send + Sync {}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
impl<T> AFConcurrent for T where T: Send + Sync {}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub type AFBoxFuture<'a, T> = futures_core::future::LocalBoxFuture<'a, T>;
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub type AFBoxFuture<'a, T> = futures_core::future::BoxFuture<'a, T>;
pub type AFStateMap = std::sync::Arc<AFPluginStateMap>;
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub(crate) fn downcast_owned<T: 'static>(boxed: AFBox) -> Option<T> {
boxed.downcast().ok().map(|boxed| *boxed)
}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub(crate) fn downcast_owned<T: 'static + Send + Sync>(boxed: AFBox) -> Option<T> {
boxed.downcast().ok().map(|boxed| *boxed)
}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub(crate) type AFBox = Box<dyn Any>;
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub(crate) type AFBox = Box<dyn Any + Send + Sync>;
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub type BoxFutureCallback =
Box<dyn FnOnce(AFPluginEventResponse) -> AFBoxFuture<'static, ()> + 'static>;
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub type BoxFutureCallback =
Box<dyn FnOnce(AFPluginEventResponse) -> AFBoxFuture<'static, ()> + Send + Sync + 'static>;
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub fn af_spawn<T>(future: T) -> tokio::task::JoinHandle<T::Output>
where
T: Future + Send + 'static,
@ -69,7 +69,7 @@ where
tokio::spawn(future)
}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub fn af_spawn<T>(future: T) -> tokio::task::JoinHandle<T::Output>
where
T: Future + Send + 'static,
@ -84,11 +84,7 @@ pub struct AFPluginDispatcher {
}
impl AFPluginDispatcher {
pub fn construct<F>(runtime: Arc<AFPluginRuntime>, module_factory: F) -> AFPluginDispatcher
where
F: FnOnce() -> Vec<AFPlugin>,
{
let plugins = module_factory();
pub fn new(runtime: Arc<AFPluginRuntime>, plugins: Vec<AFPlugin>) -> AFPluginDispatcher {
tracing::trace!("{}", plugin_info(&plugins));
AFPluginDispatcher {
plugins: as_plugin_map(plugins),
@ -206,7 +202,7 @@ impl AFPluginDispatcher {
}
}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub fn sync_send(
dispatch: Arc<AFPluginDispatcher>,
request: AFPluginRequest,
@ -218,7 +214,7 @@ impl AFPluginDispatcher {
))
}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
#[track_caller]
pub fn spawn<F>(&self, future: F) -> tokio::task::JoinHandle<F::Output>
where
@ -227,7 +223,7 @@ impl AFPluginDispatcher {
self.runtime.spawn(future)
}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
#[track_caller]
pub fn spawn<F>(&self, future: F) -> tokio::task::JoinHandle<F::Output>
where
@ -237,7 +233,7 @@ impl AFPluginDispatcher {
self.runtime.spawn(future)
}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub async fn run_until<F>(&self, future: F) -> F::Output
where
F: Future + 'static,
@ -246,7 +242,7 @@ impl AFPluginDispatcher {
self.runtime.run_until(handle).await.unwrap()
}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub async fn run_until<'a, F>(&self, future: F) -> F::Output
where
F: Future + Send + 'a,

View File

@ -8,7 +8,7 @@ use tokio::task::JoinHandle;
pub struct AFPluginRuntime {
inner: Runtime,
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
local: tokio::task::LocalSet,
}
@ -27,12 +27,12 @@ impl AFPluginRuntime {
let inner = default_tokio_runtime()?;
Ok(Self {
inner,
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
local: tokio::task::LocalSet::new(),
})
}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
#[track_caller]
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
where
@ -41,7 +41,7 @@ impl AFPluginRuntime {
self.local.spawn_local(future)
}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
#[track_caller]
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
where
@ -51,7 +51,7 @@ impl AFPluginRuntime {
self.inner.spawn(future)
}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub async fn run_until<F>(&self, future: F) -> F::Output
where
F: Future,
@ -59,7 +59,7 @@ impl AFPluginRuntime {
self.local.run_until(future).await
}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub async fn run_until<F>(&self, future: F) -> F::Output
where
F: Future,
@ -67,7 +67,7 @@ impl AFPluginRuntime {
future.await
}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
#[track_caller]
pub fn block_on<F>(&self, f: F) -> F::Output
where
@ -76,7 +76,7 @@ impl AFPluginRuntime {
self.local.block_on(&self.inner, f)
}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
#[track_caller]
pub fn block_on<F>(&self, f: F) -> F::Output
where
@ -86,16 +86,14 @@ impl AFPluginRuntime {
}
}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub fn default_tokio_runtime() -> io::Result<Runtime> {
runtime::Builder::new_current_thread()
.thread_name("dispatch-rt-st")
.enable_io()
.enable_time()
.build()
}
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub fn default_tokio_runtime() -> io::Result<Runtime> {
runtime::Builder::new_multi_thread()
.thread_name("dispatch-rt-mt")

View File

@ -16,7 +16,7 @@ where
BoxServiceFactory(Box::new(FactoryWrapper(factory)))
}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
type Inner<Cfg, Req, Res, Err> = Box<
dyn AFPluginServiceFactory<
Req,
@ -27,7 +27,7 @@ type Inner<Cfg, Req, Res, Err> = Box<
Future = AFBoxFuture<'static, Result<BoxService<Req, Res, Err>, Err>>,
>,
>;
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
type Inner<Cfg, Req, Res, Err> = Box<
dyn AFPluginServiceFactory<
Req,
@ -58,12 +58,12 @@ where
}
}
#[cfg(feature = "single_thread")]
#[cfg(feature = "wasm_build")]
pub type BoxService<Req, Res, Err> = Box<
dyn Service<Req, Response = Res, Error = Err, Future = AFBoxFuture<'static, Result<Res, Err>>>,
>;
#[cfg(not(feature = "single_thread"))]
#[cfg(not(feature = "wasm_build"))]
pub type BoxService<Req, Res, Err> = Box<
dyn Service<Req, Response = Res, Error = Err, Future = AFBoxFuture<'static, Result<Res, Err>>>
+ Sync

View File

@ -11,9 +11,10 @@ pub async fn hello() -> String {
async fn test() {
let event = "1";
let runtime = Arc::new(AFPluginRuntime::new().unwrap());
let dispatch = Arc::new(AFPluginDispatcher::construct(runtime, || {
vec![AFPlugin::new().event(event, hello)]
}));
let dispatch = Arc::new(AFPluginDispatcher::new(
runtime,
vec![AFPlugin::new().event(event, hello)],
));
let request = AFPluginRequest::new(event);
let _ = AFPluginDispatcher::async_send_with_callback(dispatch.clone(), request, |resp| {
Box::pin(async move {