mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
module as service
This commit is contained in:
parent
331115aa63
commit
6d2d24baf7
@ -20,7 +20,16 @@ env_logger = "0.8"
|
|||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_with = "1.9.4"
|
serde_with = "1.9.4"
|
||||||
|
thread-id = "3.3.0"
|
||||||
|
|
||||||
|
#optional crate
|
||||||
|
allo-isolate = {version = "^0.1", features = ["catch-unwind",], optional = true}
|
||||||
|
byteorder = {version = "1.3.4", optional = true}
|
||||||
|
ffi-support = {version = "0.4.2", optional = true}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
futures-util = "0.3.15"
|
futures-util = "0.3.15"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
dart_ffi = ["ffi-support", "allo-isolate", "byteorder"]
|
34
rust-lib/flowy-sys/src/dart_ffi/ffi.rs
Normal file
34
rust-lib/flowy-sys/src/dart_ffi/ffi.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use crate::{response::EventResponse, rt::SystemCommand};
|
||||||
|
use futures_core::ready;
|
||||||
|
use std::{future::Future, task::Context};
|
||||||
|
use tokio::{
|
||||||
|
macros::support::{Pin, Poll},
|
||||||
|
sync::{mpsc::UnboundedReceiver, oneshot},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn free_rust(ptr: *mut u8, length: u32) { reclaim_rust(ptr, length) }
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn init_stream(port: i64) -> i32 { return 0; }
|
||||||
|
|
||||||
|
struct SystemFFI {
|
||||||
|
resp_rx: UnboundedReceiver<EventResponse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Future for SystemFFI {
|
||||||
|
type Output = ();
|
||||||
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
loop {
|
||||||
|
match ready!(Pin::new(&mut self.resp_rx).poll_recv(cx)) {
|
||||||
|
None => return Poll::Ready(()),
|
||||||
|
Some(resp) => {
|
||||||
|
log::trace!("Response: {:?}", resp);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
rust-lib/flowy-sys/src/dart_ffi/mod.rs
Normal file
2
rust-lib/flowy-sys/src/dart_ffi/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#[cfg(feature = "dart_ffi")]
|
||||||
|
mod ffi;
|
@ -9,6 +9,9 @@ mod rt;
|
|||||||
mod service;
|
mod service;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
#[cfg(feature = "dart_ffi")]
|
||||||
|
mod dart_ffi;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::{error::*, module::*, request::*, response::*, rt::*};
|
pub use crate::{error::*, module::*, request::*, response::*, rt::*};
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
error::InternalError,
|
||||||
request::{payload::Payload, EventRequest},
|
request::{payload::Payload, EventRequest},
|
||||||
response::EventResponse,
|
response::{EventResponse, EventResponseBuilder},
|
||||||
|
rt::SystemCommand,
|
||||||
service::{factory, BoxServiceFactory, HandlerService},
|
service::{factory, BoxServiceFactory, HandlerService},
|
||||||
};
|
};
|
||||||
use futures_core::{future::LocalBoxFuture, ready};
|
use futures_core::{future::LocalBoxFuture, ready};
|
||||||
@ -18,6 +20,7 @@ use std::{
|
|||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
future::Future,
|
future::Future,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
|
rc::Rc,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
|
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
|
||||||
@ -28,22 +31,22 @@ pub type EventServiceFactory = BoxServiceFactory<(), ServiceRequest, ServiceResp
|
|||||||
pub struct Module {
|
pub struct Module {
|
||||||
name: String,
|
name: String,
|
||||||
data: DataContainer,
|
data: DataContainer,
|
||||||
service_map: HashMap<Event, EventServiceFactory>,
|
service_map: Rc<HashMap<Event, EventServiceFactory>>,
|
||||||
req_tx: UnboundedSender<EventRequest>,
|
req_tx: UnboundedSender<EventRequest>,
|
||||||
req_rx: UnboundedReceiver<EventRequest>,
|
req_rx: UnboundedReceiver<EventRequest>,
|
||||||
resp_tx: UnboundedSender<EventResponse>,
|
sys_tx: UnboundedSender<SystemCommand>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Module {
|
impl Module {
|
||||||
pub fn new(resp_tx: UnboundedSender<EventResponse>) -> Self {
|
pub fn new(sys_tx: UnboundedSender<SystemCommand>) -> Self {
|
||||||
let (req_tx, req_rx) = unbounded_channel::<EventRequest>();
|
let (req_tx, req_rx) = unbounded_channel::<EventRequest>();
|
||||||
Self {
|
Self {
|
||||||
name: "".to_owned(),
|
name: "".to_owned(),
|
||||||
data: DataContainer::new(),
|
data: DataContainer::new(),
|
||||||
service_map: HashMap::new(),
|
service_map: Rc::new(HashMap::new()),
|
||||||
req_tx,
|
req_tx,
|
||||||
req_rx,
|
req_rx,
|
||||||
resp_tx,
|
sys_tx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,14 +71,16 @@ impl Module {
|
|||||||
log::error!("Duplicate Event: {}", &event);
|
log::error!("Duplicate Event: {}", &event);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.service_map.insert(event, factory(HandlerService::new(handler)));
|
Rc::get_mut(&mut self.service_map)
|
||||||
|
.unwrap()
|
||||||
|
.insert(event, factory(HandlerService::new(handler)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn req_tx(&self) -> UnboundedSender<EventRequest> { self.req_tx.clone() }
|
pub fn req_tx(&self) -> UnboundedSender<EventRequest> { self.req_tx.clone() }
|
||||||
|
|
||||||
pub fn handle(&self, request: EventRequest) {
|
pub fn handle(&self, request: EventRequest) {
|
||||||
log::trace!("Module: {} receive request: {:?}", self.name, request);
|
log::debug!("Module: {} receive request: {:?}", self.name, request);
|
||||||
match self.req_tx.send(request) {
|
match self.req_tx.send(request) {
|
||||||
Ok(_) => {},
|
Ok(_) => {},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -98,30 +103,72 @@ impl Future for Module {
|
|||||||
loop {
|
loop {
|
||||||
match ready!(Pin::new(&mut self.req_rx).poll_recv(cx)) {
|
match ready!(Pin::new(&mut self.req_rx).poll_recv(cx)) {
|
||||||
None => return Poll::Ready(()),
|
None => return Poll::Ready(()),
|
||||||
Some(request) => match self.service_map.get(request.get_event()) {
|
Some(request) => {
|
||||||
Some(factory) => {
|
let mut service = self.new_service(request.get_id().to_string());
|
||||||
let fut = ModuleServiceFuture {
|
if let Ok(service) = ready!(Pin::new(&mut service).poll(cx)) {
|
||||||
request,
|
log::trace!("Spawn module service for request {}", request.get_id());
|
||||||
fut: factory.new_service(()),
|
|
||||||
};
|
|
||||||
let resp_tx = self.resp_tx.clone();
|
|
||||||
tokio::task::spawn_local(async move {
|
tokio::task::spawn_local(async move {
|
||||||
let resp = fut.await.unwrap_or_else(|_e| panic!());
|
let _ = service.call(request).await;
|
||||||
if let Err(e) = resp_tx.send(resp) {
|
|
||||||
log::error!("{:?}", e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
None => {
|
|
||||||
log::error!("Event: {} handler not found", request.get_event());
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ServiceFactory<EventRequest> for Module {
|
||||||
|
type Response = ();
|
||||||
|
type Error = SystemError;
|
||||||
|
type Service = BoxService<EventRequest, Self::Response, Self::Error>;
|
||||||
|
type Config = String;
|
||||||
|
type Future = LocalBoxFuture<'static, Result<Self::Service, Self::Error>>;
|
||||||
|
|
||||||
|
fn new_service(&self, cfg: Self::Config) -> Self::Future {
|
||||||
|
log::trace!("Create module service for request {}", cfg);
|
||||||
|
let sys_tx = self.sys_tx.clone();
|
||||||
|
let service_map = self.service_map.clone();
|
||||||
|
Box::pin(async move {
|
||||||
|
let service = ModuleService { service_map, sys_tx };
|
||||||
|
let module_service = Box::new(service) as Self::Service;
|
||||||
|
Ok(module_service)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ModuleService {
|
||||||
|
service_map: Rc<HashMap<Event, EventServiceFactory>>,
|
||||||
|
sys_tx: UnboundedSender<SystemCommand>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Service<EventRequest> for ModuleService {
|
||||||
|
type Response = ();
|
||||||
|
type Error = SystemError;
|
||||||
|
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||||
|
|
||||||
|
fn call(&self, request: EventRequest) -> Self::Future {
|
||||||
|
log::trace!("Call module service for request {}", request.get_id());
|
||||||
|
match self.service_map.get(request.get_event()) {
|
||||||
|
Some(factory) => {
|
||||||
|
let fut = ModuleServiceFuture {
|
||||||
|
request,
|
||||||
|
fut: factory.new_service(()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let sys_tx = self.sys_tx.clone();
|
||||||
|
Box::pin(async move {
|
||||||
|
let resp = fut.await.unwrap_or_else(|e| e.into());
|
||||||
|
sys_tx.send(SystemCommand::EventResponse(resp));
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
None => Box::pin(async { Err(InternalError::new("".to_string()).into()) }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type BoxModuleService = BoxService<ServiceRequest, ServiceResponse, SystemError>;
|
type BoxModuleService = BoxService<ServiceRequest, ServiceResponse, SystemError>;
|
||||||
|
|
||||||
#[pin_project]
|
#[pin_project]
|
||||||
pub struct ModuleServiceFuture {
|
pub struct ModuleServiceFuture {
|
||||||
request: EventRequest,
|
request: EventRequest,
|
||||||
@ -136,7 +183,7 @@ impl Future for ModuleServiceFuture {
|
|||||||
loop {
|
loop {
|
||||||
let service = ready!(self.as_mut().project().fut.poll(cx))?;
|
let service = ready!(self.as_mut().project().fut.poll(cx))?;
|
||||||
let req = ServiceRequest::new(self.as_mut().request.clone(), Payload::None);
|
let req = ServiceRequest::new(self.as_mut().request.clone(), Payload::None);
|
||||||
log::trace!("Call service to handle request {:?}", self.request);
|
log::debug!("Call service to handle request {:?}", self.request);
|
||||||
let (_, resp) = ready!(Pin::new(&mut service.call(req)).poll(cx))?.into_parts();
|
let (_, resp) = ready!(Pin::new(&mut service.call(req)).poll(cx))?.into_parts();
|
||||||
return Poll::Ready(Ok(resp));
|
return Poll::Ready(Ok(resp));
|
||||||
}
|
}
|
||||||
@ -149,24 +196,22 @@ mod tests {
|
|||||||
use crate::rt::Runtime;
|
use crate::rt::Runtime;
|
||||||
use futures_util::{future, pin_mut};
|
use futures_util::{future, pin_mut};
|
||||||
use tokio::sync::mpsc::unbounded_channel;
|
use tokio::sync::mpsc::unbounded_channel;
|
||||||
|
|
||||||
pub async fn hello_service() -> String { "hello".to_string() }
|
pub async fn hello_service() -> String { "hello".to_string() }
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
let mut runtime = Runtime::new().unwrap();
|
let mut runtime = Runtime::new().unwrap();
|
||||||
runtime.block_on(async {
|
runtime.block_on(async {
|
||||||
let (resp_tx, mut resp_rx) = unbounded_channel::<EventResponse>();
|
let (sys_tx, mut sys_rx) = unbounded_channel::<SystemCommand>();
|
||||||
let event = "hello".to_string();
|
let event = "hello".to_string();
|
||||||
let mut module = Module::new(resp_tx).event(event.clone(), hello_service);
|
let mut module = Module::new(sys_tx).event(event.clone(), hello_service);
|
||||||
let req_tx = module.req_tx();
|
let req_tx = module.req_tx();
|
||||||
let mut event = async move {
|
let mut event = async move {
|
||||||
let request = EventRequest::new(event.clone());
|
let request = EventRequest::new(event.clone());
|
||||||
req_tx.send(request).unwrap();
|
req_tx.send(request).unwrap();
|
||||||
|
|
||||||
match resp_rx.recv().await {
|
match sys_rx.recv().await {
|
||||||
Some(resp) => {
|
Some(cmd) => {
|
||||||
log::info!("{}", resp);
|
log::info!("{:?}", cmd);
|
||||||
},
|
},
|
||||||
None => panic!(""),
|
None => panic!(""),
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ impl EventRequest {
|
|||||||
|
|
||||||
impl EventRequest {
|
impl EventRequest {
|
||||||
pub fn get_event(&self) -> &str { &self.event }
|
pub fn get_event(&self) -> &str { &self.event }
|
||||||
|
pub fn get_id(&self) -> &str { &self.id }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FromRequest: Sized {
|
pub trait FromRequest: Sized {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::{future::Future, io};
|
use std::{future::Future, io, thread};
|
||||||
|
use thread_id;
|
||||||
use tokio::{runtime, task::LocalSet};
|
use tokio::{runtime, task::LocalSet};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -9,7 +10,25 @@ pub struct Runtime {
|
|||||||
|
|
||||||
impl Runtime {
|
impl Runtime {
|
||||||
pub fn new() -> io::Result<Runtime> {
|
pub fn new() -> io::Result<Runtime> {
|
||||||
let rt = runtime::Builder::new_multi_thread().enable_io().enable_time().build()?;
|
let rt = runtime::Builder::new_multi_thread()
|
||||||
|
.thread_name("flowy-sys")
|
||||||
|
.enable_io()
|
||||||
|
.enable_time()
|
||||||
|
.on_thread_start(move || {
|
||||||
|
log::trace!(
|
||||||
|
"{:?} thread started: thread_id= {}",
|
||||||
|
thread::current(),
|
||||||
|
thread_id::get()
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.on_thread_stop(move || {
|
||||||
|
log::trace!(
|
||||||
|
"{:?} thread stopping: thread_id= {}",
|
||||||
|
thread::current(),
|
||||||
|
thread_id::get(),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.build()?;
|
||||||
|
|
||||||
Ok(Runtime {
|
Ok(Runtime {
|
||||||
rt,
|
rt,
|
||||||
|
@ -20,8 +20,10 @@ thread_local!(
|
|||||||
static CURRENT: RefCell<Option<Arc<FlowySystem>>> = RefCell::new(None);
|
static CURRENT: RefCell<Option<Arc<FlowySystem>>> = RefCell::new(None);
|
||||||
);
|
);
|
||||||
|
|
||||||
enum SystemCommand {
|
#[derive(Debug)]
|
||||||
|
pub enum SystemCommand {
|
||||||
Exit(i8),
|
Exit(i8),
|
||||||
|
EventResponse(EventResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FlowySystem {
|
pub struct FlowySystem {
|
||||||
@ -30,28 +32,26 @@ pub struct FlowySystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FlowySystem {
|
impl FlowySystem {
|
||||||
pub fn construct<F>(module_factory: F) -> SystemRunner
|
pub fn construct<F>(module_factory: F, response_tx: Option<UnboundedSender<EventResponse>>) -> SystemRunner
|
||||||
where
|
where
|
||||||
F: FnOnce(UnboundedSender<EventResponse>) -> Vec<Module>,
|
F: FnOnce(UnboundedSender<SystemCommand>) -> Vec<Module>,
|
||||||
{
|
{
|
||||||
let runtime = Runtime::new().unwrap();
|
let runtime = Runtime::new().unwrap();
|
||||||
let (resp_tx, resp_rx) = unbounded_channel::<EventResponse>();
|
|
||||||
|
|
||||||
let (sys_tx, sys_rx) = unbounded_channel::<SystemCommand>();
|
let (sys_tx, sys_rx) = unbounded_channel::<SystemCommand>();
|
||||||
let (stop_tx, stop_rx) = oneshot::channel();
|
let (stop_tx, stop_rx) = oneshot::channel();
|
||||||
|
|
||||||
runtime.spawn(SystemFFI { resp_rx });
|
|
||||||
runtime.spawn(SystemController {
|
runtime.spawn(SystemController {
|
||||||
stop_tx: Some(stop_tx),
|
stop_tx: Some(stop_tx),
|
||||||
sys_rx,
|
sys_rx,
|
||||||
|
response_tx,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut system = Self {
|
let mut system = Self {
|
||||||
sys_tx,
|
sys_tx: sys_tx.clone(),
|
||||||
forward_map: HashMap::default(),
|
forward_map: HashMap::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let factory = module_factory(resp_tx.clone());
|
let factory = module_factory(sys_tx.clone());
|
||||||
factory.into_iter().for_each(|m| {
|
factory.into_iter().for_each(|m| {
|
||||||
system.forward_map.extend(m.forward_map());
|
system.forward_map.extend(m.forward_map());
|
||||||
runtime.spawn(m);
|
runtime.spawn(m);
|
||||||
@ -63,11 +63,18 @@ impl FlowySystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sink(&self, event: Event, request: EventRequest) -> Result<(), SystemError> {
|
pub fn sink(&self, event: Event, request: EventRequest) -> Result<(), SystemError> {
|
||||||
log::trace!("Sink event: {}", event);
|
log::debug!("Sink event: {}", event);
|
||||||
let _ = self.forward_map.get(&event)?.send(request)?;
|
let _ = self.forward_map.get(&event)?.send(request)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn request_tx(&self, event: Event) -> Option<UnboundedSender<EventRequest>> {
|
||||||
|
match self.forward_map.get(&event) {
|
||||||
|
Some(tx) => Some(tx.clone()),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stop(&self) {
|
pub fn stop(&self) {
|
||||||
match self.sys_tx.send(SystemCommand::Exit(0)) {
|
match self.sys_tx.send(SystemCommand::Exit(0)) {
|
||||||
Ok(_) => {},
|
Ok(_) => {},
|
||||||
@ -92,27 +99,10 @@ impl FlowySystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SystemFFI {
|
|
||||||
resp_rx: UnboundedReceiver<EventResponse>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Future for SystemFFI {
|
|
||||||
type Output = ();
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
loop {
|
|
||||||
match ready!(Pin::new(&mut self.resp_rx).poll_recv(cx)) {
|
|
||||||
None => return Poll::Ready(()),
|
|
||||||
Some(resp) => {
|
|
||||||
log::trace!("Response: {:?}", resp);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SystemController {
|
struct SystemController {
|
||||||
stop_tx: Option<oneshot::Sender<i8>>,
|
stop_tx: Option<oneshot::Sender<i8>>,
|
||||||
sys_rx: UnboundedReceiver<SystemCommand>,
|
sys_rx: UnboundedReceiver<SystemCommand>,
|
||||||
|
response_tx: Option<UnboundedSender<EventResponse>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Future for SystemController {
|
impl Future for SystemController {
|
||||||
@ -127,6 +117,17 @@ impl Future for SystemController {
|
|||||||
let _ = tx.send(code);
|
let _ = tx.send(code);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
SystemCommand::EventResponse(resp) => {
|
||||||
|
log::debug!("Response: {:?}", resp);
|
||||||
|
if let Some(tx) = &self.response_tx {
|
||||||
|
match tx.send(resp) {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Response tx send fail: {:?}", e);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,17 @@ where
|
|||||||
BoxServiceFactory(Box::new(FactoryWrapper(factory)))
|
BoxServiceFactory(Box::new(FactoryWrapper(factory)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Inner<Cfg, Req, Res, Err> = Box<
|
||||||
|
dyn ServiceFactory<
|
||||||
|
Req,
|
||||||
|
Config = Cfg,
|
||||||
|
Response = Res,
|
||||||
|
Error = Err,
|
||||||
|
Service = BoxService<Req, Res, Err>,
|
||||||
|
Future = LocalBoxFuture<'static, Result<BoxService<Req, Res, Err>, Err>>,
|
||||||
|
>,
|
||||||
|
>;
|
||||||
|
|
||||||
pub struct BoxServiceFactory<Cfg, Req, Res, Err>(Inner<Cfg, Req, Res, Err>);
|
pub struct BoxServiceFactory<Cfg, Req, Res, Err>(Inner<Cfg, Req, Res, Err>);
|
||||||
impl<Cfg, Req, Res, Err> ServiceFactory<Req> for BoxServiceFactory<Cfg, Req, Res, Err>
|
impl<Cfg, Req, Res, Err> ServiceFactory<Req> for BoxServiceFactory<Cfg, Req, Res, Err>
|
||||||
where
|
where
|
||||||
@ -29,17 +40,6 @@ where
|
|||||||
fn new_service(&self, cfg: Cfg) -> Self::Future { self.0.new_service(cfg) }
|
fn new_service(&self, cfg: Cfg) -> Self::Future { self.0.new_service(cfg) }
|
||||||
}
|
}
|
||||||
|
|
||||||
type Inner<Cfg, Req, Res, Err> = Box<
|
|
||||||
dyn ServiceFactory<
|
|
||||||
Req,
|
|
||||||
Config = Cfg,
|
|
||||||
Response = Res,
|
|
||||||
Error = Err,
|
|
||||||
Service = BoxService<Req, Res, Err>,
|
|
||||||
Future = LocalBoxFuture<'static, Result<BoxService<Req, Res, Err>, Err>>,
|
|
||||||
>,
|
|
||||||
>;
|
|
||||||
|
|
||||||
pub type BoxService<Req, Res, Err> =
|
pub type BoxService<Req, Res, Err> =
|
||||||
Box<dyn Service<Req, Response = Res, Error = Err, Future = LocalBoxFuture<'static, Result<Res, Err>>>>;
|
Box<dyn Service<Req, Response = Res, Error = Err, Future = LocalBoxFuture<'static, Result<Res, Err>>>>;
|
||||||
|
|
||||||
|
@ -12,12 +12,15 @@ fn test() {
|
|||||||
let no_params_command = "no params".to_string();
|
let no_params_command = "no params".to_string();
|
||||||
let one_params_command = "one params".to_string();
|
let one_params_command = "one params".to_string();
|
||||||
let two_params_command = "two params".to_string();
|
let two_params_command = "two params".to_string();
|
||||||
FlowySystem::construct(|tx| {
|
FlowySystem::construct(
|
||||||
vec![Module::new(tx.clone())
|
|tx| {
|
||||||
.event(no_params_command.clone(), no_params)
|
vec![Module::new(tx.clone())
|
||||||
.event(one_params_command.clone(), one_params)
|
.event(no_params_command.clone(), no_params)
|
||||||
.event(two_params_command.clone(), two_params)]
|
.event(one_params_command.clone(), one_params)
|
||||||
})
|
.event(two_params_command.clone(), two_params)]
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
.spawn(async {
|
.spawn(async {
|
||||||
let request = EventRequest::new(no_params_command.clone());
|
let request = EventRequest::new(no_params_command.clone());
|
||||||
FlowySystem::current().sink(no_params_command, request);
|
FlowySystem::current().sink(no_params_command, request);
|
||||||
|
Loading…
Reference in New Issue
Block a user