Feat/restore revision (#1549)

* chore: write snapshot

* chore: add tests

* chore: sync close

* chore: restore from snapshot

* chore: delete invalid revisions after restored from snapshot

* chore: create default view if it fail to deserialize view's revisions when there is no snapshot

* chore: auto generate snapshot

Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
Nathan.fooo
2022-12-09 09:19:47 +08:00
committed by GitHub
parent a507fb8ec6
commit 8c225fe547
67 changed files with 1140 additions and 582 deletions

View File

@ -1,6 +1,6 @@
use crate::entities::view::ViewDataFormatPB;
use crate::entities::{ViewLayoutTypePB, ViewPB};
use crate::services::folder_editor::FolderRevisionCompress;
use crate::services::folder_editor::FolderRevisionMergeable;
use crate::{
dart_notification::{send_dart_notification, FolderNotification},
entities::workspace::RepeatedWorkspacePB,
@ -15,8 +15,8 @@ use bytes::Bytes;
use flowy_document::editor::initial_read_me;
use flowy_error::FlowyError;
use flowy_revision::{
RevisionManager, RevisionPersistence, RevisionPersistenceConfiguration, RevisionWebSocket,
SQLiteRevisionSnapshotPersistence,
PhantomSnapshotPersistence, RevisionManager, RevisionPersistence, RevisionPersistenceConfiguration,
RevisionWebSocket,
};
use folder_rev_model::user_default;
use lazy_static::lazy_static;
@ -171,16 +171,13 @@ impl FolderManager {
let disk_cache = SQLiteFolderRevisionPersistence::new(user_id, pool.clone());
let configuration = RevisionPersistenceConfiguration::new(100, false);
let rev_persistence = RevisionPersistence::new(user_id, object_id, disk_cache, configuration);
let rev_compactor = FolderRevisionCompress();
// let history_persistence = SQLiteRevisionHistoryPersistence::new(object_id, pool.clone());
let snapshot_persistence = SQLiteRevisionSnapshotPersistence::new(object_id, pool);
let rev_compactor = FolderRevisionMergeable();
let rev_manager = RevisionManager::new(
user_id,
folder_id.as_ref(),
rev_persistence,
rev_compactor,
// history_persistence,
snapshot_persistence,
PhantomSnapshotPersistence(),
);
let folder_editor = FolderEditor::new(user_id, &folder_id, token, rev_manager, self.web_socket.clone()).await?;

View File

@ -82,10 +82,11 @@ impl FolderEditor {
pub(crate) fn apply_change(&self, change: FolderChangeset) -> FlowyResult<()> {
let FolderChangeset { operations: delta, md5 } = change;
let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
let delta_data = delta.json_bytes();
let revision = Revision::new(&self.rev_manager.object_id, base_rev_id, rev_id, delta_data, md5);
let _ = futures::executor::block_on(async { self.rev_manager.add_local_revision(&revision).await })?;
let rev_manager = self.rev_manager.clone();
tokio::spawn(async move {
let _ = rev_manager.add_local_revision(delta_data, md5).await;
});
Ok(())
}
@ -113,8 +114,8 @@ impl RevisionObjectSerializer for FolderRevisionSerde {
}
}
pub struct FolderRevisionCompress();
impl RevisionMergeable for FolderRevisionCompress {
pub struct FolderRevisionMergeable();
impl RevisionMergeable for FolderRevisionMergeable {
fn combine_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
FolderRevisionSerde::combine_revisions(revisions)
}

View File

@ -15,7 +15,7 @@ impl AppTableSql {
pub(crate) fn create_app(app_rev: AppRevision, conn: &SqliteConnection) -> Result<(), FlowyError> {
let app_table = AppTable::new(app_rev);
match diesel_record_count!(app_table, &app_table.id, conn) {
0 => diesel_insert_table!(app_table, &app_table, conn),
0 => diesel_insert_table!(app_table, app_table.clone(), conn),
_ => {
let changeset = AppChangeset::from_table(app_table);
diesel_update_table!(app_table, changeset, conn)

View File

@ -13,7 +13,7 @@ impl TrashTableSql {
for trash_rev in trashes {
let trash_table: TrashTable = trash_rev.into();
match diesel_record_count!(trash_table, &trash_table.id, conn) {
0 => diesel_insert_table!(trash_table, &trash_table, conn),
0 => diesel_insert_table!(trash_table, trash_table.clone(), conn),
_ => {
let changeset = TrashChangeset::from(trash_table);
diesel_update_table!(trash_table, changeset, conn)

View File

@ -21,7 +21,7 @@ impl ViewTableSql {
pub(crate) fn create_view(view_rev: ViewRevision, conn: &SqliteConnection) -> Result<(), FlowyError> {
let view_table = ViewTable::new(view_rev);
match diesel_record_count!(view_table, &view_table.id, conn) {
0 => diesel_insert_table!(view_table, &view_table, conn),
0 => diesel_insert_table!(view_table, view_table.clone(), conn),
_ => {
let changeset = ViewChangeset::from_table(view_table);
diesel_update_table!(view_table, changeset, conn)

View File

@ -15,7 +15,7 @@ impl WorkspaceTableSql {
) -> Result<(), FlowyError> {
let table = WorkspaceTable::new(workspace_rev, user_id);
match diesel_record_count!(workspace_table, &table.id, conn) {
0 => diesel_insert_table!(workspace_table, &table, conn),
0 => diesel_insert_table!(workspace_table, table.clone(), conn),
_ => {
let changeset = WorkspaceChangeset::from_table(table);
diesel_update_table!(workspace_table, changeset, conn);