chore: checking workspace state consistent after switching workspace (#5201)

* refactor: getting workspace id

* refactor: check workspace id is match for http response

* refactor: check http repsonse in valid by checing the workspace id

* chore: update log

* chore: fix test

* chore: fix test

* chore: add test

* chore: update test
This commit is contained in:
Nathan.fooo
2024-04-26 09:44:07 +08:00
committed by GitHub
parent 65a289648e
commit cc66147bc0
51 changed files with 980 additions and 575 deletions

View File

@ -9,8 +9,9 @@ use flowy_sqlite::{
};
use flowy_user::services::authenticate_user::AuthenticateUser;
use collab_integrate::collab_builder::WorkspaceCollabIntegrate;
use lib_infra::util::timestamp;
use std::sync::Weak;
use std::sync::{Arc, Weak};
use tracing::debug;
pub struct SnapshotDBImpl(pub Weak<AuthenticateUser>);
@ -207,3 +208,26 @@ impl CollabSnapshotSql {
Ok(())
}
}
pub(crate) struct WorkspaceCollabIntegrateImpl(pub Weak<AuthenticateUser>);
impl WorkspaceCollabIntegrateImpl {
fn upgrade_user(&self) -> Result<Arc<AuthenticateUser>, FlowyError> {
let user = self
.0
.upgrade()
.ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))?;
Ok(user)
}
}
impl WorkspaceCollabIntegrate for WorkspaceCollabIntegrateImpl {
fn workspace_id(&self) -> Result<String, anyhow::Error> {
let workspace_id = self.upgrade_user()?.workspace_id()?;
Ok(workspace_id)
}
fn device_id(&self) -> Result<String, anyhow::Error> {
Ok(self.upgrade_user()?.user_config.device_id.clone())
}
}

View File

@ -27,20 +27,30 @@ impl DatabaseDepsResolver {
}
struct DatabaseUserImpl(Weak<AuthenticateUser>);
impl DatabaseUser for DatabaseUserImpl {
fn user_id(&self) -> Result<i64, FlowyError> {
self
impl DatabaseUserImpl {
fn upgrade_user(&self) -> Result<Arc<AuthenticateUser>, FlowyError> {
let user = self
.0
.upgrade()
.ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))?
.user_id()
.ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))?;
Ok(user)
}
}
impl DatabaseUser for DatabaseUserImpl {
fn user_id(&self) -> Result<i64, FlowyError> {
self.upgrade_user()?.user_id()
}
fn collab_db(&self, uid: i64) -> Result<Weak<CollabKVDB>, FlowyError> {
self
.0
.upgrade()
.ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))?
.get_collab_db(uid)
self.upgrade_user()?.get_collab_db(uid)
}
fn workspace_id(&self) -> Result<String, FlowyError> {
self.upgrade_user()?.workspace_id()
}
fn workspace_database_object_id(&self) -> Result<String, FlowyError> {
self.upgrade_user()?.workspace_database_object_id()
}
}

View File

@ -18,7 +18,6 @@ use flowy_folder_pub::folder_builder::NestedViewBuilder;
use flowy_search::folder::indexer::FolderIndexManagerImpl;
use flowy_user::services::authenticate_user::AuthenticateUser;
use lib_dispatch::prelude::ToBytes;
use lib_infra::async_trait::async_trait;
use lib_infra::future::FutureResult;
use std::collections::HashMap;
use std::convert::TryFrom;
@ -76,22 +75,27 @@ struct FolderUserImpl {
authenticate_user: Weak<AuthenticateUser>,
}
#[async_trait]
impl FolderUser for FolderUserImpl {
fn user_id(&self) -> Result<i64, FlowyError> {
self
impl FolderUserImpl {
fn upgrade_user(&self) -> Result<Arc<AuthenticateUser>, FlowyError> {
let user = self
.authenticate_user
.upgrade()
.ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))?
.user_id()
.ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))?;
Ok(user)
}
}
impl FolderUser for FolderUserImpl {
fn user_id(&self) -> Result<i64, FlowyError> {
self.upgrade_user()?.user_id()
}
fn workspace_id(&self) -> Result<String, FlowyError> {
self.upgrade_user()?.workspace_id()
}
fn collab_db(&self, uid: i64) -> Result<Weak<CollabKVDB>, FlowyError> {
self
.authenticate_user
.upgrade()
.ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))?
.get_collab_db(uid)
self.upgrade_user()?.get_collab_db(uid)
}
}

View File

@ -6,6 +6,7 @@ use parking_lot::RwLock;
use serde_repr::*;
use flowy_error::{FlowyError, FlowyResult};
use flowy_server::af_cloud::define::ServerUser;
use flowy_server::af_cloud::AppFlowyCloudServer;
use flowy_server::local_server::{LocalServer, LocalServerDB};
use flowy_server::supabase::SupabaseServer;
@ -63,6 +64,7 @@ pub struct ServerProvider {
/// The authenticator type of the user.
authenticator: RwLock<Authenticator>,
user: Arc<dyn ServerUser>,
pub(crate) uid: Arc<RwLock<Option<i64>>>,
}
@ -71,7 +73,9 @@ impl ServerProvider {
config: AppFlowyCoreConfig,
server: Server,
store_preferences: Weak<StorePreferences>,
server_user: impl ServerUser + 'static,
) -> Self {
let user = Arc::new(server_user);
let encryption = EncryptionImpl::new(None);
Self {
config,
@ -81,6 +85,7 @@ impl ServerProvider {
encryption: RwLock::new(Arc::new(encryption)),
store_preferences,
uid: Default::default(),
user,
}
}
@ -129,6 +134,7 @@ impl ServerProvider {
*self.user_enable_sync.read(),
self.config.device_id.clone(),
&self.config.app_version,
self.user.clone(),
));
Ok::<Arc<dyn AppFlowyServer>, FlowyError>(server)

View File

@ -38,7 +38,6 @@ impl UserStatusCallback for UserStatusCallbackImpl {
) -> Fut<FlowyResult<()>> {
let user_id = user_id.to_owned();
let user_workspace = user_workspace.clone();
let collab_builder = self.collab_builder.clone();
let folder_manager = self.folder_manager.clone();
let database_manager = self.database_manager.clone();
let document_manager = self.document_manager.clone();
@ -59,7 +58,6 @@ impl UserStatusCallback for UserStatusCallbackImpl {
}
to_fut(async move {
collab_builder.initialize(user_workspace.id.clone());
folder_manager
.initialize(
user_id,
@ -69,16 +67,8 @@ impl UserStatusCallback for UserStatusCallbackImpl {
},
)
.await?;
database_manager
.initialize(
user_id,
user_workspace.id.clone(),
user_workspace.workspace_database_object_id,
)
.await?;
document_manager
.initialize(user_id, user_workspace.id)
.await?;
database_manager.initialize(user_id).await?;
document_manager.initialize(user_id).await?;
Ok(())
})
}
@ -104,19 +94,9 @@ impl UserStatusCallback for UserStatusCallbackImpl {
device_id
);
folder_manager
.initialize_with_workspace_id(user_id, &user_workspace.id)
.await?;
database_manager
.initialize(
user_id,
user_workspace.id.clone(),
user_workspace.workspace_database_object_id,
)
.await?;
document_manager
.initialize(user_id, user_workspace.id)
.await?;
folder_manager.initialize_with_workspace_id(user_id).await?;
database_manager.initialize(user_id).await?;
document_manager.initialize(user_id).await?;
Ok(())
})
}
@ -199,16 +179,12 @@ impl UserStatusCallback for UserStatusCallbackImpl {
.context("FolderManager error")?;
database_manager
.initialize_with_new_user(
user_profile.uid,
user_workspace.id.clone(),
user_workspace.workspace_database_object_id,
)
.initialize_with_new_user(user_profile.uid)
.await
.context("DatabaseManager error")?;
document_manager
.initialize_with_new_user(user_profile.uid, user_workspace.id)
.initialize_with_new_user(user_profile.uid)
.await
.context("DocumentManager error")?;
Ok(())
@ -223,29 +199,15 @@ impl UserStatusCallback for UserStatusCallbackImpl {
})
}
fn open_workspace(&self, user_id: i64, user_workspace: &UserWorkspace) -> Fut<FlowyResult<()>> {
let user_workspace = user_workspace.clone();
let collab_builder = self.collab_builder.clone();
fn open_workspace(&self, user_id: i64, _user_workspace: &UserWorkspace) -> Fut<FlowyResult<()>> {
let folder_manager = self.folder_manager.clone();
let database_manager = self.database_manager.clone();
let document_manager = self.document_manager.clone();
to_fut(async move {
collab_builder.initialize(user_workspace.id.clone());
folder_manager
.initialize_with_workspace_id(user_id, &user_workspace.id)
.await?;
database_manager
.initialize(
user_id,
user_workspace.id.clone(),
user_workspace.workspace_database_object_id,
)
.await?;
document_manager
.initialize(user_id, user_workspace.id)
.await?;
folder_manager.initialize_with_workspace_id(user_id).await?;
database_manager.initialize(user_id).await?;
document_manager.initialize(user_id).await?;
Ok(())
})
}

View File

@ -4,7 +4,7 @@ use flowy_search::folder::indexer::FolderIndexManagerImpl;
use flowy_search::services::manager::SearchManager;
use flowy_storage::ObjectStorageService;
use semver::Version;
use std::sync::Arc;
use std::sync::{Arc, Weak};
use std::time::Duration;
use sysinfo::System;
use tokio::sync::RwLock;
@ -13,7 +13,9 @@ use tracing::{debug, error, event, info, instrument};
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabPluginProviderType};
use flowy_database2::DatabaseManager;
use flowy_document::manager::DocumentManager;
use flowy_error::{FlowyError, FlowyResult};
use flowy_folder::manager::FolderManager;
use flowy_server::af_cloud::define::ServerUser;
use flowy_sqlite::kv::StorePreferences;
use flowy_user::services::authenticate_user::AuthenticateUser;
@ -104,14 +106,29 @@ impl AppFlowyCore {
let task_dispatcher = Arc::new(RwLock::new(task_scheduler));
runtime.spawn(TaskRunner::run(task_dispatcher.clone()));
let app_version = Version::parse(&config.app_version).unwrap_or_else(|_| Version::new(0, 5, 4));
let user_config = UserConfig::new(
&config.name,
&config.storage_path,
&config.application_path,
&config.device_id,
app_version,
);
let authenticate_user = Arc::new(AuthenticateUser::new(
user_config.clone(),
store_preference.clone(),
));
let server_type = current_server_type();
debug!("🔥runtime:{}, server:{}", runtime, server_type);
let server_provider = Arc::new(ServerProvider::new(
config.clone(),
server_type,
Arc::downgrade(&store_preference),
ServerUserImpl(Arc::downgrade(&authenticate_user)),
));
let app_version = Version::parse(&config.app_version).unwrap_or_else(|_| Version::new(0, 5, 4));
event!(tracing::Level::DEBUG, "Init managers",);
let (
@ -127,20 +144,7 @@ impl AppFlowyCore {
/// on demand based on the [CollabPluginConfig].
let collab_builder = Arc::new(AppFlowyCollabBuilder::new(
server_provider.clone(),
config.device_id.clone(),
));
let user_config = UserConfig::new(
&config.name,
&config.storage_path,
&config.application_path,
&config.device_id,
app_version,
);
let authenticate_user = Arc::new(AuthenticateUser::new(
user_config.clone(),
store_preference.clone(),
WorkspaceCollabIntegrateImpl(Arc::downgrade(&authenticate_user)),
));
collab_builder
@ -260,3 +264,20 @@ impl From<Server> for CollabPluginProviderType {
}
}
}
struct ServerUserImpl(Weak<AuthenticateUser>);
impl ServerUserImpl {
fn upgrade_user(&self) -> Result<Arc<AuthenticateUser>, FlowyError> {
let user = self
.0
.upgrade()
.ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))?;
Ok(user)
}
}
impl ServerUser for ServerUserImpl {
fn workspace_id(&self) -> FlowyResult<String> {
self.upgrade_user()?.workspace_id()
}
}