mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
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:
@ -65,56 +65,32 @@ impl Display for CollabPluginProviderContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait WorkspaceCollabIntegrate: Send + Sync {
|
||||
fn workspace_id(&self) -> Result<String, Error>;
|
||||
fn device_id(&self) -> Result<String, Error>;
|
||||
}
|
||||
|
||||
pub struct AppFlowyCollabBuilder {
|
||||
network_reachability: CollabConnectReachability,
|
||||
workspace_id: RwLock<Option<String>>,
|
||||
plugin_provider: RwLock<Arc<dyn CollabCloudPluginProvider>>,
|
||||
snapshot_persistence: Mutex<Option<Arc<dyn SnapshotPersistence>>>,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
rocksdb_backup: Mutex<Option<Arc<dyn RocksdbBackup>>>,
|
||||
device_id: String,
|
||||
}
|
||||
|
||||
pub struct CollabBuilderConfig {
|
||||
pub sync_enable: bool,
|
||||
/// If auto_initialize is false, the collab object will not be initialized automatically.
|
||||
/// You need to call collab.initialize() manually.
|
||||
///
|
||||
/// Default is true.
|
||||
pub auto_initialize: bool,
|
||||
}
|
||||
|
||||
impl Default for CollabBuilderConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
sync_enable: true,
|
||||
auto_initialize: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CollabBuilderConfig {
|
||||
pub fn sync_enable(mut self, sync_enable: bool) -> Self {
|
||||
self.sync_enable = sync_enable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn auto_initialize(mut self, auto_initialize: bool) -> Self {
|
||||
self.auto_initialize = auto_initialize;
|
||||
self
|
||||
}
|
||||
workspace_integrate: Arc<dyn WorkspaceCollabIntegrate>,
|
||||
}
|
||||
|
||||
impl AppFlowyCollabBuilder {
|
||||
pub fn new<T: CollabCloudPluginProvider>(storage_provider: T, device_id: String) -> Self {
|
||||
pub fn new(
|
||||
storage_provider: impl CollabCloudPluginProvider + 'static,
|
||||
workspace_integrate: impl WorkspaceCollabIntegrate + 'static,
|
||||
) -> Self {
|
||||
Self {
|
||||
network_reachability: CollabConnectReachability::new(),
|
||||
workspace_id: Default::default(),
|
||||
plugin_provider: RwLock::new(Arc::new(storage_provider)),
|
||||
snapshot_persistence: Default::default(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
rocksdb_backup: Default::default(),
|
||||
device_id,
|
||||
workspace_integrate: Arc::new(workspace_integrate),
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,10 +103,6 @@ impl AppFlowyCollabBuilder {
|
||||
*self.rocksdb_backup.lock() = Some(rocksdb_backup);
|
||||
}
|
||||
|
||||
pub fn initialize(&self, workspace_id: String) {
|
||||
*self.workspace_id.write() = Some(workspace_id);
|
||||
}
|
||||
|
||||
pub fn update_network(&self, reachable: bool) {
|
||||
if reachable {
|
||||
self
|
||||
@ -149,15 +121,14 @@ impl AppFlowyCollabBuilder {
|
||||
object_id: &str,
|
||||
collab_type: CollabType,
|
||||
) -> Result<CollabObject, Error> {
|
||||
let workspace_id = self.workspace_id.read().clone().ok_or_else(|| {
|
||||
anyhow::anyhow!("When using supabase plugin, the workspace_id should not be empty")
|
||||
})?;
|
||||
let device_id = self.workspace_integrate.device_id()?;
|
||||
let workspace_id = self.workspace_integrate.workspace_id()?;
|
||||
Ok(CollabObject::new(
|
||||
uid,
|
||||
object_id.to_string(),
|
||||
collab_type,
|
||||
workspace_id,
|
||||
self.device_id.clone(),
|
||||
device_id,
|
||||
))
|
||||
}
|
||||
|
||||
@ -175,8 +146,10 @@ impl AppFlowyCollabBuilder {
|
||||
/// - `raw_data`: The raw data of the collaboration object, defined by the [CollabDocState] type.
|
||||
/// - `collab_db`: A weak reference to the [CollabKVDB].
|
||||
///
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn build(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
uid: i64,
|
||||
object_id: &str,
|
||||
object_type: CollabType,
|
||||
@ -184,14 +157,13 @@ impl AppFlowyCollabBuilder {
|
||||
collab_db: Weak<CollabKVDB>,
|
||||
build_config: CollabBuilderConfig,
|
||||
) -> Result<Arc<MutexCollab>, Error> {
|
||||
let persistence_config = CollabPersistenceConfig::default();
|
||||
self.build_with_config(
|
||||
workspace_id,
|
||||
uid,
|
||||
object_id,
|
||||
object_type,
|
||||
collab_db,
|
||||
collab_doc_state,
|
||||
persistence_config,
|
||||
build_config,
|
||||
)
|
||||
}
|
||||
@ -211,25 +183,34 @@ impl AppFlowyCollabBuilder {
|
||||
/// - `collab_db`: A weak reference to the [CollabKVDB].
|
||||
///
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[instrument(
|
||||
level = "trace",
|
||||
skip(self, collab_db, collab_doc_state, persistence_config, build_config)
|
||||
)]
|
||||
#[instrument(level = "trace", skip(self, collab_db, collab_doc_state, build_config))]
|
||||
pub fn build_with_config(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
uid: i64,
|
||||
object_id: &str,
|
||||
object_type: CollabType,
|
||||
collab_db: Weak<CollabKVDB>,
|
||||
collab_doc_state: DataSource,
|
||||
#[allow(unused_variables)] persistence_config: CollabPersistenceConfig,
|
||||
build_config: CollabBuilderConfig,
|
||||
) -> Result<Arc<MutexCollab>, Error> {
|
||||
let collab = CollabBuilder::new(uid, object_id)
|
||||
.with_doc_state(collab_doc_state)
|
||||
.with_device_id(self.device_id.clone())
|
||||
.with_device_id(self.workspace_integrate.device_id()?)
|
||||
.build()?;
|
||||
|
||||
// Compare the workspace_id with the currently opened workspace_id. Return an error if they do not match.
|
||||
// This check is crucial in asynchronous code contexts where the workspace_id might change during operation.
|
||||
let actual_workspace_id = self.workspace_integrate.workspace_id()?;
|
||||
if workspace_id != actual_workspace_id {
|
||||
return Err(anyhow::anyhow!(
|
||||
"workspace_id not match when build collab. expect workspace_id: {}, actual workspace_id: {}",
|
||||
workspace_id,
|
||||
actual_workspace_id
|
||||
));
|
||||
}
|
||||
let persistence_config = CollabPersistenceConfig::default();
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
collab.lock().add_plugin(Box::new(IndexeddbDiskPlugin::new(
|
||||
@ -317,3 +298,33 @@ impl AppFlowyCollabBuilder {
|
||||
Ok(arc_collab)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CollabBuilderConfig {
|
||||
pub sync_enable: bool,
|
||||
/// If auto_initialize is false, the collab object will not be initialized automatically.
|
||||
/// You need to call collab.initialize() manually.
|
||||
///
|
||||
/// Default is true.
|
||||
pub auto_initialize: bool,
|
||||
}
|
||||
|
||||
impl Default for CollabBuilderConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
sync_enable: true,
|
||||
auto_initialize: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CollabBuilderConfig {
|
||||
pub fn sync_enable(mut self, sync_enable: bool) -> Self {
|
||||
self.sync_enable = sync_enable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn auto_initialize(mut self, auto_initialize: bool) -> Self {
|
||||
self.auto_initialize = auto_initialize;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderType};
|
||||
use collab::preclude::CollabPlugin;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait CollabCloudPluginProvider: Send + Sync + 'static {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub trait CollabCloudPluginProvider: 'static {
|
||||
fn provider_type(&self) -> CollabPluginProviderType;
|
||||
|
||||
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>>;
|
||||
@ -10,7 +10,35 @@ pub trait CollabCloudPluginProvider: Send + Sync + 'static {
|
||||
fn is_sync_enabled(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<T> CollabCloudPluginProvider for Arc<T>
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
impl<T> CollabCloudPluginProvider for std::rc::Rc<T>
|
||||
where
|
||||
T: CollabCloudPluginProvider,
|
||||
{
|
||||
fn provider_type(&self) -> CollabPluginProviderType {
|
||||
(**self).provider_type()
|
||||
}
|
||||
|
||||
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
|
||||
(**self).get_plugins(context)
|
||||
}
|
||||
|
||||
fn is_sync_enabled(&self) -> bool {
|
||||
(**self).is_sync_enabled()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub trait CollabCloudPluginProvider: Send + Sync + 'static {
|
||||
fn provider_type(&self) -> CollabPluginProviderType;
|
||||
|
||||
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>>;
|
||||
|
||||
fn is_sync_enabled(&self) -> bool;
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
impl<T> CollabCloudPluginProvider for std::sync::Arc<T>
|
||||
where
|
||||
T: CollabCloudPluginProvider,
|
||||
{
|
||||
|
Reference in New Issue
Block a user