mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-09-11 19:17:43 +03:00
find out how to nested the future into handler
This commit is contained in:
parent
84931e7cc6
commit
e1f73f5246
@ -86,6 +86,9 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra_ui/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra_ui/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra_ui/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra_ui/example/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra_ui/example/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra_ui/example/.pub" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
@ -1,6 +1,8 @@
|
||||
PODS:
|
||||
- flowy_editor (0.0.1):
|
||||
- FlutterMacOS
|
||||
- flowy_infra_ui (0.0.1):
|
||||
- FlutterMacOS
|
||||
- flowy_sdk (0.0.1):
|
||||
- FlutterMacOS
|
||||
- FlutterMacOS (1.0.0)
|
||||
@ -13,6 +15,7 @@ PODS:
|
||||
|
||||
DEPENDENCIES:
|
||||
- flowy_editor (from `Flutter/ephemeral/.symlinks/plugins/flowy_editor/macos`)
|
||||
- flowy_infra_ui (from `Flutter/ephemeral/.symlinks/plugins/flowy_infra_ui/macos`)
|
||||
- flowy_sdk (from `Flutter/ephemeral/.symlinks/plugins/flowy_sdk/macos`)
|
||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||
- path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`)
|
||||
@ -22,6 +25,8 @@ DEPENDENCIES:
|
||||
EXTERNAL SOURCES:
|
||||
flowy_editor:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/flowy_editor/macos
|
||||
flowy_infra_ui:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/flowy_infra_ui/macos
|
||||
flowy_sdk:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/flowy_sdk/macos
|
||||
FlutterMacOS:
|
||||
@ -35,6 +40,7 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
flowy_editor: 26060a984848e6afac1f6a4455511f4114119d8d
|
||||
flowy_infra_ui: 9d5021b1610fe0476eb1191bf7cd41c4a4138d8f
|
||||
flowy_sdk: c302ac0a22dea596db0df8073b9637b2bf2ff6fd
|
||||
FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424
|
||||
path_provider_macos: a0a3fd666cb7cd0448e936fb4abad4052961002b
|
||||
|
@ -15,6 +15,7 @@ flowy-workspace = { path = "../flowy-workspace" }
|
||||
flowy-database = { path = "../flowy-database" }
|
||||
tracing = { version = "0.1" }
|
||||
log = "0.4.14"
|
||||
futures-core = { version = "0.3", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
@ -1,11 +1,10 @@
|
||||
use flowy_dispatch::prelude::Module;
|
||||
use flowy_user::prelude::*;
|
||||
|
||||
use crate::flowy_server::{ArcFlowyServer, FlowyServerMocker};
|
||||
use flowy_database::DBConnection;
|
||||
|
||||
use flowy_dispatch::prelude::Module;
|
||||
use flowy_user::{errors::UserError, prelude::*};
|
||||
use flowy_workspace::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use futures_core::future::BoxFuture;
|
||||
use std::{pin::Pin, sync::Arc};
|
||||
|
||||
pub struct ModuleConfig {
|
||||
pub root: String,
|
||||
@ -33,7 +32,18 @@ pub struct WorkspaceUserImpl {
|
||||
}
|
||||
|
||||
impl WorkspaceUser for WorkspaceUserImpl {
|
||||
fn set_current_workspace(&self, id: &str) { UserSession::set_current_workspace(id); }
|
||||
fn set_current_workspace(&self, workspace_id: &str) -> BoxFuture<()> {
|
||||
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);
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn get_current_workspace(&self) -> Result<String, WorkspaceError> {
|
||||
let user_detail = self.user_session.user_detail().map_err(|e| {
|
||||
|
@ -28,7 +28,11 @@ impl UserDB {
|
||||
}
|
||||
|
||||
fn open_user_db(&self, user_id: &str) -> Result<(), UserError> {
|
||||
set_user_db_init(true, user_id);
|
||||
if user_id.is_empty() {
|
||||
return Err(ErrorBuilder::new(UserErrorCode::DatabaseInitFailed)
|
||||
.msg("user id is empty")
|
||||
.build());
|
||||
}
|
||||
|
||||
let dir = format!("{}/{}", self.db_dir, user_id);
|
||||
let db = flowy_database::init(&dir).map_err(|e| {
|
||||
@ -48,21 +52,20 @@ impl UserDB {
|
||||
}
|
||||
|
||||
pub(crate) fn close_user_db(&self, user_id: &str) -> Result<(), UserError> {
|
||||
set_user_db_init(false, user_id);
|
||||
|
||||
let mut db_map = DB_MAP.write().map_err(|e| {
|
||||
ErrorBuilder::new(UserErrorCode::DatabaseWriteLocked)
|
||||
.msg(format!("Close user db failed. {:?}", e))
|
||||
.build()
|
||||
})?;
|
||||
|
||||
set_user_db_init(false, user_id);
|
||||
db_map.remove(user_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn get_connection(&self, user_id: &str) -> Result<DBConnection, UserError> {
|
||||
if !is_user_db_init(user_id) {
|
||||
let _ = self.open_user_db(user_id);
|
||||
let _ = self.open_user_db(user_id)?;
|
||||
set_user_db_init(true, user_id);
|
||||
}
|
||||
|
||||
let db_map = DB_MAP.read().map_err(|e| {
|
||||
@ -73,7 +76,7 @@ impl UserDB {
|
||||
|
||||
match db_map.get(user_id) {
|
||||
None => Err(ErrorBuilder::new(UserErrorCode::DatabaseInitFailed)
|
||||
.msg("Database is not initialization")
|
||||
.msg("Get connection failed. The database is not initialization")
|
||||
.build()),
|
||||
Some(database) => Ok(database.get_connection()?),
|
||||
}
|
||||
@ -86,10 +89,8 @@ lazy_static! {
|
||||
|
||||
static INIT_FLAG_MAP: Lazy<Mutex<HashMap<String, bool>>> = Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
fn set_user_db_init(is_init: bool, user_id: &str) {
|
||||
INIT_FLAG_MAP
|
||||
.lock()
|
||||
.entry(user_id.to_owned())
|
||||
.or_insert_with(|| is_init);
|
||||
let mut flag_map = INIT_FLAG_MAP.lock();
|
||||
flag_map.insert(user_id.to_owned(), is_init);
|
||||
}
|
||||
|
||||
fn is_user_db_init(user_id: &str) -> bool {
|
||||
|
@ -34,6 +34,7 @@ pub struct UserSession {
|
||||
database: UserDB,
|
||||
config: UserSessionConfig,
|
||||
server: Arc<dyn UserServer + Send + Sync>,
|
||||
user_id: RwLock<Option<String>>,
|
||||
}
|
||||
|
||||
impl UserSession {
|
||||
@ -46,28 +47,30 @@ impl UserSession {
|
||||
database: db,
|
||||
config,
|
||||
server,
|
||||
user_id: RwLock::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_db_connection(&self) -> Result<DBConnection, UserError> {
|
||||
let user_id = get_current_user_id()?;
|
||||
let user_id = self.get_user_id()?;
|
||||
self.database.get_connection(&user_id)
|
||||
}
|
||||
|
||||
pub fn sign_in(&self, params: SignInParams) -> Result<User, UserError> {
|
||||
let user = self.server.sign_in(params)?;
|
||||
let _ = set_current_user_id(Some(user.id.clone()))?;
|
||||
let _ = self.set_user_id(Some(user.id.clone()))?;
|
||||
|
||||
self.save_user(user)
|
||||
}
|
||||
|
||||
pub fn sign_up(&self, params: SignUpParams) -> Result<User, UserError> {
|
||||
let user = self.server.sign_up(params)?;
|
||||
let _ = set_current_user_id(Some(user.id.clone()))?;
|
||||
let _ = self.set_user_id(Some(user.id.clone()))?;
|
||||
self.save_user(user)
|
||||
}
|
||||
|
||||
pub fn sign_out(&self) -> Result<(), UserError> {
|
||||
let user_id = current_user_id()?;
|
||||
let user_id = self.get_user_id()?;
|
||||
let conn = self.get_db_connection()?;
|
||||
let _ = diesel::delete(dsl::user_table.filter(dsl::id.eq(&user_id))).execute(&*conn)?;
|
||||
|
||||
@ -76,7 +79,7 @@ impl UserSession {
|
||||
Err(_) => {},
|
||||
}
|
||||
let _ = self.database.close_user_db(&user_id)?;
|
||||
let _ = set_current_user_id(None)?;
|
||||
let _ = self.set_user_id(None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -100,7 +103,7 @@ impl UserSession {
|
||||
}
|
||||
|
||||
pub fn user_detail(&self) -> Result<UserDetail, UserError> {
|
||||
let user_id = current_user_id()?;
|
||||
let user_id = self.get_user_id()?;
|
||||
let conn = self.get_db_connection()?;
|
||||
|
||||
let user = dsl::user_table
|
||||
@ -118,16 +121,49 @@ impl UserSession {
|
||||
|
||||
Ok(UserDetail::from(user))
|
||||
}
|
||||
}
|
||||
|
||||
impl UserSession {
|
||||
pub async fn set_current_workspace(workspace: &str) -> Result<(), UserError> {
|
||||
let user_id = current_user_id()?;
|
||||
pub fn set_user_id(&self, user_id: Option<String>) -> Result<(), UserError> {
|
||||
log::trace!("Set user id: {:?}", user_id);
|
||||
KVStore::set_str(USER_ID_CACHE_KEY, user_id.clone().unwrap_or("".to_owned()));
|
||||
match self.user_id.write() {
|
||||
Ok(mut write_guard) => {
|
||||
*write_guard = user_id;
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => Err(ErrorBuilder::new(UserErrorCode::WriteCurrentIdFailed)
|
||||
.error(e)
|
||||
.build()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_user_id(&self) -> Result<String, UserError> {
|
||||
let read_guard = self.user_id.read().map_err(|e| {
|
||||
ErrorBuilder::new(UserErrorCode::ReadCurrentIdFailed)
|
||||
.error(e)
|
||||
.build()
|
||||
})?;
|
||||
|
||||
let mut user_id = (*read_guard).clone();
|
||||
drop(read_guard);
|
||||
|
||||
if user_id.is_none() {
|
||||
user_id = KVStore::get_str(USER_ID_CACHE_KEY);
|
||||
self.set_user_id(user_id.clone());
|
||||
}
|
||||
|
||||
match user_id {
|
||||
None => Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build()),
|
||||
Some(user_id) => Ok(user_id),
|
||||
}
|
||||
}
|
||||
|
||||
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.to_owned()),
|
||||
workspace: Some(workspace_id.to_owned()),
|
||||
password: None,
|
||||
}
|
||||
.into_bytes()
|
||||
@ -144,7 +180,7 @@ impl UserSession {
|
||||
}
|
||||
|
||||
pub fn current_user_id() -> Result<String, UserError> {
|
||||
match KVStore::get_str(USER_ID_DISK_CACHE_KEY) {
|
||||
match KVStore::get_str(USER_ID_CACHE_KEY) {
|
||||
None => Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build()),
|
||||
Some(user_id) => Ok(user_id),
|
||||
}
|
||||
@ -156,48 +192,4 @@ impl UserDatabaseConnection for UserSession {
|
||||
}
|
||||
}
|
||||
|
||||
const USER_ID_DISK_CACHE_KEY: &str = "user_id";
|
||||
lazy_static! {
|
||||
pub static ref CURRENT_USER_ID: RwLock<Option<String>> = RwLock::new(None);
|
||||
}
|
||||
|
||||
pub(crate) fn get_current_user_id() -> Result<String, UserError> {
|
||||
let read_guard = CURRENT_USER_ID.read().map_err(|e| {
|
||||
ErrorBuilder::new(UserErrorCode::ReadCurrentIdFailed)
|
||||
.error(e)
|
||||
.build()
|
||||
})?;
|
||||
|
||||
let mut user_id = (*read_guard).clone();
|
||||
// explicitly drop the read_guard in case of dead lock
|
||||
drop(read_guard);
|
||||
|
||||
if user_id.is_none() {
|
||||
user_id = KVStore::get_str(USER_ID_DISK_CACHE_KEY);
|
||||
*(CURRENT_USER_ID.write().unwrap()) = user_id.clone();
|
||||
}
|
||||
|
||||
if user_id.is_none() {
|
||||
return Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build());
|
||||
}
|
||||
|
||||
match user_id {
|
||||
None => Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build()),
|
||||
Some(user_id) => Ok(user_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_current_user_id(user_id: Option<String>) -> Result<(), UserError> {
|
||||
KVStore::set_str(
|
||||
USER_ID_DISK_CACHE_KEY,
|
||||
user_id.clone().unwrap_or("".to_owned()),
|
||||
);
|
||||
|
||||
let mut current_user_id = CURRENT_USER_ID.write().map_err(|e| {
|
||||
ErrorBuilder::new(UserErrorCode::WriteCurrentIdFailed)
|
||||
.error(e)
|
||||
.build()
|
||||
})?;
|
||||
*current_user_id = user_id;
|
||||
Ok(())
|
||||
}
|
||||
const USER_ID_CACHE_KEY: &str = "user_id";
|
||||
|
@ -16,6 +16,8 @@ protobuf = {version = "2.18.0"}
|
||||
log = "0.4.14"
|
||||
diesel = {version = "1.4.7", features = ["sqlite"]}
|
||||
diesel_derives = {version = "1.4.1", features = ["sqlite"]}
|
||||
futures-core = { version = "0.3", default-features = false }
|
||||
pin-project = "1.0.0"
|
||||
|
||||
lazy_static = "1.4.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
@ -1,16 +1,17 @@
|
||||
use crate::{
|
||||
entities::workspace::{CreateWorkspaceParams, CreateWorkspaceRequest, WorkspaceDetail},
|
||||
errors::WorkspaceError,
|
||||
services::WorkspaceController,
|
||||
services::{save_workspace, WorkspaceController},
|
||||
};
|
||||
use flowy_dispatch::prelude::{response_ok, Data, ModuleData, ResponseResult};
|
||||
use std::{convert::TryInto, sync::Arc};
|
||||
use flowy_dispatch::prelude::{response_ok, Data, EventResponse, ModuleData, ResponseResult};
|
||||
use std::{convert::TryInto, pin::Pin, sync::Arc};
|
||||
|
||||
pub async fn create_workspace(
|
||||
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)?;
|
||||
let detail = save_workspace(controller, params).await?;
|
||||
response_ok(detail)
|
||||
}
|
||||
|
@ -7,10 +7,11 @@ use crate::{
|
||||
services::{AppController, WorkspaceController},
|
||||
};
|
||||
use flowy_database::DBConnection;
|
||||
use futures_core::future::BoxFuture;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait WorkspaceUser: Send + Sync {
|
||||
fn set_current_workspace(&self, id: &str);
|
||||
fn set_current_workspace(&self, id: &str) -> BoxFuture<()>;
|
||||
fn get_current_workspace(&self) -> Result<String, WorkspaceError>;
|
||||
fn db_connection(&self) -> Result<DBConnection, WorkspaceError>;
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
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 {
|
||||
pub(crate) user: Arc<dyn WorkspaceUser>,
|
||||
pub user: Arc<dyn WorkspaceUser>,
|
||||
}
|
||||
|
||||
impl WorkspaceController {
|
||||
pub fn new(user: Arc<dyn WorkspaceUser>) -> Self { Self { user } }
|
||||
|
||||
pub fn save_workspace(
|
||||
pub async fn save_workspace(
|
||||
&self,
|
||||
params: CreateWorkspaceParams,
|
||||
) -> Result<WorkspaceDetail, WorkspaceError> {
|
||||
@ -34,3 +35,19 @@ 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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user