def _sync_file_look_resolve_concurrency( self, path: FsPath, access: Access, diverged_manifest: LocalFileManifest, target_remote_manifest: FileManifest, ) -> None: parent_access, parent_manifest = self.local_folder_fs.get_entry( path.parent) moved_name = find_conflicting_name_for_child_entry( path.name, lambda name: name not in parent_manifest.children) moved_access = ManifestAccess() parent_manifest = parent_manifest.evolve_children_and_mark_updated( {moved_name: moved_access}) diverged_manifest = diverged_manifest.evolve(base_version=0, created=pendulum.now(), need_sync=True, is_placeholder=True) self.local_folder_fs.set_manifest(moved_access, diverged_manifest) self.local_folder_fs.set_manifest(parent_access, parent_manifest) target_manifest = target_remote_manifest.to_local() self.local_folder_fs.set_manifest(access, target_manifest) self.event_bus.send( "fs.entry.file_update_conflicted", path=str(path), diverged_path=str(path.parent / moved_name), original_id=access.id, diverged_id=moved_access.id, ) self.event_bus.send("fs.entry.updated", id=moved_access.id)
async def _minimal_sync_file(self, path: FsPath, access: Access, manifest: LocalFileManifest) -> bool: """ Returns: If additional sync are needed Raises: FileSyncConcurrencyError BackendNotAvailable """ if not is_placeholder_manifest(manifest): return manifest.need_sync need_more_sync = bool(manifest.dirty_blocks) # Don't sync the dirty blocks for fast synchronization try: last_block = manifest.blocks[-1] size = last_block.offset + last_block.size except IndexError: size = 0 minimal_manifest = manifest.evolve( updated=manifest.created if need_more_sync else manifest.updated, size=size, blocks=manifest.blocks, dirty_blocks=(), ) await self._sync_file_actual_sync(path, access, minimal_manifest) self.event_bus.send("fs.entry.minimal_synced", path=str(path), id=access.id) return need_more_sync
def fast_forward_file(local_base: LocalFileManifest, local_current: LocalFileManifest, remote_target: FileManifest) -> LocalFileManifest: assert local_base.base_version < remote_target.version assert local_base.base_version <= local_current.base_version assert local_current.base_version < remote_target.version processed_dirty_blocks_ids = [k.id for k in local_base.dirty_blocks] merged_dirty_blocks = [ k for k in local_current.dirty_blocks if k.id not in processed_dirty_blocks_ids ] merged_need_sync = bool(merged_dirty_blocks or local_current.size != remote_target.size) return local_current.evolve( blocks=remote_target.blocks, dirty_blocks=merged_dirty_blocks, base_version=remote_target.version, is_placeholder=False, need_sync=merged_need_sync, )
def update_manifest(block: int, manifest: LocalFileManifest, new_chunk: Chunk) -> LocalFileManifest: blocks = list(manifest.blocks) blocks[block] = (new_chunk, ) return manifest.evolve(blocks=tuple(blocks))