generic DispatchFuture and mark async_send with sync trait

This commit is contained in:
appflowy 2021-07-19 11:32:33 +08:00
parent e1f73f5246
commit 602018765d
18 changed files with 122 additions and 74 deletions

View File

@ -14,7 +14,7 @@ import window_size
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlowyEditorPlugin.register(with: registry.registrar(forPlugin: "FlowyEditorPlugin"))
FlowyInfraUiPlugin.register(with: registry.registrar(forPlugin: "FlowyInfraUiPlugin"))
FlowyInfraUIPlugin.register(with: registry.registrar(forPlugin: "FlowyInfraUIPlugin"))
FlowySdkPlugin.register(with: registry.registrar(forPlugin: "FlowySdkPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))

View File

@ -253,6 +253,20 @@ packages:
relative: true
source: path
version: "0.0.1"
flowy_infra_ui_platform_interface:
dependency: transitive
description:
path: "packages/flowy_infra_ui/flowy_infra_ui_platform_interface"
relative: true
source: path
version: "0.0.1"
flowy_infra_ui_web:
dependency: transitive
description:
path: "packages/flowy_infra_ui/flowy_infra_ui_web"
relative: true
source: path
version: "0.0.1"
flowy_sdk:
dependency: "direct main"
description:

2
rust-lib/.gitignore vendored
View File

@ -11,3 +11,5 @@ Cargo.lock
**/**/*.log*
**/**/temp
bin/
.idea

View File

@ -1,7 +1,7 @@
use crate::{
errors::{DispatchError, Error, InternalError},
module::{as_module_map, Module, ModuleMap, ModuleRequest},
response::EventResponse,
response::{EventResponse, Responder},
service::{Service, ServiceFactory},
util::tokio_default_runtime,
};
@ -38,7 +38,7 @@ impl EventDispatch {
*(EVENT_DISPATCH.write().unwrap()) = Some(dispatch);
}
pub fn async_send<Req>(request: Req) -> DispatchFuture
pub fn async_send<Req>(request: Req) -> DispatchFuture<EventResponse>
where
Req: std::convert::Into<ModuleRequest>,
{
@ -48,7 +48,7 @@ impl EventDispatch {
pub fn async_send_with_callback<Req, Callback>(
request: Req,
callback: Callback,
) -> DispatchFuture
) -> DispatchFuture<EventResponse>
where
Req: std::convert::Into<ModuleRequest>,
Callback: FnOnce(EventResponse) -> BoxFuture<'static, ()> + 'static + Send + Sync,
@ -99,13 +99,16 @@ impl EventDispatch {
}
#[pin_project]
pub struct DispatchFuture {
pub struct DispatchFuture<T: Responder + Send + Sync> {
#[pin]
fut: BoxFuture<'static, EventResponse>,
pub fut: Pin<Box<dyn Future<Output = T> + Sync + Send>>,
}
impl Future for DispatchFuture {
type Output = EventResponse;
impl<T> Future for DispatchFuture<T>
where
T: Responder + Send + Sync,
{
type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.as_mut().project();

View File

@ -12,6 +12,9 @@ mod data;
mod dispatch;
mod system;
#[macro_use]
pub mod macros;
pub use errors::Error;
pub mod prelude {

View File

@ -0,0 +1,8 @@
#[macro_export]
macro_rules! dispatch_future {
($fut:expr) => {
DispatchFuture {
fut: Box::pin(async move { $fut.await }),
}
};
}

View File

@ -1,4 +1,3 @@
use flowy_infra::uuid;
use flowy_user::{
entities::{SignInParams, SignUpParams, UserDetail},
errors::{ErrorBuilder, UserError, UserErrorCode},

View File

@ -1,10 +1,10 @@
use crate::flowy_server::{ArcFlowyServer, FlowyServerMocker};
use flowy_database::DBConnection;
use flowy_dispatch::prelude::Module;
use flowy_user::{errors::UserError, prelude::*};
use flowy_dispatch::prelude::{DispatchFuture, Module};
use flowy_user::prelude::*;
use flowy_workspace::prelude::*;
use futures_core::future::BoxFuture;
use std::{pin::Pin, sync::Arc};
use std::sync::Arc;
pub struct ModuleConfig {
pub root: String,
@ -32,20 +32,26 @@ pub struct WorkspaceUserImpl {
}
impl WorkspaceUser for WorkspaceUserImpl {
fn set_current_workspace(&self, workspace_id: &str) -> BoxFuture<()> {
fn set_workspace(&self, workspace_id: &str) -> DispatchFuture<Result<(), WorkspaceError>> {
let user_session = self.user_session.clone();
let workspace_id = workspace_id.to_owned();
Box::pin(async move {
match user_session.set_current_workspace(&workspace_id).await {
Ok(_) => {},
Err(e) => {
log::error!("Set current workspace error: {:?}", e);
},
}
})
DispatchFuture {
fut: Box::pin(async move {
let _ = user_session
.set_current_workspace(&workspace_id)
.await
.map_err(|e| {
ErrorBuilder::new(WorkspaceErrorCode::UserInternalError)
.error(e)
.build()
});
Ok(())
}),
}
}
fn get_current_workspace(&self) -> Result<String, WorkspaceError> {
fn get_workspace(&self) -> Result<String, WorkspaceError> {
let user_detail = self.user_session.user_detail().map_err(|e| {
ErrorBuilder::new(WorkspaceErrorCode::UserNotLoginYet)
.error(e)

View File

@ -16,10 +16,11 @@ use std::marker::PhantomData;
pub type WorkspaceTestBuilder = TestBuilder<FixedUserTester<WorkspaceError>>;
impl WorkspaceTestBuilder {
pub fn new() -> Self {
Self {
let builder = Self {
tester: Box::new(FixedUserTester::<WorkspaceError>::new()),
user_detail: None,
}
};
builder.login()
}
}

View File

@ -14,7 +14,6 @@ use std::{
fmt::{Debug, Display},
hash::Hash,
sync::Arc,
thread,
};
pub struct TesterContext {

View File

@ -23,6 +23,35 @@ pub struct UpdateUserRequest {
pub password: Option<String>,
}
impl UpdateUserRequest {
pub fn new(id: &str) -> Self {
Self {
id: id.to_owned(),
..Default::default()
}
}
pub fn name(mut self, name: &str) -> Self {
self.name = Some(name.to_owned());
self
}
pub fn email(mut self, email: &str) -> Self {
self.email = Some(email.to_owned());
self
}
pub fn workspace(mut self, workspace: &str) -> Self {
self.workspace = Some(workspace.to_owned());
self
}
pub fn password(mut self, password: &str) -> Self {
self.password = Some(password.to_owned());
self
}
}
pub struct UpdateUserParams {
pub id: String,
pub name: Option<String>,

View File

@ -3,14 +3,7 @@ use flowy_database::{DBConnection, Database};
use lazy_static::lazy_static;
use once_cell::sync::Lazy;
use parking_lot::Mutex;
use std::{
cell::RefCell,
collections::HashMap,
sync::{
atomic::{AtomicBool, Ordering},
RwLock,
},
};
use std::{collections::HashMap, sync::RwLock};
lazy_static! {
static ref DB: RwLock<Option<Database>> = RwLock::new(None);

View File

@ -6,7 +6,7 @@ use flowy_database::{
UserDatabaseConnection,
};
use flowy_infra::kv::KVStore;
use lazy_static::lazy_static;
use std::sync::{Arc, RwLock};
use crate::{
@ -159,15 +159,10 @@ impl UserSession {
pub async fn set_current_workspace(&self, workspace_id: &str) -> Result<(), UserError> {
let user_id = self.get_user_id()?;
let payload: Vec<u8> = UpdateUserRequest {
id: user_id,
name: None,
email: None,
workspace: Some(workspace_id.to_owned()),
password: None,
}
.into_bytes()
.unwrap();
let payload: Vec<u8> = UpdateUserRequest::new(&user_id)
.workspace(workspace_id)
.into_bytes()
.unwrap();
let request = ModuleRequest::new(UpdateUser).payload(payload);
let _user_detail = EventDispatch::async_send(request)

View File

@ -1,10 +1,10 @@
use crate::{
entities::workspace::{CreateWorkspaceParams, CreateWorkspaceRequest, WorkspaceDetail},
errors::WorkspaceError,
services::{save_workspace, WorkspaceController},
services::WorkspaceController,
};
use flowy_dispatch::prelude::{response_ok, Data, EventResponse, ModuleData, ResponseResult};
use std::{convert::TryInto, pin::Pin, sync::Arc};
use flowy_dispatch::prelude::{response_ok, Data, ModuleData, ResponseResult};
use std::{convert::TryInto, sync::Arc};
pub async fn create_workspace(
data: Data<CreateWorkspaceRequest>,
@ -12,6 +12,16 @@ pub async fn create_workspace(
) -> ResponseResult<WorkspaceDetail, WorkspaceError> {
let controller = controller.get_ref().clone();
let params: CreateWorkspaceParams = data.into_inner().try_into()?;
let detail = save_workspace(controller, params).await?;
let detail = controller.save_workspace(params).await?;
response_ok(detail)
}
pub async fn workspace_user(
data: Data<CreateWorkspaceRequest>,
controller: ModuleData<Arc<WorkspaceController>>,
) -> ResponseResult<WorkspaceDetail, WorkspaceError> {
let controller = controller.get_ref().clone();
let params: CreateWorkspaceParams = data.into_inner().try_into()?;
let detail = controller.save_workspace(params).await?;
response_ok(detail)
}

View File

@ -13,6 +13,9 @@ mod services;
#[macro_use]
extern crate flowy_database;
#[macro_use]
extern crate flowy_dispatch;
pub mod prelude {
pub use crate::{errors::*, module::*, services::*};
}

View File

@ -3,16 +3,16 @@ use flowy_dispatch::prelude::*;
use crate::{
errors::WorkspaceError,
event::WorkspaceEvent,
handlers::create_workspace,
services::{AppController, WorkspaceController},
};
use flowy_database::DBConnection;
use futures_core::future::BoxFuture;
use crate::handlers::*;
use std::sync::Arc;
pub trait WorkspaceUser: Send + Sync {
fn set_current_workspace(&self, id: &str) -> BoxFuture<()>;
fn get_current_workspace(&self) -> Result<String, WorkspaceError>;
fn set_workspace(&self, id: &str) -> DispatchFuture<Result<(), WorkspaceError>>;
fn get_workspace(&self) -> Result<String, WorkspaceError>;
fn db_connection(&self) -> Result<DBConnection, WorkspaceError>;
}
@ -25,4 +25,5 @@ pub fn create(user: Arc<dyn WorkspaceUser>) -> Module {
.data(workspace_controller)
.data(app_controller)
.event(WorkspaceEvent::CreateWorkspace, create_workspace)
.event(WorkspaceEvent::GetWorkspaceUserDetail, workspace_user)
}

View File

@ -1,6 +1,6 @@
use crate::{entities::workspace::*, errors::*, module::WorkspaceUser, sql_tables::workspace::*};
use flowy_database::{prelude::*, schema::workspace_table};
use futures_core::future::BoxFuture;
use std::sync::Arc;
pub struct WorkspaceController {
@ -15,14 +15,13 @@ impl WorkspaceController {
params: CreateWorkspaceParams,
) -> Result<WorkspaceDetail, WorkspaceError> {
let workspace = Workspace::new(params);
let conn = self.user.db_connection()?;
let detail: WorkspaceDetail = workspace.clone().into();
let _ = diesel::insert_into(workspace_table::table)
.values(workspace)
.execute(&*conn)?;
.execute(&*(self.user.db_connection()?))?;
self.user.set_current_workspace(&detail.id);
let _ = self.user.set_workspace(&detail.id).await?;
Ok(detail)
}
@ -35,19 +34,3 @@ impl WorkspaceController {
Ok(())
}
}
pub async fn save_workspace(
controller: Arc<WorkspaceController>,
params: CreateWorkspaceParams,
) -> Result<WorkspaceDetail, WorkspaceError> {
let workspace = Workspace::new(params);
let detail: WorkspaceDetail = workspace.clone().into();
let _ = diesel::insert_into(workspace_table::table)
.values(workspace)
.execute(&*(controller.user.db_connection()?))?;
// set_current_workspace(controller.clone(), &detail.id).await;
Ok(detail)
}

View File

@ -13,7 +13,6 @@ fn workspace_create_success() {
};
let response = WorkspaceTestBuilder::new()
.login()
.event(CreateWorkspace)
.request(request)
.sync_send()