refactor: rename flowy-dispatch structs

This commit is contained in:
nathan
2022-12-01 08:35:50 +08:00
parent fff4af53e2
commit 96c427e869
35 changed files with 486 additions and 543 deletions

View File

@ -39,12 +39,12 @@ where
// From bytes
pub trait FromBytes: Sized {
pub trait AFPluginFromBytes: Sized {
fn parse_from_bytes(bytes: Bytes) -> Result<Self, DispatchError>;
}
#[cfg(feature = "use_protobuf")]
impl<T> FromBytes for T
impl<T> AFPluginFromBytes for T
where
// // https://stackoverflow.com/questions/62871045/tryfromu8-trait-bound-in-trait
// T: for<'a> std::convert::TryFrom<&'a Bytes, Error =
@ -67,7 +67,7 @@ where
}
#[cfg(feature = "use_serde")]
impl<T> FromBytes for T
impl<T> AFPluginFromBytes for T
where
T: serde::de::DeserializeOwned + 'static,
{

View File

@ -1,22 +1,22 @@
use crate::{
byte_trait::*,
errors::{DispatchError, InternalError},
request::{unexpected_none_payload, EventRequest, FromRequest, Payload},
response::{EventResponse, Responder, ResponseBuilder},
request::{unexpected_none_payload, AFPluginEventRequest, FromAFPluginRequest, Payload},
response::{AFPluginResponder, EventResponse, ResponseBuilder},
util::ready::{ready, Ready},
};
use bytes::Bytes;
use std::ops;
pub struct Data<T>(pub T);
pub struct AFPluginData<T>(pub T);
impl<T> Data<T> {
impl<T> AFPluginData<T> {
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> ops::Deref for Data<T> {
impl<T> ops::Deref for AFPluginData<T> {
type Target = T;
fn deref(&self) -> &T {
@ -24,36 +24,36 @@ impl<T> ops::Deref for Data<T> {
}
}
impl<T> ops::DerefMut for Data<T> {
impl<T> ops::DerefMut for AFPluginData<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> FromRequest for Data<T>
impl<T> FromAFPluginRequest for AFPluginData<T>
where
T: FromBytes + 'static,
T: AFPluginFromBytes + 'static,
{
type Error = DispatchError;
type Future = Ready<Result<Self, DispatchError>>;
#[inline]
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
fn from_request(req: &AFPluginEventRequest, payload: &mut Payload) -> Self::Future {
match payload {
Payload::None => ready(Err(unexpected_none_payload(req))),
Payload::Bytes(bytes) => match T::parse_from_bytes(bytes.clone()) {
Ok(data) => ready(Ok(Data(data))),
Ok(data) => ready(Ok(AFPluginData(data))),
Err(e) => ready(Err(InternalError::DeserializeFromBytes(format!("{}", e)).into())),
},
}
}
}
impl<T> Responder for Data<T>
impl<T> AFPluginResponder for AFPluginData<T>
where
T: ToBytes,
{
fn respond_to(self, _request: &EventRequest) -> EventResponse {
fn respond_to(self, _request: &AFPluginEventRequest) -> EventResponse {
match self.into_inner().into_bytes() {
Ok(bytes) => {
log::trace!("Serialize Data: {:?} to event response", std::any::type_name::<T>());
@ -64,29 +64,29 @@ where
}
}
impl<T> std::convert::TryFrom<&Payload> for Data<T>
impl<T> std::convert::TryFrom<&Payload> for AFPluginData<T>
where
T: FromBytes,
T: AFPluginFromBytes,
{
type Error = DispatchError;
fn try_from(payload: &Payload) -> Result<Data<T>, Self::Error> {
fn try_from(payload: &Payload) -> Result<AFPluginData<T>, Self::Error> {
parse_payload(payload)
}
}
impl<T> std::convert::TryFrom<Payload> for Data<T>
impl<T> std::convert::TryFrom<Payload> for AFPluginData<T>
where
T: FromBytes,
T: AFPluginFromBytes,
{
type Error = DispatchError;
fn try_from(payload: Payload) -> Result<Data<T>, Self::Error> {
fn try_from(payload: Payload) -> Result<AFPluginData<T>, Self::Error> {
parse_payload(&payload)
}
}
fn parse_payload<T>(payload: &Payload) -> Result<Data<T>, DispatchError>
fn parse_payload<T>(payload: &Payload) -> Result<AFPluginData<T>, DispatchError>
where
T: FromBytes,
T: AFPluginFromBytes,
{
match payload {
Payload::None => Err(InternalError::UnexpectedNone(format!(
@ -96,12 +96,12 @@ where
.into()),
Payload::Bytes(bytes) => {
let data = T::parse_from_bytes(bytes.clone())?;
Ok(Data(data))
Ok(AFPluginData(data))
}
}
}
impl<T> std::convert::TryInto<Payload> for Data<T>
impl<T> std::convert::TryInto<Payload> for AFPluginData<T>
where
T: ToBytes,
{
@ -114,7 +114,7 @@ where
}
}
impl ToBytes for Data<String> {
impl ToBytes for AFPluginData<String> {
fn into_bytes(self) -> Result<Bytes, DispatchError> {
Ok(Bytes::from(self.0))
}

View File

@ -1,9 +1,9 @@
use crate::runtime::FlowyRuntime;
use crate::runtime::AFPluginRuntime;
use crate::{
errors::{DispatchError, Error, InternalError},
module::{as_module_map, Module, ModuleMap, ModuleRequest},
module::{as_plugin_map, AFPlugin, AFPluginMap, AFPluginRequest},
response::EventResponse,
service::{Service, ServiceFactory},
service::{AFPluginServiceFactory, Service},
};
use derivative::*;
use futures_core::future::BoxFuture;
@ -12,42 +12,43 @@ use pin_project::pin_project;
use std::{future::Future, sync::Arc};
use tokio::macros::support::{Pin, Poll};
pub struct EventDispatcher {
module_map: ModuleMap,
runtime: FlowyRuntime,
pub struct AFPluginDispatcher {
plugins: AFPluginMap,
runtime: AFPluginRuntime,
}
impl EventDispatcher {
pub fn construct<F>(runtime: FlowyRuntime, module_factory: F) -> EventDispatcher
impl AFPluginDispatcher {
pub fn construct<F>(runtime: AFPluginRuntime, module_factory: F) -> AFPluginDispatcher
where
F: FnOnce() -> Vec<Module>,
F: FnOnce() -> Vec<AFPlugin>,
{
let modules = module_factory();
tracing::trace!("{}", module_info(&modules));
let module_map = as_module_map(modules);
EventDispatcher { module_map, runtime }
let plugins = module_factory();
tracing::trace!("{}", plugin_info(&plugins));
AFPluginDispatcher {
plugins: as_plugin_map(plugins),
runtime,
}
}
pub fn async_send<Req>(dispatch: Arc<EventDispatcher>, request: Req) -> DispatchFuture<EventResponse>
pub fn async_send<Req>(dispatch: Arc<AFPluginDispatcher>, request: Req) -> DispatchFuture<EventResponse>
where
Req: std::convert::Into<ModuleRequest>,
Req: std::convert::Into<AFPluginRequest>,
{
EventDispatcher::async_send_with_callback(dispatch, request, |_| Box::pin(async {}))
AFPluginDispatcher::async_send_with_callback(dispatch, request, |_| Box::pin(async {}))
}
pub fn async_send_with_callback<Req, Callback>(
dispatch: Arc<EventDispatcher>,
dispatch: Arc<AFPluginDispatcher>,
request: Req,
callback: Callback,
) -> DispatchFuture<EventResponse>
where
Req: std::convert::Into<ModuleRequest>,
Req: std::convert::Into<AFPluginRequest>,
Callback: FnOnce(EventResponse) -> BoxFuture<'static, ()> + 'static + Send + Sync,
{
let request: ModuleRequest = request.into();
let module_map = dispatch.module_map.clone();
let service = Box::new(DispatchService { module_map });
let request: AFPluginRequest = request.into();
let plugins = dispatch.plugins.clone();
let service = Box::new(DispatchService { plugins });
tracing::trace!("Async event: {:?}", &request.event);
let service_ctx = DispatchContext {
request,
@ -72,9 +73,9 @@ impl EventDispatcher {
}
}
pub fn sync_send(dispatch: Arc<EventDispatcher>, request: ModuleRequest) -> EventResponse {
pub fn sync_send(dispatch: Arc<AFPluginDispatcher>, request: AFPluginRequest) -> EventResponse {
futures::executor::block_on(async {
EventDispatcher::async_send_with_callback(dispatch, request, |_| Box::pin(async {})).await
AFPluginDispatcher::async_send_with_callback(dispatch, request, |_| Box::pin(async {})).await
})
}
@ -109,20 +110,20 @@ pub type BoxFutureCallback = Box<dyn FnOnce(EventResponse) -> BoxFuture<'static,
#[derive(Derivative)]
#[derivative(Debug)]
pub struct DispatchContext {
pub request: ModuleRequest,
pub request: AFPluginRequest,
#[derivative(Debug = "ignore")]
pub callback: Option<BoxFutureCallback>,
}
impl DispatchContext {
pub(crate) fn into_parts(self) -> (ModuleRequest, Option<BoxFutureCallback>) {
pub(crate) fn into_parts(self) -> (AFPluginRequest, Option<BoxFutureCallback>) {
let DispatchContext { request, callback } = self;
(request, callback)
}
}
pub(crate) struct DispatchService {
pub(crate) module_map: ModuleMap,
pub(crate) plugins: AFPluginMap,
}
impl Service<DispatchContext> for DispatchService {
@ -135,7 +136,7 @@ impl Service<DispatchContext> for DispatchService {
tracing::instrument(name = "DispatchService", level = "debug", skip(self, ctx))
)]
fn call(&self, ctx: DispatchContext) -> Self::Future {
let module_map = self.module_map.clone();
let module_map = self.plugins.clone();
let (request, callback) = ctx.into_parts();
Box::pin(async move {
@ -168,17 +169,17 @@ impl Service<DispatchContext> for DispatchService {
}
#[allow(dead_code)]
fn module_info(modules: &[Module]) -> String {
let mut info = format!("{} modules loaded\n", modules.len());
for module in modules {
fn plugin_info(plugins: &[AFPlugin]) -> String {
let mut info = format!("{} plugins loaded\n", plugins.len());
for module in plugins {
info.push_str(&format!("-> {} loaded \n", module.name));
}
info
}
#[allow(dead_code)]
fn print_module_map_info(module_map: &ModuleMap) {
module_map.iter().for_each(|(k, v)| {
tracing::info!("Event: {:?} module: {:?}", k, v.name);
fn print_plugins(plugins: &AFPluginMap) {
plugins.iter().for_each(|(k, v)| {
tracing::info!("Event: {:?} plugin : {:?}", k, v.name);
})
}

View File

@ -1,6 +1,6 @@
use crate::{
byte_trait::FromBytes,
request::EventRequest,
byte_trait::AFPluginFromBytes,
request::AFPluginEventRequest,
response::{EventResponse, ResponseBuilder},
};
use bytes::Bytes;
@ -54,8 +54,8 @@ impl std::error::Error for DispatchError {
}
}
impl From<SendError<EventRequest>> for DispatchError {
fn from(err: SendError<EventRequest>) -> Self {
impl From<SendError<AFPluginEventRequest>> for DispatchError {
fn from(err: SendError<AFPluginEventRequest>) -> Self {
InternalError::Other(format!("{}", err)).into()
}
}
@ -73,7 +73,7 @@ impl From<protobuf::ProtobufError> for DispatchError {
}
}
impl FromBytes for DispatchError {
impl AFPluginFromBytes for DispatchError {
fn parse_from_bytes(bytes: Bytes) -> Result<Self, DispatchError> {
let s = String::from_utf8(bytes.to_vec()).unwrap();
Ok(InternalError::DeserializeFromBytes(s).into())

View File

@ -4,46 +4,40 @@ use std::{
};
#[derive(Default, Debug)]
pub struct ModuleDataMap {
map: HashMap<TypeId, Box<dyn Any + Sync + Send>>,
}
pub struct AFPluginStateMap(HashMap<TypeId, Box<dyn Any + Sync + Send>>);
impl ModuleDataMap {
impl AFPluginStateMap {
#[inline]
pub fn new() -> ModuleDataMap {
ModuleDataMap {
map: HashMap::default(),
}
pub fn new() -> AFPluginStateMap {
AFPluginStateMap(HashMap::default())
}
pub fn insert<T>(&mut self, val: T) -> Option<T>
where
T: 'static + Send + Sync,
{
self.map
.insert(TypeId::of::<T>(), Box::new(val))
.and_then(downcast_owned)
self.0.insert(TypeId::of::<T>(), Box::new(val)).and_then(downcast_owned)
}
pub fn remove<T>(&mut self) -> Option<T>
where
T: 'static + Send + Sync,
{
self.map.remove(&TypeId::of::<T>()).and_then(downcast_owned)
self.0.remove(&TypeId::of::<T>()).and_then(downcast_owned)
}
pub fn get<T>(&self) -> Option<&T>
where
T: 'static + Send + Sync,
{
self.map.get(&TypeId::of::<T>()).and_then(|boxed| boxed.downcast_ref())
self.0.get(&TypeId::of::<T>()).and_then(|boxed| boxed.downcast_ref())
}
pub fn get_mut<T>(&mut self) -> Option<&mut T>
where
T: 'static + Send + Sync,
{
self.map
self.0
.get_mut(&TypeId::of::<T>())
.and_then(|boxed| boxed.downcast_mut())
}
@ -52,11 +46,11 @@ impl ModuleDataMap {
where
T: 'static + Send + Sync,
{
self.map.contains_key(&TypeId::of::<T>())
self.0.contains_key(&TypeId::of::<T>())
}
pub fn extend(&mut self, other: ModuleDataMap) {
self.map.extend(other.map);
pub fn extend(&mut self, other: AFPluginStateMap) {
self.0.extend(other.0);
}
}

View File

@ -1,18 +1,18 @@
use crate::{
errors::{DispatchError, InternalError},
request::{payload::Payload, EventRequest, FromRequest},
request::{payload::Payload, AFPluginEventRequest, FromAFPluginRequest},
util::ready::{ready, Ready},
};
use std::{any::type_name, ops::Deref, sync::Arc};
pub struct AppData<T: ?Sized + Send + Sync>(Arc<T>);
pub struct AFPluginState<T: ?Sized + Send + Sync>(Arc<T>);
impl<T> AppData<T>
impl<T> AFPluginState<T>
where
T: Send + Sync,
{
pub fn new(data: T) -> Self {
AppData(Arc::new(data))
AFPluginState(Arc::new(data))
}
pub fn get_ref(&self) -> &T {
@ -20,7 +20,7 @@ where
}
}
impl<T> Deref for AppData<T>
impl<T> Deref for AFPluginState<T>
where
T: ?Sized + Send + Sync,
{
@ -31,25 +31,25 @@ where
}
}
impl<T> Clone for AppData<T>
impl<T> Clone for AFPluginState<T>
where
T: ?Sized + Send + Sync,
{
fn clone(&self) -> AppData<T> {
AppData(self.0.clone())
fn clone(&self) -> AFPluginState<T> {
AFPluginState(self.0.clone())
}
}
impl<T> From<Arc<T>> for AppData<T>
impl<T> From<Arc<T>> for AFPluginState<T>
where
T: ?Sized + Send + Sync,
{
fn from(arc: Arc<T>) -> Self {
AppData(arc)
AFPluginState(arc)
}
}
impl<T> FromRequest for AppData<T>
impl<T> FromAFPluginRequest for AFPluginState<T>
where
T: ?Sized + Send + Sync + 'static,
{
@ -57,11 +57,11 @@ where
type Future = Ready<Result<Self, DispatchError>>;
#[inline]
fn from_request(req: &EventRequest, _: &mut Payload) -> Self::Future {
if let Some(data) = req.module_data::<AppData<T>>() {
ready(Ok(data.clone()))
fn from_request(req: &AFPluginEventRequest, _: &mut Payload) -> Self::Future {
if let Some(state) = req.get_state::<AFPluginState<T>>() {
ready(Ok(state.clone()))
} else {
let msg = format!("Failed to get the module data of type: {}", type_name::<T>());
let msg = format!("Failed to get the plugin state of type: {}", type_name::<T>());
log::error!("{}", msg,);
ready(Err(InternalError::Other(msg).into()))
}

View File

@ -1,3 +1,18 @@
use crate::{
errors::{DispatchError, InternalError},
module::{container::AFPluginStateMap, AFPluginState},
request::{payload::Payload, AFPluginEventRequest, FromAFPluginRequest},
response::{AFPluginResponder, EventResponse},
service::{
factory, AFPluginHandler, AFPluginHandlerService, AFPluginServiceFactory, BoxService, BoxServiceFactory,
Service, ServiceRequest, ServiceResponse,
},
};
use futures_core::future::BoxFuture;
use futures_core::ready;
use nanoid::nanoid;
use pin_project::pin_project;
use std::sync::Arc;
use std::{
collections::HashMap,
fmt,
@ -8,66 +23,48 @@ use std::{
task::{Context, Poll},
};
use futures_core::ready;
use pin_project::pin_project;
use crate::{
errors::{DispatchError, InternalError},
module::{container::ModuleDataMap, AppData},
request::{payload::Payload, EventRequest, FromRequest},
response::{EventResponse, Responder},
service::{
factory, BoxService, BoxServiceFactory, Handler, HandlerService, Service, ServiceFactory, ServiceRequest,
ServiceResponse,
},
};
use futures_core::future::BoxFuture;
use nanoid::nanoid;
use std::sync::Arc;
pub type ModuleMap = Arc<HashMap<Event, Arc<Module>>>;
pub(crate) fn as_module_map(modules: Vec<Module>) -> ModuleMap {
let mut module_map = HashMap::new();
modules.into_iter().for_each(|m| {
pub type AFPluginMap = Arc<HashMap<AFPluginEvent, Arc<AFPlugin>>>;
pub(crate) fn as_plugin_map(plugins: Vec<AFPlugin>) -> AFPluginMap {
let mut plugin_map = HashMap::new();
plugins.into_iter().for_each(|m| {
let events = m.events();
let module = Arc::new(m);
let plugins = Arc::new(m);
events.into_iter().for_each(|e| {
module_map.insert(e, module.clone());
plugin_map.insert(e, plugins.clone());
});
});
Arc::new(module_map)
Arc::new(plugin_map)
}
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub struct Event(String);
pub struct AFPluginEvent(String);
impl<T: Display + Eq + Hash + Debug + Clone> std::convert::From<T> for Event {
impl<T: Display + Eq + Hash + Debug + Clone> std::convert::From<T> for AFPluginEvent {
fn from(t: T) -> Self {
Event(format!("{}", t))
AFPluginEvent(format!("{}", t))
}
}
pub type EventServiceFactory = BoxServiceFactory<(), ServiceRequest, ServiceResponse, DispatchError>;
pub struct Module {
pub struct AFPlugin {
pub name: String,
module_data: Arc<ModuleDataMap>,
service_map: Arc<HashMap<Event, EventServiceFactory>>,
states: Arc<AFPluginStateMap>,
event_service_factory:
Arc<HashMap<AFPluginEvent, BoxServiceFactory<(), ServiceRequest, ServiceResponse, DispatchError>>>,
}
impl std::default::Default for Module {
impl std::default::Default for AFPlugin {
fn default() -> Self {
Self {
name: "".to_owned(),
module_data: Arc::new(ModuleDataMap::new()),
service_map: Arc::new(HashMap::new()),
states: Arc::new(AFPluginStateMap::new()),
event_service_factory: Arc::new(HashMap::new()),
}
}
}
impl Module {
impl AFPlugin {
pub fn new() -> Self {
Module::default()
AFPlugin::default()
}
pub fn name(mut self, s: &str) -> Self {
@ -75,48 +72,48 @@ impl Module {
self
}
pub fn data<D: 'static + Send + Sync>(mut self, data: D) -> Self {
Arc::get_mut(&mut self.module_data).unwrap().insert(AppData::new(data));
pub fn state<D: 'static + Send + Sync>(mut self, data: D) -> Self {
Arc::get_mut(&mut self.states).unwrap().insert(AFPluginState::new(data));
self
}
pub fn event<E, H, T, R>(mut self, event: E, handler: H) -> Self
where
H: Handler<T, R>,
T: FromRequest + 'static + Send + Sync,
<T as FromRequest>::Future: Sync + Send,
H: AFPluginHandler<T, R>,
T: FromAFPluginRequest + 'static + Send + Sync,
<T as FromAFPluginRequest>::Future: Sync + Send,
R: Future + 'static + Send + Sync,
R::Output: Responder + 'static,
R::Output: AFPluginResponder + 'static,
E: Eq + Hash + Debug + Clone + Display,
{
let event: Event = event.into();
if self.service_map.contains_key(&event) {
let event: AFPluginEvent = event.into();
if self.event_service_factory.contains_key(&event) {
log::error!("Duplicate Event: {:?}", &event);
}
Arc::get_mut(&mut self.service_map)
Arc::get_mut(&mut self.event_service_factory)
.unwrap()
.insert(event, factory(HandlerService::new(handler)));
.insert(event, factory(AFPluginHandlerService::new(handler)));
self
}
pub fn events(&self) -> Vec<Event> {
self.service_map.keys().cloned().collect::<Vec<_>>()
pub fn events(&self) -> Vec<AFPluginEvent> {
self.event_service_factory.keys().cloned().collect::<Vec<_>>()
}
}
#[derive(Debug, Clone)]
pub struct ModuleRequest {
pub struct AFPluginRequest {
pub id: String,
pub event: Event,
pub event: AFPluginEvent,
pub(crate) payload: Payload,
}
impl ModuleRequest {
impl AFPluginRequest {
pub fn new<E>(event: E) -> Self
where
E: Into<Event>,
E: Into<AFPluginEvent>,
{
Self {
id: nanoid!(6),
@ -134,52 +131,48 @@ impl ModuleRequest {
}
}
impl std::fmt::Display for ModuleRequest {
impl std::fmt::Display for AFPluginRequest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{:?}", self.id, self.event)
}
}
impl ServiceFactory<ModuleRequest> for Module {
impl AFPluginServiceFactory<AFPluginRequest> for AFPlugin {
type Response = EventResponse;
type Error = DispatchError;
type Service = BoxService<ModuleRequest, Self::Response, Self::Error>;
type Service = BoxService<AFPluginRequest, Self::Response, Self::Error>;
type Context = ();
type Future = BoxFuture<'static, Result<Self::Service, Self::Error>>;
fn new_service(&self, _cfg: Self::Context) -> Self::Future {
let service_map = self.service_map.clone();
let module_data = self.module_data.clone();
let services = self.event_service_factory.clone();
let states = self.states.clone();
Box::pin(async move {
let service = ModuleService {
service_map,
module_data,
};
let module_service = Box::new(service) as Self::Service;
Ok(module_service)
let service = AFPluginService { services, states };
Ok(Box::new(service) as Self::Service)
})
}
}
pub struct ModuleService {
service_map: Arc<HashMap<Event, EventServiceFactory>>,
module_data: Arc<ModuleDataMap>,
pub struct AFPluginService {
services: Arc<HashMap<AFPluginEvent, BoxServiceFactory<(), ServiceRequest, ServiceResponse, DispatchError>>>,
states: Arc<AFPluginStateMap>,
}
impl Service<ModuleRequest> for ModuleService {
impl Service<AFPluginRequest> for AFPluginService {
type Response = EventResponse;
type Error = DispatchError;
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
fn call(&self, request: ModuleRequest) -> Self::Future {
let ModuleRequest { id, event, payload } = request;
let module_data = self.module_data.clone();
let request = EventRequest::new(id, event, module_data);
fn call(&self, request: AFPluginRequest) -> Self::Future {
let AFPluginRequest { id, event, payload } = request;
let states = self.states.clone();
let request = AFPluginEventRequest::new(id, event, states);
match self.service_map.get(&request.event) {
match self.services.get(&request.event) {
Some(factory) => {
let service_fut = factory.new_service(());
let fut = ModuleServiceFuture {
let fut = AFPluginServiceFuture {
fut: Box::pin(async {
let service = service_fut.await?;
let service_req = ServiceRequest::new(request, payload);
@ -197,12 +190,12 @@ impl Service<ModuleRequest> for ModuleService {
}
#[pin_project]
pub struct ModuleServiceFuture {
pub struct AFPluginServiceFuture {
#[pin]
fut: BoxFuture<'static, Result<ServiceResponse, DispatchError>>,
}
impl Future for ModuleServiceFuture {
impl Future for AFPluginServiceFuture {
type Output = Result<EventResponse, DispatchError>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
@ -210,36 +203,3 @@ impl Future for ModuleServiceFuture {
Poll::Ready(Ok(response))
}
}
// #[cfg(test)]
// mod tests {
// use super::*;
// use crate::rt::Runtime;
// use futures_util::{future, pin_mut};
// use tokio::sync::mpsc::unbounded_channel;
// pub async fn hello_service() -> String { "hello".to_string() }
// #[test]
// fn test() {
// let runtime = Runtime::new().unwrap();
// runtime.block_on(async {
// let (sys_tx, mut sys_rx) = unbounded_channel::<SystemCommand>();
// let event = "hello".to_string();
// let module = Module::new(sys_tx).event(event.clone(),
// hello_service); let req_tx = module.req_tx();
// let event = async move {
// let request = EventRequest::new(event.clone());
// req_tx.send(request).unwrap();
//
// match sys_rx.recv().await {
// Some(cmd) => {
// tracing::info!("{:?}", cmd);
// },
// None => panic!(""),
// }
// };
//
// pin_mut!(module, event);
// future::select(module, event).await;
// });
// }
// }

View File

@ -2,7 +2,7 @@ use std::future::Future;
use crate::{
errors::{DispatchError, InternalError},
module::{Event, ModuleDataMap},
module::{AFPluginEvent, AFPluginStateMap},
request::payload::Payload,
util::ready::{ready, Ready},
};
@ -16,31 +16,31 @@ use std::{
};
#[derive(Clone, Debug, Derivative)]
pub struct EventRequest {
pub struct AFPluginEventRequest {
#[allow(dead_code)]
pub(crate) id: String,
pub(crate) event: Event,
pub(crate) event: AFPluginEvent,
#[derivative(Debug = "ignore")]
pub(crate) module_data: Arc<ModuleDataMap>,
pub(crate) states: Arc<AFPluginStateMap>,
}
impl EventRequest {
pub fn new<E>(id: String, event: E, module_data: Arc<ModuleDataMap>) -> EventRequest
impl AFPluginEventRequest {
pub fn new<E>(id: String, event: E, module_data: Arc<AFPluginStateMap>) -> AFPluginEventRequest
where
E: Into<Event>,
E: Into<AFPluginEvent>,
{
Self {
id,
event: event.into(),
module_data,
states: module_data,
}
}
pub fn module_data<T: 'static>(&self) -> Option<&T>
pub fn get_state<T: 'static>(&self) -> Option<&T>
where
T: Send + Sync,
{
if let Some(data) = self.module_data.get::<T>() {
if let Some(data) = self.states.get::<T>() {
return Some(data);
}
@ -48,29 +48,29 @@ impl EventRequest {
}
}
pub trait FromRequest: Sized {
pub trait FromAFPluginRequest: Sized {
type Error: Into<DispatchError>;
type Future: Future<Output = Result<Self, Self::Error>>;
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future;
fn from_request(req: &AFPluginEventRequest, payload: &mut Payload) -> Self::Future;
}
#[doc(hidden)]
impl FromRequest for () {
impl FromAFPluginRequest for () {
type Error = DispatchError;
type Future = Ready<Result<(), DispatchError>>;
fn from_request(_req: &EventRequest, _payload: &mut Payload) -> Self::Future {
fn from_request(_req: &AFPluginEventRequest, _payload: &mut Payload) -> Self::Future {
ready(Ok(()))
}
}
#[doc(hidden)]
impl FromRequest for String {
impl FromAFPluginRequest for String {
type Error = DispatchError;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
fn from_request(req: &AFPluginEventRequest, payload: &mut Payload) -> Self::Future {
match &payload {
Payload::None => ready(Err(unexpected_none_payload(req))),
Payload::Bytes(buf) => ready(Ok(String::from_utf8_lossy(buf).into_owned())),
@ -78,20 +78,20 @@ impl FromRequest for String {
}
}
pub fn unexpected_none_payload(request: &EventRequest) -> DispatchError {
pub fn unexpected_none_payload(request: &AFPluginEventRequest) -> DispatchError {
log::warn!("{:?} expected payload", &request.event);
InternalError::UnexpectedNone("Expected payload".to_string()).into()
}
#[doc(hidden)]
impl<T> FromRequest for Result<T, T::Error>
impl<T> FromAFPluginRequest for Result<T, T::Error>
where
T: FromRequest,
T: FromAFPluginRequest,
{
type Error = DispatchError;
type Future = FromRequestFuture<T::Future>;
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
fn from_request(req: &AFPluginEventRequest, payload: &mut Payload) -> Self::Future {
FromRequestFuture {
fut: T::from_request(req, payload),
}

View File

@ -1,19 +1,19 @@
#[allow(unused_imports)]
use crate::errors::{DispatchError, InternalError};
use crate::{
request::EventRequest,
request::AFPluginEventRequest,
response::{EventResponse, ResponseBuilder},
};
use bytes::Bytes;
pub trait Responder {
fn respond_to(self, req: &EventRequest) -> EventResponse;
pub trait AFPluginResponder {
fn respond_to(self, req: &AFPluginEventRequest) -> EventResponse;
}
macro_rules! impl_responder {
($res: ty) => {
impl Responder for $res {
fn respond_to(self, _: &EventRequest) -> EventResponse {
impl AFPluginResponder for $res {
fn respond_to(self, _: &AFPluginEventRequest) -> EventResponse {
ResponseBuilder::Ok().data(self).build()
}
}
@ -27,12 +27,12 @@ impl_responder!(Bytes);
impl_responder!(());
impl_responder!(Vec<u8>);
impl<T, E> Responder for Result<T, E>
impl<T, E> AFPluginResponder for Result<T, E>
where
T: Responder,
T: AFPluginResponder,
E: Into<DispatchError>,
{
fn respond_to(self, request: &EventRequest) -> EventResponse {
fn respond_to(self, request: &AFPluginEventRequest) -> EventResponse {
match self {
Ok(val) => val.respond_to(request),
Err(e) => e.into().into(),

View File

@ -1,9 +1,9 @@
use crate::{
byte_trait::FromBytes,
data::Data,
byte_trait::AFPluginFromBytes,
data::AFPluginData,
errors::DispatchError,
request::{EventRequest, Payload},
response::Responder,
request::{AFPluginEventRequest, Payload},
response::AFPluginResponder,
};
use derivative::*;
use std::{convert::TryFrom, fmt, fmt::Formatter};
@ -35,16 +35,16 @@ impl EventResponse {
pub fn parse<T, E>(self) -> Result<Result<T, E>, DispatchError>
where
T: FromBytes,
E: FromBytes,
T: AFPluginFromBytes,
E: AFPluginFromBytes,
{
match self.status_code {
StatusCode::Ok => {
let data = <Data<T>>::try_from(self.payload)?;
let data = <AFPluginData<T>>::try_from(self.payload)?;
Ok(Ok(data.into_inner()))
}
StatusCode::Err | StatusCode::Internal => {
let err = <Data<E>>::try_from(self.payload)?;
let err = <AFPluginData<E>>::try_from(self.payload)?;
Ok(Err(err.into_inner()))
}
}
@ -64,18 +64,18 @@ impl std::fmt::Display for EventResponse {
}
}
impl Responder for EventResponse {
impl AFPluginResponder for EventResponse {
#[inline]
fn respond_to(self, _: &EventRequest) -> EventResponse {
fn respond_to(self, _: &AFPluginEventRequest) -> EventResponse {
self
}
}
pub type DataResult<T, E> = std::result::Result<Data<T>, E>;
pub type DataResult<T, E> = std::result::Result<AFPluginData<T>, E>;
pub fn data_result<T, E>(data: T) -> Result<Data<T>, E>
pub fn data_result<T, E>(data: T) -> Result<AFPluginData<T>, E>
where
E: Into<DispatchError>,
{
Ok(Data(data))
Ok(AFPluginData(data))
}

View File

@ -1,9 +1,9 @@
use std::{io, thread};
use tokio::runtime;
pub type FlowyRuntime = tokio::runtime::Runtime;
pub type AFPluginRuntime = tokio::runtime::Runtime;
pub fn tokio_default_runtime() -> io::Result<FlowyRuntime> {
pub fn tokio_default_runtime() -> io::Result<AFPluginRuntime> {
runtime::Builder::new_multi_thread()
.thread_name("dispatch-rt")
.enable_io()

View File

@ -1,23 +1,23 @@
use crate::service::{Service, ServiceFactory};
use crate::service::{AFPluginServiceFactory, Service};
use futures_core::future::BoxFuture;
pub fn factory<SF, Req>(factory: SF) -> BoxServiceFactory<SF::Context, Req, SF::Response, SF::Error>
where
SF: ServiceFactory<Req> + 'static + Sync + Send,
SF: AFPluginServiceFactory<Req> + 'static + Sync + Send,
Req: 'static,
SF::Response: 'static,
SF::Service: 'static,
SF::Future: 'static,
SF::Error: 'static + Send + Sync,
<SF as ServiceFactory<Req>>::Service: Sync + Send,
<<SF as ServiceFactory<Req>>::Service as Service<Req>>::Future: Send + Sync,
<SF as ServiceFactory<Req>>::Future: Send + Sync,
<SF as AFPluginServiceFactory<Req>>::Service: Sync + Send,
<<SF as AFPluginServiceFactory<Req>>::Service as Service<Req>>::Future: Send + Sync,
<SF as AFPluginServiceFactory<Req>>::Future: Send + Sync,
{
BoxServiceFactory(Box::new(FactoryWrapper(factory)))
}
type Inner<Cfg, Req, Res, Err> = Box<
dyn ServiceFactory<
dyn AFPluginServiceFactory<
Req,
Context = Cfg,
Response = Res,
@ -29,7 +29,7 @@ type Inner<Cfg, Req, Res, Err> = Box<
>;
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> AFPluginServiceFactory<Req> for BoxServiceFactory<Cfg, Req, Res, Err>
where
Req: 'static,
Res: 'static,
@ -98,16 +98,16 @@ where
struct FactoryWrapper<SF>(SF);
impl<SF, Req, Cfg, Res, Err> ServiceFactory<Req> for FactoryWrapper<SF>
impl<SF, Req, Cfg, Res, Err> AFPluginServiceFactory<Req> for FactoryWrapper<SF>
where
Req: 'static,
Res: 'static,
Err: 'static,
SF: ServiceFactory<Req, Context = Cfg, Response = Res, Error = Err>,
SF: AFPluginServiceFactory<Req, Context = Cfg, Response = Res, Error = Err>,
SF::Future: 'static,
SF::Service: 'static + Send + Sync,
<<SF as ServiceFactory<Req>>::Service as Service<Req>>::Future: Send + Sync + 'static,
<SF as ServiceFactory<Req>>::Future: Send + Sync,
<<SF as AFPluginServiceFactory<Req>>::Service as Service<Req>>::Future: Send + Sync + 'static,
<SF as AFPluginServiceFactory<Req>>::Future: Send + Sync,
{
type Response = Res;
type Error = Err;

View File

@ -10,37 +10,37 @@ use pin_project::pin_project;
use crate::{
errors::DispatchError,
request::{payload::Payload, EventRequest, FromRequest},
response::{EventResponse, Responder},
service::{Service, ServiceFactory, ServiceRequest, ServiceResponse},
request::{payload::Payload, AFPluginEventRequest, FromAFPluginRequest},
response::{AFPluginResponder, EventResponse},
service::{AFPluginServiceFactory, Service, ServiceRequest, ServiceResponse},
util::ready::*,
};
pub trait Handler<T, R>: Clone + 'static + Sync + Send
pub trait AFPluginHandler<T, R>: Clone + 'static + Sync + Send
where
R: Future + Send + Sync,
R::Output: Responder,
R::Output: AFPluginResponder,
{
fn call(&self, param: T) -> R;
}
pub struct HandlerService<H, T, R>
pub struct AFPluginHandlerService<H, T, R>
where
H: Handler<T, R>,
T: FromRequest,
H: AFPluginHandler<T, R>,
T: FromAFPluginRequest,
R: Future + Sync + Send,
R::Output: Responder,
R::Output: AFPluginResponder,
{
handler: H,
_phantom: PhantomData<(T, R)>,
}
impl<H, T, R> HandlerService<H, T, R>
impl<H, T, R> AFPluginHandlerService<H, T, R>
where
H: Handler<T, R>,
T: FromRequest,
H: AFPluginHandler<T, R>,
T: FromAFPluginRequest,
R: Future + Sync + Send,
R::Output: Responder,
R::Output: AFPluginResponder,
{
pub fn new(handler: H) -> Self {
Self {
@ -50,12 +50,12 @@ where
}
}
impl<H, T, R> Clone for HandlerService<H, T, R>
impl<H, T, R> Clone for AFPluginHandlerService<H, T, R>
where
H: Handler<T, R>,
T: FromRequest,
H: AFPluginHandler<T, R>,
T: FromAFPluginRequest,
R: Future + Sync + Send,
R::Output: Responder,
R::Output: AFPluginResponder,
{
fn clone(&self) -> Self {
Self {
@ -65,12 +65,12 @@ where
}
}
impl<F, T, R> ServiceFactory<ServiceRequest> for HandlerService<F, T, R>
impl<F, T, R> AFPluginServiceFactory<ServiceRequest> for AFPluginHandlerService<F, T, R>
where
F: Handler<T, R>,
T: FromRequest,
F: AFPluginHandler<T, R>,
T: FromAFPluginRequest,
R: Future + Send + Sync,
R::Output: Responder,
R::Output: AFPluginResponder,
{
type Response = ServiceResponse;
type Error = DispatchError;
@ -83,12 +83,12 @@ where
}
}
impl<H, T, R> Service<ServiceRequest> for HandlerService<H, T, R>
impl<H, T, R> Service<ServiceRequest> for AFPluginHandlerService<H, T, R>
where
H: Handler<T, R>,
T: FromRequest,
H: AFPluginHandler<T, R>,
T: FromAFPluginRequest,
R: Future + Sync + Send,
R::Output: Responder,
R::Output: AFPluginResponder,
{
type Response = ServiceResponse;
type Error = DispatchError;
@ -104,21 +104,21 @@ where
#[pin_project(project = HandlerServiceProj)]
pub enum HandlerServiceFuture<H, T, R>
where
H: Handler<T, R>,
T: FromRequest,
H: AFPluginHandler<T, R>,
T: FromAFPluginRequest,
R: Future + Sync + Send,
R::Output: Responder,
R::Output: AFPluginResponder,
{
Extract(#[pin] T::Future, Option<EventRequest>, H),
Handle(#[pin] R, Option<EventRequest>),
Extract(#[pin] T::Future, Option<AFPluginEventRequest>, H),
Handle(#[pin] R, Option<AFPluginEventRequest>),
}
impl<F, T, R> Future for HandlerServiceFuture<F, T, R>
where
F: Handler<T, R>,
T: FromRequest,
F: AFPluginHandler<T, R>,
T: FromAFPluginRequest,
R: Future + Sync + Send,
R::Output: Responder,
R::Output: AFPluginResponder,
{
type Output = Result<ServiceResponse, DispatchError>;
@ -152,10 +152,10 @@ where
}
macro_rules! factory_tuple ({ $($param:ident)* } => {
impl<Func, $($param,)* Res> Handler<($($param,)*), Res> for Func
impl<Func, $($param,)* Res> AFPluginHandler<($($param,)*), Res> for Func
where Func: Fn($($param),*) -> Res + Clone + 'static + Sync + Send,
Res: Future + Sync + Send,
Res::Output: Responder,
Res::Output: AFPluginResponder,
{
#[allow(non_snake_case)]
fn call(&self, ($($param,)*): ($($param,)*)) -> Res {
@ -170,17 +170,17 @@ macro_rules! tuple_from_req ({$tuple_type:ident, $(($n:tt, $T:ident)),+} => {
use super::*;
#[pin_project::pin_project]
struct FromRequestFutures<$($T: FromRequest),+>($(#[pin] $T::Future),+);
struct FromRequestFutures<$($T: FromAFPluginRequest),+>($(#[pin] $T::Future),+);
/// FromRequest implementation for tuple
#[doc(hidden)]
#[allow(unused_parens)]
impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
impl<$($T: FromAFPluginRequest + 'static),+> FromAFPluginRequest for ($($T,)+)
{
type Error = DispatchError;
type Future = $tuple_type<$($T),+>;
fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
fn from_request(req: &AFPluginEventRequest, payload: &mut Payload) -> Self::Future {
$tuple_type {
items: <($(Option<$T>,)+)>::default(),
futs: FromRequestFutures($($T::from_request(req, payload),)+),
@ -190,13 +190,13 @@ macro_rules! tuple_from_req ({$tuple_type:ident, $(($n:tt, $T:ident)),+} => {
#[doc(hidden)]
#[pin_project::pin_project]
pub struct $tuple_type<$($T: FromRequest),+> {
pub struct $tuple_type<$($T: FromAFPluginRequest),+> {
items: ($(Option<$T>,)+),
#[pin]
futs: FromRequestFutures<$($T,)+>,
}
impl<$($T: FromRequest),+> Future for $tuple_type<$($T),+>
impl<$($T: FromAFPluginRequest),+> Future for $tuple_type<$($T),+>
{
type Output = Result<($($T,)+), DispatchError>;

View File

@ -1,7 +1,7 @@
use std::future::Future;
use crate::{
request::{payload::Payload, EventRequest},
request::{payload::Payload, AFPluginEventRequest},
response::EventResponse,
};
@ -13,7 +13,7 @@ pub trait Service<Request> {
fn call(&self, req: Request) -> Self::Future;
}
pub trait ServiceFactory<Request> {
pub trait AFPluginServiceFactory<Request> {
type Response;
type Error;
type Service: Service<Request, Response = Self::Response, Error = Self::Error>;
@ -23,33 +23,33 @@ pub trait ServiceFactory<Request> {
fn new_service(&self, cfg: Self::Context) -> Self::Future;
}
pub struct ServiceRequest {
req: EventRequest,
pub(crate) struct ServiceRequest {
req: AFPluginEventRequest,
payload: Payload,
}
impl ServiceRequest {
pub fn new(req: EventRequest, payload: Payload) -> Self {
pub(crate) fn new(req: AFPluginEventRequest, payload: Payload) -> Self {
Self { req, payload }
}
#[inline]
pub fn into_parts(self) -> (EventRequest, Payload) {
pub(crate) fn into_parts(self) -> (AFPluginEventRequest, Payload) {
(self.req, self.payload)
}
}
pub struct ServiceResponse {
request: EventRequest,
request: AFPluginEventRequest,
response: EventResponse,
}
impl ServiceResponse {
pub fn new(request: EventRequest, response: EventResponse) -> Self {
pub fn new(request: AFPluginEventRequest, response: EventResponse) -> Self {
ServiceResponse { request, response }
}
pub fn into_parts(self) -> (EventRequest, EventResponse) {
pub fn into_parts(self) -> (AFPluginEventRequest, EventResponse) {
(self.request, self.response)
}
}

View File

@ -12,11 +12,11 @@ async fn test() {
let event = "1";
let runtime = tokio_default_runtime().unwrap();
let dispatch = Arc::new(EventDispatcher::construct(runtime, || {
vec![Module::new().event(event, hello)]
let dispatch = Arc::new(AFPluginDispatcher::construct(runtime, || {
vec![AFPlugin::new().event(event, hello)]
}));
let request = ModuleRequest::new(event);
let _ = EventDispatcher::async_send_with_callback(dispatch.clone(), request, |resp| {
let request = AFPluginRequest::new(event);
let _ = AFPluginDispatcher::async_send_with_callback(dispatch.clone(), request, |resp| {
Box::pin(async move {
dbg!(&resp);
})