|
@@ -1,20 +1,3 @@
|
|
|
-use crate::{
|
|
|
- data::container::DataContainer,
|
|
|
- error::SystemError,
|
|
|
- module::ModuleData,
|
|
|
- request::FromRequest,
|
|
|
- response::Responder,
|
|
|
- service::{BoxService, Handler, Service, ServiceFactory, ServiceRequest, ServiceResponse},
|
|
|
-};
|
|
|
-
|
|
|
-use crate::{
|
|
|
- error::InternalError,
|
|
|
- request::{payload::Payload, EventRequest},
|
|
|
- response::EventResponse,
|
|
|
- service::{factory, BoxServiceFactory, HandlerService},
|
|
|
-};
|
|
|
-use futures_core::{future::LocalBoxFuture, ready};
|
|
|
-use pin_project::pin_project;
|
|
|
use std::{
|
|
|
collections::HashMap,
|
|
|
fmt::{Debug, Display},
|
|
@@ -24,8 +7,29 @@ use std::{
|
|
|
rc::Rc,
|
|
|
task::{Context, Poll},
|
|
|
};
|
|
|
+
|
|
|
+use futures_core::{future::LocalBoxFuture, ready};
|
|
|
+use pin_project::pin_project;
|
|
|
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
|
|
|
|
|
|
+use crate::{
|
|
|
+ error::{InternalError, SystemError},
|
|
|
+ module::{container::DataContainer, ModuleData},
|
|
|
+ request::{payload::Payload, EventRequest, FromRequest},
|
|
|
+ response::{EventResponse, Responder},
|
|
|
+ service::{
|
|
|
+ factory,
|
|
|
+ BoxService,
|
|
|
+ BoxServiceFactory,
|
|
|
+ Handler,
|
|
|
+ HandlerService,
|
|
|
+ Service,
|
|
|
+ ServiceFactory,
|
|
|
+ ServiceRequest,
|
|
|
+ ServiceResponse,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
|
|
|
pub struct Event(String);
|
|
|
|
|
@@ -39,13 +43,13 @@ pub struct Module {
|
|
|
name: String,
|
|
|
data: DataContainer,
|
|
|
service_map: Rc<HashMap<Event, EventServiceFactory>>,
|
|
|
- req_tx: UnboundedSender<EventRequest>,
|
|
|
- req_rx: UnboundedReceiver<EventRequest>,
|
|
|
+ req_tx: UnboundedSender<ModuleRequest>,
|
|
|
+ req_rx: UnboundedReceiver<ModuleRequest>,
|
|
|
}
|
|
|
|
|
|
impl Module {
|
|
|
pub fn new() -> Self {
|
|
|
- let (req_tx, req_rx) = unbounded_channel::<EventRequest>();
|
|
|
+ let (req_tx, req_rx) = unbounded_channel::<ModuleRequest>();
|
|
|
Self {
|
|
|
name: "".to_owned(),
|
|
|
data: DataContainer::new(),
|
|
@@ -84,22 +88,10 @@ impl Module {
|
|
|
self
|
|
|
}
|
|
|
|
|
|
- pub fn req_tx(&self) -> UnboundedSender<EventRequest> { self.req_tx.clone() }
|
|
|
-
|
|
|
- pub fn handle(&self, request: EventRequest) {
|
|
|
- log::debug!("Module: {} receive request: {:?}", self.name, request);
|
|
|
- match self.req_tx.send(request) {
|
|
|
- Ok(_) => {},
|
|
|
- Err(e) => {
|
|
|
- log::error!("Module: {} with error: {:?}", self.name, e);
|
|
|
- },
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pub fn forward_map(&self) -> HashMap<Event, UnboundedSender<EventRequest>> {
|
|
|
+ pub fn forward_map(&self) -> HashMap<Event, UnboundedSender<ModuleRequest>> {
|
|
|
self.service_map
|
|
|
.keys()
|
|
|
- .map(|key| (key.clone(), self.req_tx()))
|
|
|
+ .map(|key| (key.clone(), self.req_tx.clone()))
|
|
|
.collect::<HashMap<_, _>>()
|
|
|
}
|
|
|
|
|
@@ -113,9 +105,9 @@ impl Future for Module {
|
|
|
match ready!(Pin::new(&mut self.req_rx).poll_recv(cx)) {
|
|
|
None => return Poll::Ready(()),
|
|
|
Some(request) => {
|
|
|
- let mut service = self.new_service(request.get_id().to_string());
|
|
|
+ let mut service = self.new_service(());
|
|
|
if let Ok(service) = ready!(Pin::new(&mut service).poll(cx)) {
|
|
|
- log::trace!("Spawn module service for request {}", request.get_id());
|
|
|
+ log::trace!("Spawn module service for request {}", request.id());
|
|
|
tokio::task::spawn_local(async move {
|
|
|
let _ = service.call(request).await;
|
|
|
});
|
|
@@ -126,15 +118,45 @@ impl Future for Module {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl ServiceFactory<EventRequest> for Module {
|
|
|
+#[derive(Debug)]
|
|
|
+pub struct ModuleRequest {
|
|
|
+ inner: EventRequest,
|
|
|
+ payload: Payload,
|
|
|
+}
|
|
|
+
|
|
|
+impl ModuleRequest {
|
|
|
+ pub fn new<E>(event: E) -> Self
|
|
|
+ where
|
|
|
+ E: Into<Event>,
|
|
|
+ {
|
|
|
+ Self {
|
|
|
+ inner: EventRequest::new(event),
|
|
|
+ payload: Payload::None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn payload(mut self, payload: Payload) -> Self {
|
|
|
+ self.payload = payload;
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ pub(crate) fn into_parts(self) -> (EventRequest, Payload) { (self.inner, self.payload) }
|
|
|
+
|
|
|
+ pub(crate) fn into_service_request(self) -> ServiceRequest { ServiceRequest::new(self.inner, self.payload) }
|
|
|
+
|
|
|
+ pub(crate) fn id(&self) -> &str { &self.inner.id }
|
|
|
+
|
|
|
+ pub(crate) fn event(&self) -> &Event { &self.inner.event }
|
|
|
+}
|
|
|
+
|
|
|
+impl ServiceFactory<ModuleRequest> for Module {
|
|
|
type Response = EventResponse;
|
|
|
type Error = SystemError;
|
|
|
- type Service = BoxService<EventRequest, Self::Response, Self::Error>;
|
|
|
- type Config = String;
|
|
|
+ type Service = BoxService<ModuleRequest, Self::Response, Self::Error>;
|
|
|
+ type Context = ();
|
|
|
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);
|
|
|
+ fn new_service(&self, cfg: Self::Context) -> Self::Future {
|
|
|
let service_map = self.service_map.clone();
|
|
|
Box::pin(async move {
|
|
|
let service = ModuleService { service_map };
|
|
@@ -148,18 +170,22 @@ pub struct ModuleService {
|
|
|
service_map: Rc<HashMap<Event, EventServiceFactory>>,
|
|
|
}
|
|
|
|
|
|
-impl Service<EventRequest> for ModuleService {
|
|
|
+impl Service<ModuleRequest> for ModuleService {
|
|
|
type Response = EventResponse;
|
|
|
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()) {
|
|
|
+ fn call(&self, request: ModuleRequest) -> Self::Future {
|
|
|
+ log::trace!("Call module service for request {}", &request.id());
|
|
|
+ match self.service_map.get(&request.event()) {
|
|
|
Some(factory) => {
|
|
|
+ let service_fut = factory.new_service(());
|
|
|
let fut = ModuleServiceFuture {
|
|
|
- request,
|
|
|
- fut: factory.new_service(()),
|
|
|
+ fut: Box::pin(async {
|
|
|
+ let service = service_fut.await?;
|
|
|
+ let request = request.into_service_request();
|
|
|
+ service.call(request).await
|
|
|
+ }),
|
|
|
};
|
|
|
Box::pin(async move { Ok(fut.await.unwrap_or_else(|e| e.into())) })
|
|
|
},
|
|
@@ -168,13 +194,13 @@ impl Service<EventRequest> for ModuleService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-type BoxModuleService = BoxService<ServiceRequest, ServiceResponse, SystemError>;
|
|
|
+// type BoxModuleService = BoxService<ServiceRequest, ServiceResponse,
|
|
|
+// SystemError>;
|
|
|
|
|
|
#[pin_project]
|
|
|
pub struct ModuleServiceFuture {
|
|
|
- request: EventRequest,
|
|
|
#[pin]
|
|
|
- fut: LocalBoxFuture<'static, Result<BoxModuleService, SystemError>>,
|
|
|
+ fut: LocalBoxFuture<'static, Result<ServiceResponse, SystemError>>,
|
|
|
}
|
|
|
|
|
|
impl Future for ModuleServiceFuture {
|
|
@@ -182,11 +208,8 @@ impl Future for ModuleServiceFuture {
|
|
|
|
|
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
|
loop {
|
|
|
- let service = ready!(self.as_mut().project().fut.poll(cx))?;
|
|
|
- let req = ServiceRequest::new(self.as_mut().request.clone(), Payload::None);
|
|
|
- log::debug!("Call service to handle request {:?}", self.request);
|
|
|
- let (_, resp) = ready!(Pin::new(&mut service.call(req)).poll(cx))?.into_parts();
|
|
|
- return Poll::Ready(Ok(resp));
|
|
|
+ let (_, response) = ready!(self.as_mut().project().fut.poll(cx))?.into_parts();
|
|
|
+ return Poll::Ready(Ok(response));
|
|
|
}
|
|
|
}
|
|
|
}
|