mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Fix/read app (#1808)
* fix: filter out the apps that are deleted * chore: format code style * chore: fix clippy wanrings
This commit is contained in:
parent
1df2619c9f
commit
3491ffdd08
4
frontend/.vscode/launch.json
vendored
4
frontend/.vscode/launch.json
vendored
@ -12,8 +12,8 @@
|
||||
"type": "dart",
|
||||
"preLaunchTask": "AF: Build Appflowy Core",
|
||||
"env": {
|
||||
// "RUST_LOG": "trace"
|
||||
"RUST_LOG": "debug"
|
||||
"RUST_LOG": "trace"
|
||||
// "RUST_LOG": "debug"
|
||||
},
|
||||
"cwd": "${workspaceRoot}/app_flowy"
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(clippy::unused_unit)]
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{internal_error, FlowyResult};
|
||||
use flowy_revision::{RevisionSnapshot, RevisionSnapshotDiskCache};
|
||||
use flowy_revision::{RevisionSnapshotData, RevisionSnapshotPersistence};
|
||||
use flowy_sqlite::{
|
||||
prelude::*,
|
||||
schema::{grid_rev_snapshot, grid_rev_snapshot::dsl},
|
||||
@ -28,7 +28,7 @@ impl SQLiteDatabaseRevisionSnapshotPersistence {
|
||||
}
|
||||
}
|
||||
|
||||
impl RevisionSnapshotDiskCache for SQLiteDatabaseRevisionSnapshotPersistence {
|
||||
impl RevisionSnapshotPersistence for SQLiteDatabaseRevisionSnapshotPersistence {
|
||||
fn write_snapshot(&self, rev_id: i64, data: Vec<u8>) -> FlowyResult<()> {
|
||||
let conn = self.pool.get().map_err(internal_error)?;
|
||||
let snapshot_id = self.gen_snapshot_id(rev_id);
|
||||
@ -72,7 +72,7 @@ impl RevisionSnapshotDiskCache for SQLiteDatabaseRevisionSnapshotPersistence {
|
||||
// })
|
||||
}
|
||||
|
||||
fn read_snapshot(&self, rev_id: i64) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
fn read_snapshot(&self, rev_id: i64) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
let conn = self.pool.get().map_err(internal_error)?;
|
||||
let snapshot_id = self.gen_snapshot_id(rev_id);
|
||||
let record = dsl::grid_rev_snapshot
|
||||
@ -82,7 +82,7 @@ impl RevisionSnapshotDiskCache for SQLiteDatabaseRevisionSnapshotPersistence {
|
||||
Ok(Some(record.into()))
|
||||
}
|
||||
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
let conn = self.pool.get().map_err(internal_error)?;
|
||||
let latest_record = dsl::grid_rev_snapshot
|
||||
.filter(dsl::object_id.eq(&self.object_id))
|
||||
@ -106,9 +106,9 @@ struct GridSnapshotRecord {
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl std::convert::From<GridSnapshotRecord> for RevisionSnapshot {
|
||||
impl std::convert::From<GridSnapshotRecord> for RevisionSnapshotData {
|
||||
fn from(record: GridSnapshotRecord) -> Self {
|
||||
RevisionSnapshot {
|
||||
RevisionSnapshotData {
|
||||
rev_id: record.rev_id,
|
||||
base_rev_id: record.base_rev_id,
|
||||
timestamp: record.timestamp,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::grid::database_editor::DatabaseEditorTest;
|
||||
|
||||
use flowy_client_sync::client_database::{DatabaseOperations, DatabaseRevisionPad};
|
||||
use flowy_revision::{RevisionSnapshot, REVISION_WRITE_INTERVAL_IN_MILLIS};
|
||||
use flowy_revision::{RevisionSnapshotData, REVISION_WRITE_INTERVAL_IN_MILLIS};
|
||||
use grid_model::FieldRevision;
|
||||
use revision_model::Revision;
|
||||
use std::time::Duration;
|
||||
@ -12,10 +12,10 @@ pub enum SnapshotScript {
|
||||
#[allow(dead_code)]
|
||||
AssertSnapshot {
|
||||
rev_id: i64,
|
||||
expected: Option<RevisionSnapshot>,
|
||||
expected: Option<RevisionSnapshotData>,
|
||||
},
|
||||
AssertSnapshotContent {
|
||||
snapshot: RevisionSnapshot,
|
||||
snapshot: RevisionSnapshotData,
|
||||
expected: String,
|
||||
},
|
||||
CreateField {
|
||||
@ -28,7 +28,7 @@ pub enum SnapshotScript {
|
||||
|
||||
pub struct DatabaseSnapshotTest {
|
||||
inner: DatabaseEditorTest,
|
||||
pub current_snapshot: Option<RevisionSnapshot>,
|
||||
pub current_snapshot: Option<RevisionSnapshotData>,
|
||||
pub current_revision: Option<Revision>,
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ impl DatabaseSnapshotTest {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_latest_snapshot(&self) -> Option<RevisionSnapshot> {
|
||||
pub async fn get_latest_snapshot(&self) -> Option<RevisionSnapshotData> {
|
||||
self.editor.rev_manager().read_snapshot(None).await.unwrap()
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::editor::{initial_document_content, AppFlowyDocumentEditor, DocumentRevisionMergeable};
|
||||
use crate::entities::{DocumentVersionPB, EditParams};
|
||||
use crate::old_editor::editor::{DeltaDocumentEditor, DeltaDocumentRevisionMergeable};
|
||||
use crate::old_editor::snapshot::DeltaDocumentSnapshotPersistence;
|
||||
use crate::services::rev_sqlite::{
|
||||
SQLiteDeltaDocumentRevisionPersistence, SQLiteDocumentRevisionPersistence,
|
||||
SQLiteDocumentRevisionSnapshotPersistence,
|
||||
@ -12,8 +13,7 @@ use document_model::document::DocumentId;
|
||||
use flowy_client_sync::client_document::initial_delta_document_content;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_revision::{
|
||||
PhantomSnapshotPersistence, RevisionCloudService, RevisionManager, RevisionPersistence,
|
||||
RevisionPersistenceConfiguration, RevisionWebSocket,
|
||||
RevisionCloudService, RevisionManager, RevisionPersistence, RevisionPersistenceConfiguration, RevisionWebSocket,
|
||||
};
|
||||
use flowy_sqlite::ConnectionPool;
|
||||
use lib_infra::async_trait::async_trait;
|
||||
@ -292,7 +292,7 @@ impl DocumentManager {
|
||||
doc_id,
|
||||
rev_persistence,
|
||||
DeltaDocumentRevisionMergeable(),
|
||||
PhantomSnapshotPersistence(),
|
||||
DeltaDocumentSnapshotPersistence(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod conflict;
|
||||
pub mod editor;
|
||||
pub mod queue;
|
||||
pub mod snapshot;
|
||||
mod web_socket;
|
||||
|
18
frontend/rust-lib/flowy-document/src/old_editor/snapshot.rs
Normal file
18
frontend/rust-lib/flowy-document/src/old_editor/snapshot.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_revision::{RevisionSnapshotData, RevisionSnapshotPersistence};
|
||||
|
||||
pub struct DeltaDocumentSnapshotPersistence();
|
||||
|
||||
impl RevisionSnapshotPersistence for DeltaDocumentSnapshotPersistence {
|
||||
fn write_snapshot(&self, _rev_id: i64, _data: Vec<u8>) -> FlowyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_snapshot(&self, _rev_id: i64) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{internal_error, FlowyResult};
|
||||
use flowy_revision::{RevisionSnapshot, RevisionSnapshotDiskCache};
|
||||
use flowy_revision::{RevisionSnapshotData, RevisionSnapshotPersistence};
|
||||
use flowy_sqlite::{
|
||||
prelude::*,
|
||||
schema::{document_rev_snapshot, document_rev_snapshot::dsl},
|
||||
@ -27,7 +27,7 @@ impl SQLiteDocumentRevisionSnapshotPersistence {
|
||||
}
|
||||
}
|
||||
|
||||
impl RevisionSnapshotDiskCache for SQLiteDocumentRevisionSnapshotPersistence {
|
||||
impl RevisionSnapshotPersistence for SQLiteDocumentRevisionSnapshotPersistence {
|
||||
fn should_generate_snapshot_from_range(&self, start_rev_id: i64, current_rev_id: i64) -> bool {
|
||||
(current_rev_id - start_rev_id) >= 150
|
||||
}
|
||||
@ -50,7 +50,7 @@ impl RevisionSnapshotDiskCache for SQLiteDocumentRevisionSnapshotPersistence {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_snapshot(&self, rev_id: i64) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
fn read_snapshot(&self, rev_id: i64) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
let conn = self.pool.get().map_err(internal_error)?;
|
||||
let snapshot_id = self.gen_snapshot_id(rev_id);
|
||||
let record = dsl::document_rev_snapshot
|
||||
@ -60,7 +60,7 @@ impl RevisionSnapshotDiskCache for SQLiteDocumentRevisionSnapshotPersistence {
|
||||
Ok(Some(record.into()))
|
||||
}
|
||||
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
let conn = self.pool.get().map_err(internal_error)?;
|
||||
let latest_record = dsl::document_rev_snapshot
|
||||
.filter(dsl::object_id.eq(&self.object_id))
|
||||
@ -84,9 +84,9 @@ struct DocumentSnapshotRecord {
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl std::convert::From<DocumentSnapshotRecord> for RevisionSnapshot {
|
||||
impl std::convert::From<DocumentSnapshotRecord> for RevisionSnapshotData {
|
||||
fn from(record: DocumentSnapshotRecord) -> Self {
|
||||
RevisionSnapshot {
|
||||
RevisionSnapshotData {
|
||||
rev_id: record.rev_id,
|
||||
base_rev_id: record.base_rev_id,
|
||||
timestamp: record.timestamp,
|
||||
|
@ -60,18 +60,16 @@ impl AppController {
|
||||
Ok(app.into())
|
||||
}
|
||||
|
||||
pub(crate) async fn read_app(&self, params: AppIdPB) -> Result<AppRevision, FlowyError> {
|
||||
pub(crate) async fn read_app(&self, params: AppIdPB) -> Result<Option<AppRevision>, FlowyError> {
|
||||
let app = self
|
||||
.persistence
|
||||
.begin_transaction(|transaction| {
|
||||
let app = transaction.read_app(¶ms.value)?;
|
||||
let trash_ids = self.trash_controller.read_trash_ids(&transaction)?;
|
||||
if trash_ids.contains(&app.id) {
|
||||
return Err(
|
||||
FlowyError::record_not_found().context(format!("Can not find the app:{}", params.value))
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
Ok(app)
|
||||
Ok(Some(app))
|
||||
})
|
||||
.await?;
|
||||
self.read_app_on_server(params)?;
|
||||
@ -243,7 +241,7 @@ fn notify_apps_changed<'a>(
|
||||
trash_controller: Arc<TrashController>,
|
||||
transaction: &'a (dyn FolderPersistenceTransaction + 'a),
|
||||
) -> FlowyResult<()> {
|
||||
let items = read_local_workspace_apps(workspace_id, trash_controller, transaction)?
|
||||
let items = read_workspace_apps(workspace_id, trash_controller, transaction)?
|
||||
.into_iter()
|
||||
.map(|app_rev| app_rev.into())
|
||||
.collect();
|
||||
@ -254,7 +252,7 @@ fn notify_apps_changed<'a>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_local_workspace_apps<'a>(
|
||||
pub fn read_workspace_apps<'a>(
|
||||
workspace_id: &str,
|
||||
trash_controller: Arc<TrashController>,
|
||||
transaction: &'a (dyn FolderPersistenceTransaction + 'a),
|
||||
|
@ -51,8 +51,10 @@ pub(crate) async fn read_app_handler(
|
||||
view_controller: AFPluginState<Arc<ViewController>>,
|
||||
) -> DataResult<AppPB, FlowyError> {
|
||||
let params: AppIdPB = data.into_inner();
|
||||
let mut app_rev = app_controller.read_app(params.clone()).await?;
|
||||
if let Some(mut app_rev) = app_controller.read_app(params.clone()).await? {
|
||||
app_rev.belongings = view_controller.read_views_belong_to(¶ms.value).await?;
|
||||
|
||||
data_result(app_rev.into())
|
||||
} else {
|
||||
Err(FlowyError::record_not_found())
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(clippy::unused_unit)]
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{internal_error, FlowyResult};
|
||||
use flowy_revision::{RevisionSnapshot, RevisionSnapshotDiskCache};
|
||||
use flowy_revision::{RevisionSnapshotData, RevisionSnapshotPersistence};
|
||||
use flowy_sqlite::{
|
||||
prelude::*,
|
||||
schema::{folder_rev_snapshot, folder_rev_snapshot::dsl},
|
||||
@ -28,7 +28,7 @@ impl SQLiteFolderRevisionSnapshotPersistence {
|
||||
}
|
||||
}
|
||||
|
||||
impl RevisionSnapshotDiskCache for SQLiteFolderRevisionSnapshotPersistence {
|
||||
impl RevisionSnapshotPersistence for SQLiteFolderRevisionSnapshotPersistence {
|
||||
fn should_generate_snapshot_from_range(&self, start_rev_id: i64, current_rev_id: i64) -> bool {
|
||||
(current_rev_id - start_rev_id) >= 2
|
||||
}
|
||||
@ -51,7 +51,7 @@ impl RevisionSnapshotDiskCache for SQLiteFolderRevisionSnapshotPersistence {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_snapshot(&self, rev_id: i64) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
fn read_snapshot(&self, rev_id: i64) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
let conn = self.pool.get().map_err(internal_error)?;
|
||||
let snapshot_id = self.gen_snapshot_id(rev_id);
|
||||
let record = dsl::folder_rev_snapshot
|
||||
@ -61,7 +61,7 @@ impl RevisionSnapshotDiskCache for SQLiteFolderRevisionSnapshotPersistence {
|
||||
Ok(Some(record.into()))
|
||||
}
|
||||
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
let conn = self.pool.get().map_err(internal_error)?;
|
||||
let latest_record = dsl::folder_rev_snapshot
|
||||
.filter(dsl::object_id.eq(&self.object_id))
|
||||
@ -85,9 +85,9 @@ struct FolderSnapshotRecord {
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl std::convert::From<FolderSnapshotRecord> for RevisionSnapshot {
|
||||
impl std::convert::From<FolderSnapshotRecord> for RevisionSnapshotData {
|
||||
fn from(record: FolderSnapshotRecord) -> Self {
|
||||
RevisionSnapshot {
|
||||
RevisionSnapshotData {
|
||||
rev_id: record.rev_id,
|
||||
base_rev_id: record.base_rev_id,
|
||||
timestamp: record.timestamp,
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
notification::*,
|
||||
services::{
|
||||
persistence::{FolderPersistence, FolderPersistenceTransaction, WorkspaceChangeset},
|
||||
read_local_workspace_apps, TrashController,
|
||||
read_workspace_apps, TrashController,
|
||||
},
|
||||
};
|
||||
use flowy_sqlite::kv::KV;
|
||||
@ -69,7 +69,7 @@ impl WorkspaceController {
|
||||
.begin_transaction(|transaction| {
|
||||
transaction.update_workspace(changeset)?;
|
||||
let user_id = self.user.user_id()?;
|
||||
self.read_local_workspace(workspace_id.clone(), &user_id, &transaction)
|
||||
self.read_workspace(workspace_id.clone(), &user_id, &transaction)
|
||||
})
|
||||
.await?;
|
||||
|
||||
@ -89,7 +89,7 @@ impl WorkspaceController {
|
||||
.persistence
|
||||
.begin_transaction(|transaction| {
|
||||
transaction.delete_workspace(workspace_id)?;
|
||||
self.read_local_workspaces(None, &user_id, &transaction)
|
||||
self.read_workspaces(None, &user_id, &transaction)
|
||||
})
|
||||
.await?;
|
||||
send_notification(&token, FolderNotification::UserDeleteWorkspace)
|
||||
@ -104,7 +104,7 @@ impl WorkspaceController {
|
||||
if let Some(workspace_id) = params.value {
|
||||
let workspace = self
|
||||
.persistence
|
||||
.begin_transaction(|transaction| self.read_local_workspace(workspace_id, &user_id, &transaction))
|
||||
.begin_transaction(|transaction| self.read_workspace(workspace_id, &user_id, &transaction))
|
||||
.await?;
|
||||
set_current_workspace(&user_id, &workspace.id);
|
||||
Ok(workspace)
|
||||
@ -119,7 +119,7 @@ impl WorkspaceController {
|
||||
let app_revs = self
|
||||
.persistence
|
||||
.begin_transaction(|transaction| {
|
||||
read_local_workspace_apps(&workspace_id, self.trash_controller.clone(), &transaction)
|
||||
read_workspace_apps(&workspace_id, self.trash_controller.clone(), &transaction)
|
||||
})
|
||||
.await?;
|
||||
// TODO: read from server
|
||||
@ -127,38 +127,39 @@ impl WorkspaceController {
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, transaction), err)]
|
||||
pub(crate) fn read_local_workspaces<'a>(
|
||||
pub(crate) fn read_workspaces<'a>(
|
||||
&self,
|
||||
workspace_id: Option<String>,
|
||||
user_id: &str,
|
||||
transaction: &'a (dyn FolderPersistenceTransaction + 'a),
|
||||
) -> Result<RepeatedWorkspacePB, FlowyError> {
|
||||
let workspace_id = workspace_id.to_owned();
|
||||
let trash_ids = self.trash_controller.read_trash_ids(transaction)?;
|
||||
let workspaces = transaction
|
||||
.read_workspaces(user_id, workspace_id)?
|
||||
.into_iter()
|
||||
.map(|workspace_rev| workspace_rev.into())
|
||||
.map(|mut workspace_rev| {
|
||||
workspace_rev.apps.retain(|app_rev| !trash_ids.contains(&app_rev.id));
|
||||
workspace_rev.into()
|
||||
})
|
||||
.collect();
|
||||
Ok(RepeatedWorkspacePB { items: workspaces })
|
||||
}
|
||||
|
||||
pub(crate) fn read_local_workspace<'a>(
|
||||
pub(crate) fn read_workspace<'a>(
|
||||
&self,
|
||||
workspace_id: String,
|
||||
user_id: &str,
|
||||
transaction: &'a (dyn FolderPersistenceTransaction + 'a),
|
||||
) -> Result<WorkspacePB, FlowyError> {
|
||||
let mut workspace_revs = transaction.read_workspaces(user_id, Some(workspace_id.clone()))?;
|
||||
if workspace_revs.is_empty() {
|
||||
let mut workspaces = self
|
||||
.read_workspaces(Some(workspace_id.clone()), user_id, transaction)?
|
||||
.items;
|
||||
if workspaces.is_empty() {
|
||||
return Err(FlowyError::record_not_found().context(format!("{} workspace not found", workspace_id)));
|
||||
}
|
||||
debug_assert_eq!(workspace_revs.len(), 1);
|
||||
let workspace = workspace_revs
|
||||
.drain(..1)
|
||||
.map(|workspace_rev| workspace_rev.into())
|
||||
.collect::<Vec<WorkspacePB>>()
|
||||
.pop()
|
||||
.unwrap();
|
||||
debug_assert_eq!(workspaces.len(), 1);
|
||||
let workspace = workspaces.drain(..1).collect::<Vec<WorkspacePB>>().pop().unwrap();
|
||||
Ok(workspace)
|
||||
}
|
||||
}
|
||||
@ -215,11 +216,10 @@ pub async fn notify_workspace_setting_did_change(
|
||||
let workspace_setting = folder_manager
|
||||
.persistence
|
||||
.begin_transaction(|transaction| {
|
||||
let workspace = folder_manager.workspace_controller.read_local_workspace(
|
||||
workspace_id.clone(),
|
||||
&user_id,
|
||||
&transaction,
|
||||
)?;
|
||||
let workspace =
|
||||
folder_manager
|
||||
.workspace_controller
|
||||
.read_workspace(workspace_id.clone(), &user_id, &transaction)?;
|
||||
|
||||
let setting = match transaction.read_view(view_id) {
|
||||
Ok(latest_view) => WorkspaceSettingPB {
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
errors::FlowyError,
|
||||
manager::FolderManager,
|
||||
notification::{send_notification, FolderNotification},
|
||||
services::{get_current_workspace, read_local_workspace_apps, WorkspaceController},
|
||||
services::{get_current_workspace, read_workspace_apps, WorkspaceController},
|
||||
};
|
||||
use lib_dispatch::prelude::{data_result, AFPluginData, AFPluginState, DataResult};
|
||||
use std::{convert::TryInto, sync::Arc};
|
||||
@ -60,10 +60,9 @@ pub(crate) async fn read_workspaces_handler(
|
||||
let workspaces = folder
|
||||
.persistence
|
||||
.begin_transaction(|transaction| {
|
||||
let mut workspaces =
|
||||
workspace_controller.read_local_workspaces(params.value.clone(), &user_id, &transaction)?;
|
||||
let mut workspaces = workspace_controller.read_workspaces(params.value.clone(), &user_id, &transaction)?;
|
||||
for workspace in workspaces.iter_mut() {
|
||||
let apps = read_local_workspace_apps(&workspace.id, trash_controller.clone(), &transaction)?
|
||||
let apps = read_workspace_apps(&workspace.id, trash_controller.clone(), &transaction)?
|
||||
.into_iter()
|
||||
.map(|app_rev| app_rev.into())
|
||||
.collect();
|
||||
@ -91,7 +90,7 @@ pub async fn read_cur_workspace_handler(
|
||||
.begin_transaction(|transaction| {
|
||||
folder
|
||||
.workspace_controller
|
||||
.read_local_workspace(workspace_id, &user_id, &transaction)
|
||||
.read_workspace(workspace_id, &user_id, &transaction)
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::rev_queue::{RevCommand, RevCommandSender, RevQueue};
|
||||
use crate::{
|
||||
RevisionPersistence, RevisionSnapshot, RevisionSnapshotController, RevisionSnapshotDiskCache,
|
||||
RevisionPersistence, RevisionSnapshotController, RevisionSnapshotData, RevisionSnapshotPersistence,
|
||||
WSDataProviderDataSource,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
@ -83,16 +83,16 @@ pub struct RevisionManager<Connection> {
|
||||
}
|
||||
|
||||
impl<Connection: 'static> RevisionManager<Connection> {
|
||||
pub fn new<SP, C>(
|
||||
pub fn new<Snapshot, Compress>(
|
||||
user_id: &str,
|
||||
object_id: &str,
|
||||
rev_persistence: RevisionPersistence<Connection>,
|
||||
rev_compress: C,
|
||||
snapshot_persistence: SP,
|
||||
rev_compress: Compress,
|
||||
snapshot_persistence: Snapshot,
|
||||
) -> Self
|
||||
where
|
||||
SP: 'static + RevisionSnapshotDiskCache,
|
||||
C: 'static + RevisionMergeable,
|
||||
Snapshot: 'static + RevisionSnapshotPersistence,
|
||||
Compress: 'static + RevisionMergeable,
|
||||
{
|
||||
let rev_id_counter = Arc::new(RevIdCounter::new(0));
|
||||
let rev_compress = Arc::new(rev_compress);
|
||||
@ -128,26 +128,26 @@ impl<Connection: 'static> RevisionManager<Connection> {
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "revision_manager_initialize", level = "trace", skip_all, fields(deserializer, object_id, deserialize_revisions) err)]
|
||||
pub async fn initialize<B>(&mut self, _cloud: Option<Arc<dyn RevisionCloudService>>) -> FlowyResult<B::Output>
|
||||
pub async fn initialize<De>(&mut self, _cloud: Option<Arc<dyn RevisionCloudService>>) -> FlowyResult<De::Output>
|
||||
where
|
||||
B: RevisionObjectDeserializer,
|
||||
De: RevisionObjectDeserializer,
|
||||
{
|
||||
let revision_records = self.rev_persistence.load_all_records(&self.object_id)?;
|
||||
tracing::Span::current().record("object_id", self.object_id.as_str());
|
||||
tracing::Span::current().record("deserializer", std::any::type_name::<B>());
|
||||
tracing::Span::current().record("deserializer", std::any::type_name::<De>());
|
||||
let revisions: Vec<Revision> = revision_records.iter().map(|record| record.revision.clone()).collect();
|
||||
tracing::Span::current().record("deserialize_revisions", revisions.len());
|
||||
let current_rev_id = revisions.last().as_ref().map(|revision| revision.rev_id).unwrap_or(0);
|
||||
match B::deserialize_revisions(&self.object_id, revisions.clone()) {
|
||||
match De::deserialize_revisions(&self.object_id, revisions.clone()) {
|
||||
Ok(object) => {
|
||||
self.rev_persistence.sync_revision_records(&revision_records).await?;
|
||||
self.rev_id_counter.set(current_rev_id);
|
||||
Ok(object)
|
||||
}
|
||||
Err(e) => match self.rev_snapshot.restore_from_snapshot::<B>(current_rev_id) {
|
||||
Err(e) => match self.rev_snapshot.restore_from_snapshot::<De>(current_rev_id) {
|
||||
None => {
|
||||
tracing::info!("Restore object from validation revisions");
|
||||
B::recover_operations_from_revisions(revisions).ok_or(e)
|
||||
De::recover_operations_from_revisions(revisions).ok_or(e)
|
||||
}
|
||||
Some((object, snapshot_rev)) => {
|
||||
let snapshot_rev_id = snapshot_rev.rev_id;
|
||||
@ -169,7 +169,7 @@ impl<Connection: 'static> RevisionManager<Connection> {
|
||||
self.rev_snapshot.generate_snapshot().await;
|
||||
}
|
||||
|
||||
pub async fn read_snapshot(&self, rev_id: Option<i64>) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
pub async fn read_snapshot(&self, rev_id: Option<i64>) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
match rev_id {
|
||||
None => self.rev_snapshot.read_last_snapshot(),
|
||||
Some(rev_id) => self.rev_snapshot.read_snapshot(rev_id),
|
||||
|
@ -9,34 +9,18 @@ use std::sync::atomic::AtomicI64;
|
||||
use std::sync::atomic::Ordering::SeqCst;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait RevisionSnapshotDiskCache: Send + Sync {
|
||||
pub trait RevisionSnapshotPersistence: Send + Sync {
|
||||
fn should_generate_snapshot_from_range(&self, start_rev_id: i64, current_rev_id: i64) -> bool {
|
||||
(current_rev_id - start_rev_id) >= AUTO_GEN_SNAPSHOT_PER_10_REVISION
|
||||
}
|
||||
|
||||
fn write_snapshot(&self, rev_id: i64, data: Vec<u8>) -> FlowyResult<()>;
|
||||
|
||||
fn read_snapshot(&self, rev_id: i64) -> FlowyResult<Option<RevisionSnapshot>>;
|
||||
fn read_snapshot(&self, rev_id: i64) -> FlowyResult<Option<RevisionSnapshotData>>;
|
||||
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshot>>;
|
||||
}
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshotData>>;
|
||||
|
||||
/// Do nothing but just used to clam the rust compiler about the generic parameter `SP` of `RevisionManager`
|
||||
///
|
||||
pub struct PhantomSnapshotPersistence();
|
||||
|
||||
impl RevisionSnapshotDiskCache for PhantomSnapshotPersistence {
|
||||
fn write_snapshot(&self, rev_id: i64, data: Vec<u8>) -> FlowyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_snapshot(&self, rev_id: i64) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
Ok(None)
|
||||
}
|
||||
// fn generate_snapshot_data(&self) -> Option<RevisionSnapshotData>;
|
||||
}
|
||||
|
||||
const AUTO_GEN_SNAPSHOT_PER_10_REVISION: i64 = 10;
|
||||
@ -44,7 +28,7 @@ const AUTO_GEN_SNAPSHOT_PER_10_REVISION: i64 = 10;
|
||||
pub struct RevisionSnapshotController<Connection> {
|
||||
user_id: String,
|
||||
object_id: String,
|
||||
rev_snapshot_persistence: Arc<dyn RevisionSnapshotDiskCache>,
|
||||
rev_snapshot_persistence: Arc<dyn RevisionSnapshotPersistence>,
|
||||
rev_id_counter: Arc<RevIdCounter>,
|
||||
rev_persistence: Arc<RevisionPersistence<Connection>>,
|
||||
rev_compress: Arc<dyn RevisionMergeable>,
|
||||
@ -64,13 +48,13 @@ where
|
||||
revision_compress: Arc<dyn RevisionMergeable>,
|
||||
) -> Self
|
||||
where
|
||||
D: RevisionSnapshotDiskCache + 'static,
|
||||
D: RevisionSnapshotPersistence + 'static,
|
||||
{
|
||||
let disk_cache = Arc::new(disk_cache);
|
||||
let rev_snapshot_persistence = Arc::new(disk_cache);
|
||||
Self {
|
||||
user_id: user_id.to_string(),
|
||||
object_id: object_id.to_string(),
|
||||
rev_snapshot_persistence: disk_cache,
|
||||
rev_snapshot_persistence,
|
||||
rev_id_counter,
|
||||
start_rev_id: AtomicI64::new(0),
|
||||
rev_persistence: revision_persistence,
|
||||
@ -168,7 +152,7 @@ where
|
||||
}
|
||||
|
||||
impl<Connection> std::ops::Deref for RevisionSnapshotController<Connection> {
|
||||
type Target = Arc<dyn RevisionSnapshotDiskCache>;
|
||||
type Target = Arc<dyn RevisionSnapshotPersistence>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.rev_snapshot_persistence
|
||||
@ -176,7 +160,7 @@ impl<Connection> std::ops::Deref for RevisionSnapshotController<Connection> {
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct RevisionSnapshot {
|
||||
pub struct RevisionSnapshotData {
|
||||
pub rev_id: i64,
|
||||
pub base_rev_id: i64,
|
||||
pub timestamp: i64,
|
||||
|
@ -2,7 +2,8 @@ use bytes::Bytes;
|
||||
use flowy_error::{internal_error, FlowyError, FlowyResult};
|
||||
use flowy_revision::{
|
||||
RevisionManager, RevisionMergeable, RevisionObjectDeserializer, RevisionPersistence,
|
||||
RevisionPersistenceConfiguration, RevisionSnapshot, RevisionSnapshotDiskCache, REVISION_WRITE_INTERVAL_IN_MILLIS,
|
||||
RevisionPersistenceConfiguration, RevisionSnapshotData, RevisionSnapshotPersistence,
|
||||
REVISION_WRITE_INTERVAL_IN_MILLIS,
|
||||
};
|
||||
use flowy_revision_persistence::{RevisionChangeset, RevisionDiskCache, SyncRecord};
|
||||
|
||||
@ -244,16 +245,16 @@ impl RevisionDiskCache<RevisionConnectionMock> for RevisionDiskCacheMock {
|
||||
|
||||
pub struct RevisionConnectionMock {}
|
||||
pub struct RevisionSnapshotMock {}
|
||||
impl RevisionSnapshotDiskCache for RevisionSnapshotMock {
|
||||
impl RevisionSnapshotPersistence for RevisionSnapshotMock {
|
||||
fn write_snapshot(&self, _rev_id: i64, _data: Vec<u8>) -> FlowyResult<()> {
|
||||
todo!()
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_snapshot(&self, _rev_id: i64) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
todo!()
|
||||
fn read_snapshot(&self, _rev_id: i64) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshot>> {
|
||||
fn read_last_snapshot(&self) -> FlowyResult<Option<RevisionSnapshotData>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user