diff --git a/src/DIRAC/Resources/Storage/GFAL2_StorageBase.py b/src/DIRAC/Resources/Storage/GFAL2_StorageBase.py index 16fa7819095..7194d764f11 100644 --- a/src/DIRAC/Resources/Storage/GFAL2_StorageBase.py +++ b/src/DIRAC/Resources/Storage/GFAL2_StorageBase.py @@ -53,6 +53,9 @@ MAX_SINGLE_STREAM_SIZE = 1024 * 1024 * 10 # 10MB MIN_BANDWIDTH = 0.5 * (1024 * 1024) # 0.5 MB/s +# Timeout when performing a stat call +STAT_TIMEOUT = 10 + @contextmanager def setGfalSetting( @@ -218,11 +221,12 @@ def exists(self, path): successful = {} failed = {} - for url in urls: - try: - successful[url] = self.__singleExists(url) - except Exception as e: - failed[url] = repr(e) + with setGfalSetting(self.ctx, "CORE", "NAMESPACE_TIMEOUT", STAT_TIMEOUT): + for url in urls: + try: + successful[url] = self.__singleExists(url) + except Exception as e: + failed[url] = repr(e) resDict = {"Failed": failed, "Successful": successful} return resDict @@ -268,29 +272,15 @@ def isFile(self, path): successful = {} failed = {} - for url in urls: - try: - successful[url] = self._isSingleFile(url) - except Exception as e: - failed[url] = repr(e) + with setGfalSetting(self.ctx, "CORE", "NAMESPACE_TIMEOUT", STAT_TIMEOUT): + for url in urls: + try: + successful[url] = S_ISREG(self.ctx.stat(url).st_mode) + except Exception as e: + failed[url] = repr(e) return {"Failed": failed, "Successful": successful} - def _isSingleFile(self, path: str) -> bool: - """Checking if :path: exists and is a file - - :param str path: single path on the storage (srm://...) - - :returns: boolean - - :raises: - gfal2.GError: gfal problem - - """ - - statInfo = self.ctx.stat(path) - return S_ISREG(statInfo.st_mode) - @convertToReturnValue def putFile(self, path, sourceSize: int = 0): """Put a copy of a local file or a file on another srm storage to a directory on the @@ -600,7 +590,8 @@ def _getSingleFileSize(self, path: str) -> int: log = self.log.getLocalSubLogger("GFAL2_StorageBase._getSingleFileSize") log.debug(f"Determining file size of {path}") - statInfo = self.ctx.stat(path) # keeps info like size, mode. + with setGfalSetting(self.ctx, "CORE", "NAMESPACE_TIMEOUT", STAT_TIMEOUT): + statInfo = self.ctx.stat(path) # keeps info like size, mode. # If it is not a file if not S_ISREG(statInfo.st_mode): @@ -675,7 +666,8 @@ def _getSingleMetadata(self, path: str) -> dict[str, Any]: log = self.log.getLocalSubLogger("GFAL2_StorageBase._getSingleMetadata") log.debug(f"Reading metadata for {path}") - statInfo = self.ctx.stat(path) + with setGfalSetting(self.ctx, "CORE", "NAMESPACE_TIMEOUT", STAT_TIMEOUT): + statInfo = self.ctx.stat(path) metadataDict = self.__parseStatInfoFromApiOutput(statInfo) if metadataDict["File"] and self.checksumType: @@ -942,27 +934,15 @@ def isDirectory(self, path): successful = {} failed = {} - for url in urls: - try: - successful[url] = self._isSingleDirectory(url) - except Exception as e: - failed[url] = f"Failed to determine if path is a directory {repr(e)}" + with setGfalSetting(self.ctx, "CORE", "NAMESPACE_TIMEOUT", STAT_TIMEOUT): + for url in urls: + try: + successful[url] = S_ISDIR(self.ctx.stat(url).st_mode) + except Exception as e: + failed[url] = f"Failed to determine if path is a directory {repr(e)}" return {"Failed": failed, "Successful": successful} - def _isSingleDirectory(self, path: str) -> bool: - """Checking if :path: exists and is a directory - - :param str path: single path on the storage (srm://...) - - :returns: boolean if it is a directory or not - - :raises: - gfal2.GError in case of gfal problem - """ - - return S_ISDIR(self.ctx.stat(path).st_mode) - @convertToReturnValue def listDirectory(self, path): """List the content of the path provided