From 9ec7ecfdbc79dd89dffe2d631783ce83c734f1f1 Mon Sep 17 00:00:00 2001 From: "petr.kalis" Date: Mon, 27 Jul 2020 15:13:38 +0200 Subject: [PATCH] Added possibility of tree injection to constructor Speed optimalization - limits number of times folder structures is being build during synchronization loop. --- pype/modules/sync_server/providers/gdrive.py | 14 ++++++++++++-- pype/modules/sync_server/providers/lib.py | 4 ++-- pype/modules/sync_server/sync_server.py | 8 +++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/pype/modules/sync_server/providers/gdrive.py b/pype/modules/sync_server/providers/gdrive.py index ce6dff96b4..287a4f1cf8 100644 --- a/pype/modules/sync_server/providers/gdrive.py +++ b/pype/modules/sync_server/providers/gdrive.py @@ -20,10 +20,10 @@ log = Logger().get_logger("SyncServer") class GDriveHandler(AbstractProvider): FOLDER_STR = 'application/vnd.google-apps.folder' - def __init__(self): + def __init__(self, tree=None): self.service = self._get_gd_service() self.root = self.service.files().get(fileId='root').execute() - self.tree = self._build_tree(self.list_folders()) + self.tree = tree or self._build_tree(self.list_folders()) def _get_gd_service(self): """ @@ -98,6 +98,16 @@ class GDriveHandler(AbstractProvider): return tree + def get_tree(self): + """ + Building of the folder tree could be potentially expensive, + constructor provides argument that could inject previously created + tree. + Tree structure must be handled in thread safe fashion! + :return: - url to id + """ + return self.tree + def get_root_name(self): """ Return name of root folder. Needs to be used as a beginning of diff --git a/pype/modules/sync_server/providers/lib.py b/pype/modules/sync_server/providers/lib.py index 35fb041664..e2a65a117a 100644 --- a/pype/modules/sync_server/providers/lib.py +++ b/pype/modules/sync_server/providers/lib.py @@ -19,7 +19,7 @@ class ProviderFactory: def register_provider(self, provider, creator, batch_limit): self.providers[provider] = (creator, batch_limit) - def get_provider(self, provider): + def get_provider(self, provider, tree=None): """ Returns new instance of provider client :param provider: 'gdrive','S3' @@ -27,7 +27,7 @@ class ProviderFactory: """ creator_info = self._get_creator_info(provider) - return creator_info[0]() + return creator_info[0](tree) def get_provider_batch_limit(self, provider): """ diff --git a/pype/modules/sync_server/sync_server.py b/pype/modules/sync_server/sync_server.py index 962a687da6..446195fa36 100644 --- a/pype/modules/sync_server/sync_server.py +++ b/pype/modules/sync_server/sync_server.py @@ -120,7 +120,7 @@ class SyncServer(): return SyncStatus.DO_NOTHING - async def upload(self, file, representation, provider): + async def upload(self, file, representation, provider, tree=None): """ Upload single 'file' of a 'representation' to 'provider'. Source url is taken from 'file' portion, where {root} placeholder @@ -137,7 +137,7 @@ class SyncServer(): """ # create ids sequentially, upload file in parallel later with self.lock: - handler = lib.factory.get_provider(provider) + handler = lib.factory.get_provider(provider, tree) local_root = representation.get("context", {}).get("root") if not local_root: raise ValueError("Unknown local root for file {}") @@ -332,6 +332,7 @@ class SynchServerThread(threading.Thread): # upload process can find already uploaded file and reuse same id processed_file_path = set() for provider in lib.factory.providers.keys(): + tree = lib.factory.get_provider(provider).get_tree() limit = lib.factory.get_provider_batch_limit(provider) for sync in sync_representations: if limit <= 0: @@ -352,7 +353,8 @@ class SynchServerThread(threading.Thread): task_files_to_upload.append(asyncio.create_task( self.module.upload(file, sync, - provider))) + provider, + tree))) # store info for exception handling files_created_info.append((file, sync,