From c9349305c557343639b845b5d1b67cc1dbd93cfa Mon Sep 17 00:00:00 2001 From: Aurelia Date: Thu, 21 Nov 2024 15:45:27 +0100 Subject: [PATCH] [WIP] Expose last updater. --- bindings/generator/api/workspace.py | 3 +++ libparsec/crates/client/src/workspace/merge.rs | 4 ++++ .../client/src/workspace/transactions/inbound_sync.rs | 2 ++ .../client/src/workspace/transactions/read_folder.rs | 1 + .../client/src/workspace/transactions/stat_entry.rs | 6 ++++++ libparsec/crates/testbed/src/template/crc_hash.rs | 4 ++++ .../schema/local_manifest/local_file_manifest.json5 | 4 ++++ .../schema/local_manifest/local_folder_manifest.json5 | 4 ++++ libparsec/crates/types/src/local_manifest/file.rs | 5 +++++ libparsec/crates/types/src/local_manifest/folder.rs | 9 +++++++++ 10 files changed, 42 insertions(+) diff --git a/bindings/generator/api/workspace.py b/bindings/generator/api/workspace.py index 18f1cff1e46..b387e65396e 100644 --- a/bindings/generator/api/workspace.py +++ b/bindings/generator/api/workspace.py @@ -5,6 +5,7 @@ from .common import ( U64, DateTime, + DeviceID, EntryName, ErrorVariant, FsPath, @@ -316,6 +317,7 @@ class File: is_placeholder: bool need_sync: bool size: SizeInt + last_updater: DeviceID class Folder: confinement_point: Optional[VlobID] @@ -326,6 +328,7 @@ class Folder: base_version: VersionInt is_placeholder: bool need_sync: bool + last_update: DeviceID async def workspace_stat_entry( diff --git a/libparsec/crates/client/src/workspace/merge.rs b/libparsec/crates/client/src/workspace/merge.rs index 4db24a8c552..3e69b054362 100644 --- a/libparsec/crates/client/src/workspace/merge.rs +++ b/libparsec/crates/client/src/workspace/merge.rs @@ -174,6 +174,7 @@ pub(super) fn merge_local_file_manifest( need_sync: _, // Ignore `updated`: we don't merge data that change on each sync updated: _, + last_updater: _, parent: local_parent, size: local_size, blocksize: local_blocksize, @@ -275,6 +276,7 @@ pub(super) fn merge_local_folder_manifest( local_confinement_points: _, // Ignored, we don't merge data that change on each sync updated: _, + last_updater: _, } = local; // 0) Sanity checks, caller is responsible to handle them properly ! @@ -370,12 +372,14 @@ pub(super) fn merge_local_folder_manifest( updated: merged_updated, children: merged_children, speculative: merged_speculative, + last_updater: merged_last_updater, } = &mut merge_in_progress; *merged_speculative = false; *merged_parent = local.parent; *merged_need_sync = local.need_sync; *merged_updated = local.updated; + *merged_last_updater = local.last_updater; local.children.clone_into(merged_children); return MergeLocalFolderManifestOutcome::Merged(Arc::new(merge_in_progress)); diff --git a/libparsec/crates/client/src/workspace/transactions/inbound_sync.rs b/libparsec/crates/client/src/workspace/transactions/inbound_sync.rs index cf5bcc2db1d..5cdfcab4a88 100644 --- a/libparsec/crates/client/src/workspace/transactions/inbound_sync.rs +++ b/libparsec/crates/client/src/workspace/transactions/inbound_sync.rs @@ -454,6 +454,7 @@ async fn handle_conflict_and_update_store( size, blocksize, blocks, + last_updater, } = child_manifest.as_ref(); let mut conflicting = @@ -462,6 +463,7 @@ async fn handle_conflict_and_update_store( conflicting.updated = *updated; conflicting.size = *size; conflicting.blocksize = *blocksize; + conflicting.last_updater = *last_updater; blocks.clone_into(&mut conflicting.blocks); (child_manifest.base.id, Arc::new(conflicting)) diff --git a/libparsec/crates/client/src/workspace/transactions/read_folder.rs b/libparsec/crates/client/src/workspace/transactions/read_folder.rs index 736929e9e46..b239bb8fced 100644 --- a/libparsec/crates/client/src/workspace/transactions/read_folder.rs +++ b/libparsec/crates/client/src/workspace/transactions/read_folder.rs @@ -105,6 +105,7 @@ impl FolderReader { base_version: self.manifest.base.version, is_placeholder: self.manifest.base.version == 0, need_sync: self.manifest.need_sync, + last_updater: self.manifest.last_updater, } } diff --git a/libparsec/crates/client/src/workspace/transactions/stat_entry.rs b/libparsec/crates/client/src/workspace/transactions/stat_entry.rs index 3509e5e4ae2..02dcd85ae9e 100644 --- a/libparsec/crates/client/src/workspace/transactions/stat_entry.rs +++ b/libparsec/crates/client/src/workspace/transactions/stat_entry.rs @@ -26,6 +26,7 @@ pub enum EntryStat { is_placeholder: bool, need_sync: bool, size: SizeInt, + last_updater: DeviceID, }, // Here Folder can also be the root of the workspace (i.e. WorkspaceManifest) Folder { @@ -40,6 +41,7 @@ pub enum EntryStat { base_version: VersionInt, is_placeholder: bool, need_sync: bool, + last_updater: DeviceID, }, } @@ -145,6 +147,7 @@ pub(crate) async fn stat_entry_by_id( base_version: manifest.base.version, is_placeholder: manifest.base.version == 0, need_sync: manifest.need_sync, + last_updater: manifest.last_updater, }, ArcLocalChildManifest::File(manifest) => { // If the file may be currently opened with un-flushed modifications. @@ -174,6 +177,7 @@ pub(crate) async fn stat_entry_by_id( is_placeholder: manifest.base.version == 0, need_sync: manifest.need_sync, size: manifest.size, + last_updater: manifest.last_updater, } } }; @@ -216,6 +220,7 @@ pub(crate) async fn stat_entry( base_version: manifest.base.version, is_placeholder: manifest.base.version == 0, need_sync: manifest.need_sync, + last_updater: manifest.last_updater, }, ArcLocalChildManifest::File(manifest) => { // If the file may be currently opened with un-flushed modifications. @@ -245,6 +250,7 @@ pub(crate) async fn stat_entry( is_placeholder: manifest.base.version == 0, need_sync: manifest.need_sync, size: manifest.size, + last_updater: manifest.last_updater, } } }; diff --git a/libparsec/crates/testbed/src/template/crc_hash.rs b/libparsec/crates/testbed/src/template/crc_hash.rs index 98a11d73f74..29886347903 100644 --- a/libparsec/crates/testbed/src/template/crc_hash.rs +++ b/libparsec/crates/testbed/src/template/crc_hash.rs @@ -407,6 +407,7 @@ impl CrcHash for LocalFolderManifest { local_confinement_points, remote_confinement_points, speculative, + last_updater, } = self; base.crc_hash(hasher); @@ -417,6 +418,7 @@ impl CrcHash for LocalFolderManifest { local_confinement_points.crc_hash(hasher); remote_confinement_points.crc_hash(hasher); speculative.crc_hash(hasher); + last_updater.crc_hash(hasher); } } @@ -501,6 +503,7 @@ impl CrcHash for LocalFileManifest { size, blocksize, blocks, + last_updater, } = self; base.crc_hash(hasher); @@ -510,6 +513,7 @@ impl CrcHash for LocalFileManifest { size.crc_hash(hasher); blocksize.crc_hash(hasher); blocks.crc_hash(hasher); + last_updater.crc_hash(hasher); } } diff --git a/libparsec/crates/types/schema/local_manifest/local_file_manifest.json5 b/libparsec/crates/types/schema/local_manifest/local_file_manifest.json5 index 9995f2ff6d6..5c476491792 100644 --- a/libparsec/crates/types/schema/local_manifest/local_file_manifest.json5 +++ b/libparsec/crates/types/schema/local_manifest/local_file_manifest.json5 @@ -19,6 +19,10 @@ "name": "updated", "type": "DateTime" }, + { + "name": "last_updater", + "type": "DeviceID" + }, { "name": "size", "type": "Size" diff --git a/libparsec/crates/types/schema/local_manifest/local_folder_manifest.json5 b/libparsec/crates/types/schema/local_manifest/local_folder_manifest.json5 index d2a1feb6b19..1ed33ff742d 100644 --- a/libparsec/crates/types/schema/local_manifest/local_folder_manifest.json5 +++ b/libparsec/crates/types/schema/local_manifest/local_folder_manifest.json5 @@ -19,6 +19,10 @@ "name": "updated", "type": "DateTime" }, + { + "name": "last_updater", + "type": "DeviceID" + }, { "name": "children", "type": "Map" diff --git a/libparsec/crates/types/src/local_manifest/file.rs b/libparsec/crates/types/src/local_manifest/file.rs index c34859e5025..856126e9af7 100644 --- a/libparsec/crates/types/src/local_manifest/file.rs +++ b/libparsec/crates/types/src/local_manifest/file.rs @@ -29,6 +29,7 @@ pub struct LocalFileManifest { pub parent: VlobID, pub need_sync: bool, pub updated: DateTime, + pub last_updater: DeviceID, pub size: u64, pub blocksize: Blocksize, /// This field is named after the `FileManifest::blocks` field, however it @@ -60,6 +61,7 @@ impl TryFrom for LocalFileManifest { size: data.size, blocksize: data.blocksize.try_into()?, blocks: data.blocks, + last_updater: data.last_updater, }) } } @@ -75,6 +77,7 @@ impl From for LocalFileManifestData { size: obj.size, blocksize: obj.blocksize.into(), blocks: obj.blocks, + last_updater: obj.last_updater, } } } @@ -102,6 +105,7 @@ impl LocalFileManifest { blocksize: DEFAULT_BLOCK_SIZE, size: 0, blocks: vec![], + last_updater: author, } } @@ -218,6 +222,7 @@ impl LocalFileManifest { size: remote.size, blocksize: remote.blocksize, blocks, + last_updater: remote.author, base: remote, }; diff --git a/libparsec/crates/types/src/local_manifest/folder.rs b/libparsec/crates/types/src/local_manifest/folder.rs index 8454db8db06..a389f24d454 100644 --- a/libparsec/crates/types/src/local_manifest/folder.rs +++ b/libparsec/crates/types/src/local_manifest/folder.rs @@ -25,6 +25,7 @@ pub struct LocalFolderManifest { pub parent: VlobID, pub need_sync: bool, pub updated: DateTime, + pub last_updater: DeviceID, pub children: HashMap, // Confined entries are entries that are meant to stay locally and not be added // to the uploaded remote manifest when synchronizing. The criteria for being @@ -62,6 +63,7 @@ impl_transparent_data_format_conversion!( local_confinement_points, remote_confinement_points, speculative, + last_updater ); impl_local_manifest_dump!(LocalFolderManifest); @@ -87,6 +89,7 @@ impl LocalFolderManifest { local_confinement_points: HashSet::new(), remote_confinement_points: HashSet::new(), speculative: false, + last_updater: author, } } @@ -156,6 +159,7 @@ impl LocalFolderManifest { local_confinement_points: HashSet::new(), remote_confinement_points: HashSet::new(), speculative, + last_updater: author, } } @@ -270,6 +274,7 @@ pub struct UnconfinedLocalFolderManifest { pub updated: DateTime, pub children: HashMap, pub speculative: bool, + pub last_updater: DeviceID, } impl UnconfinedLocalFolderManifest { @@ -280,6 +285,7 @@ impl UnconfinedLocalFolderManifest { updated: remote.updated, children: remote.children.clone(), speculative: false, + last_updater: remote.author, base: remote, } } @@ -327,6 +333,7 @@ impl UnconfinedLocalFolderManifest { local_confinement_points: HashSet::new(), remote_confinement_points, speculative: false, + last_updater: remote.author, base: remote, } } @@ -390,6 +397,7 @@ impl UnconfinedLocalFolderManifest { local_confinement_points, remote_confinement_points, speculative: self.speculative, + last_updater: self.last_updater, }; // Check whether there are existing local confinement entries to restore @@ -463,6 +471,7 @@ impl UnconfinedLocalFolderManifest { updated: local_manifest.updated, children: new_children, speculative: local_manifest.speculative, + last_updater: local_manifest.last_updater, } } }