feat: cloud workspace api (#4469)

* feat: workspace api

* feat: added cloud apis for add and delete workspace

* feat: add and delete workspace event handlers

* chore: rust fmt

* chore: save user workspace

* test: add test

* test: add test

* chore: add to gitignore

* feat: update api add name to workspace

* chore: cargo clippy and rename to create

* chore: add envrc and direnv to gitignore

* chore: change name to create workspace instead of add workspace

* chore: update client api rev

* feat: add create workspace impl

* chore: restore gitignore to original

* test: fix create workspace event test

* fix: change delete workspace input

* fix: compile

* fix: create workspace test

* feat: add error code for request payload too large

* chore: remove cargo backup files

* feat: add is async option for upload file handler

* chore: update client api version

---------

Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
Zack
2024-02-04 05:49:45 +08:00
committed by GitHub
parent 250f29f325
commit 08938b8c70
46 changed files with 457 additions and 128 deletions

View File

@ -76,16 +76,21 @@ impl DatabaseManager {
}
}
/// When initialize with new workspace, all the resources will be cleared.
pub async fn initialize(
&self,
uid: i64,
workspace_id: String,
workspace_database_object_id: String,
) -> FlowyResult<()> {
// Clear all existing tasks
// 1. Clear all existing tasks
self.task_scheduler.write().await.clear_task();
// Release all existing editors
// 2. Release all existing editors
for (_, editor) in self.editors.lock().await.iter() {
editor.close().await;
}
self.editors.lock().await.clear();
// 3. Clear the workspace database
*self.workspace_database.write().await = None;
let collab_db = self.user.collab_db(uid)?;
@ -95,22 +100,22 @@ impl DatabaseManager {
cloud_service: self.cloud_service.clone(),
};
let config = CollabPersistenceConfig::new().snapshot_per_update(100);
let mut collab_raw_data = CollabDocState::default();
let mut workspace_database_doc_state = CollabDocState::default();
// If the workspace database not exist in disk, try to fetch from remote.
if !self.is_collab_exist(uid, &collab_db, &workspace_database_object_id) {
trace!("workspace database not exist, try to fetch from remote");
match self
.cloud_service
.get_collab_doc_state_db(
.get_database_object_doc_state(
&workspace_database_object_id,
CollabType::WorkspaceDatabase,
&workspace_id,
)
.await
{
Ok(updates) => {
collab_raw_data = updates;
Ok(remote_doc_state) => {
workspace_database_doc_state = remote_doc_state;
},
Err(err) => {
return Err(FlowyError::record_not_found().with_context(format!(
@ -132,13 +137,12 @@ impl DatabaseManager {
&workspace_database_object_id,
CollabType::WorkspaceDatabase,
collab_db.clone(),
collab_raw_data,
workspace_database_doc_state,
config.clone(),
);
let workspace_database =
WorkspaceDatabase::open(uid, collab, collab_db, config, collab_builder);
*self.workspace_database.write().await = Some(Arc::new(workspace_database));
Ok(())
}
@ -234,7 +238,7 @@ impl DatabaseManager {
if let Some(database_id) = database_id {
let mut editors = self.editors.lock().await;
if let Some(editor) = editors.get(&database_id) {
editor.close_view_editor(view_id).await;
editor.close_view(view_id).await;
}
}
@ -350,7 +354,7 @@ impl DatabaseManager {
let database_id = self.get_database_id_with_view_id(view_id).await?;
let snapshots = self
.cloud_service
.get_collab_snapshots(&database_id, limit)
.get_database_collab_object_snapshots(&database_id, limit)
.await?
.into_iter()
.map(|snapshot| DatabaseSnapshotPB {
@ -423,7 +427,7 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl {
},
Some(cloud_service) => {
let updates = cloud_service
.get_collab_doc_state_db(&object_id, object_ty, &workspace_id)
.get_database_object_doc_state(&object_id, object_ty, &workspace_id)
.await?;
Ok(updates)
},
@ -446,7 +450,7 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl {
},
Some(cloud_service) => {
let updates = cloud_service
.batch_get_collab_doc_state_db(object_ids, object_ty, &workspace_id)
.batch_get_database_object_doc_state(object_ids, object_ty, &workspace_id)
.await?;
Ok(updates)
},

View File

@ -115,12 +115,24 @@ impl DatabaseEditor {
/// Returns bool value indicating whether the database is empty.
///
#[tracing::instrument(level = "debug", skip_all)]
pub async fn close_view_editor(&self, view_id: &str) -> bool {
pub async fn close_view(&self, view_id: &str) -> bool {
// If the database is empty, flush the database to the disk.
if self.database_views.editors().await.len() == 1 {
if let Some(database) = self.database.try_lock() {
let _ = database.flush();
}
}
self.database_views.close_view(view_id).await
}
#[tracing::instrument(level = "debug", skip_all)]
pub async fn close(&self) {
if let Some(database) = self.database.try_lock() {
let _ = database.flush();
}
self.database_views.close_view(view_id).await
for view in self.database_views.editors().await {
view.close().await;
}
}
pub async fn get_layout_type(&self, view_id: &str) -> DatabaseLayout {