comparison libervia/backend/memory/memory.py @ 4269:64a85ce8be70

memory (file): avoid race condition when creating parent path directories.
author Goffi <goffi@goffi.org>
date Tue, 18 Jun 2024 12:06:45 +0200
parents 9fc3d28bc3f6
children 0d7bb4df2343
comparison
equal deleted inserted replaced
4268:51d004e50786 4269:64a85ce8be70
249 self.disco = Discovery(host) 249 self.disco = Discovery(host)
250 self.config = tools_config.parse_main_conf(log_filenames=True) 250 self.config = tools_config.parse_main_conf(log_filenames=True)
251 self._cache_path = Path(self.config_get("", "local_dir"), C.CACHE_DIR) 251 self._cache_path = Path(self.config_get("", "local_dir"), C.CACHE_DIR)
252 self.admins = self.config_get("", "admins_list", []) 252 self.admins = self.config_get("", "admins_list", [])
253 self.admin_jids = set() 253 self.admin_jids = set()
254 self._file_path_lock = defer.DeferredLock()
254 255
255 256
256 async def initialise(self): 257 async def initialise(self):
257 self.storage = Storage() 258 self.storage = Storage()
258 await self.storage.initialise() 259 await self.storage.initialise()
1704 "version, file_hash, size and mime_type can't be set for a directory" 1705 "version, file_hash, size and mime_type can't be set for a directory"
1705 ) 1706 )
1706 owner = self.get_files_owner(client, owner, peer_jid, file_id, parent) 1707 owner = self.get_files_owner(client, owner, peer_jid, file_id, parent)
1707 1708
1708 if path is not None: 1709 if path is not None:
1709 path = str(path) 1710 # We use a lock to avoid race condition leading to duplicate directories with
1710 # _get_parent_dir will check permissions if peer_jid is set, so we use owner 1711 # same name and parent.
1711 parent, remaining_path_elts = await self._get_parent_dir( 1712 await self._file_path_lock.acquire()
1712 client, path, parent, namespace, owner, owner, perms_to_check 1713 try:
1713 ) 1714
1714 # if remaining directories don't exist, we have to create them 1715 path = str(path)
1715 for new_dir in remaining_path_elts: 1716 # _get_parent_dir will check permissions if peer_jid is set, so we use owner
1716 new_dir_id = shortuuid.uuid() 1717 parent, remaining_path_elts = await self._get_parent_dir(
1717 await self.storage.set_file( 1718 client, path, parent, namespace, owner, owner, perms_to_check
1718 client,
1719 name=new_dir,
1720 file_id=new_dir_id,
1721 version="",
1722 parent=parent,
1723 type_=C.FILE_TYPE_DIRECTORY,
1724 namespace=namespace,
1725 created=time.time(),
1726 owner=owner,
1727 access=access,
1728 extra={},
1729 ) 1719 )
1730 parent = new_dir_id 1720 # if remaining directories don't exist, we have to create them
1721 for new_dir in remaining_path_elts:
1722 new_dir_id = shortuuid.uuid()
1723 await self.storage.set_file(
1724 client,
1725 name=new_dir,
1726 file_id=new_dir_id,
1727 version="",
1728 parent=parent,
1729 type_=C.FILE_TYPE_DIRECTORY,
1730 namespace=namespace,
1731 created=time.time(),
1732 owner=owner,
1733 access=access,
1734 extra={},
1735 )
1736 parent = new_dir_id
1737 finally:
1738 self._file_path_lock.release()
1739
1731 elif parent is None: 1740 elif parent is None:
1732 parent = "" 1741 parent = ""
1733 1742
1734 await self.storage.set_file( 1743 await self.storage.set_file(
1735 client, 1744 client,