base.py (6604B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\fsdBuiltData\common\base.py 2 from __future__ import absolute_import 3 import os 4 import logging 5 import time 6 from fsd import AbsJoin, GetBranchRoot 7 from fsdBuiltData.common.paths import get_file_contents_with_yield, resolve_path 8 try: 9 import monolithconfig 10 except ImportError: 11 monolithconfig = None 12 13 from .errors import NoBinaryLoaderError 14 from signals import Signal 15 log = logging.getLogger('fsdBuiltData') 16 IS_PACKAGED = False 17 IS_INTERPRETER = False 18 FSD_DATA_RELOAD = bool(int(os.getenv('FSD_DATA_RELOAD', '1'))) 19 NO_BINARY_LOADER = object() 20 21 def ShouldUseResData(): 22 if monolithconfig is None: 23 return False 24 return monolithconfig.on_client() or monolithconfig.on_proxy() or monolithconfig.on_server() 25 26 27 def EnableUseResFileServer(): 28 UseResFileServer.__enabled__ = True 29 30 31 def DisableUseResFileServer(): 32 UseResFileServer.__enabled__ = False 33 34 35 def UseResFileServer(): 36 return getattr(UseResFileServer, '__enabled__', False) 37 38 39 useResData = ShouldUseResData() 40 if useResData: 41 import blue 42 IS_PACKAGED = blue.pyos.packaged 43 IS_INTERPRETER = blue.pyos.interpreterMode 44 try: 45 import fsd.schemas.binaryLoader as binaryLoader 46 except ImportError: 47 import site 48 branchRoot = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../..')) 49 site.addsitedir(os.path.abspath(os.path.join(branchRoot, 'packages'))) 50 import fsd.schemas.binaryLoader as binaryLoader 51 52 class BuiltDataLoader(object): 53 __binary__ = None 54 __resBuiltFile__ = None 55 __clientAutobuildBuiltFile__ = None 56 __serverAutobuildBuiltFile__ = None 57 __loader__ = NO_BINARY_LOADER 58 __autoBuildFileTimeStamp__ = 0 59 onReload = None 60 61 @classmethod 62 def _GetAutobuildBuiltFilePath(cls, name): 63 if not name: 64 return None 65 autobuildFilePath = AbsJoin(GetBranchRoot(), name) 66 if os.path.isfile(autobuildFilePath): 67 return autobuildFilePath 68 69 @classmethod 70 def __LoadBinaryFromResFolder(cls): 71 if cls.IsReloadEnabled(): 72 autobuild_file = cls.GetAutobuildFilePath() 73 if autobuild_file: 74 cls.__autoBuildFileTimeStamp__ = os.path.getmtime(autobuild_file) 75 if cls.__loader__ is not NO_BINARY_LOADER: 76 if cls.__loader__ is None: 77 raise NoBinaryLoaderError() 78 resolvedBuiltFile = resolve_path(cls.__resBuiltFile__) 79 log.info('Trying to load cFSD file at %s', resolvedBuiltFile) 80 if not IS_INTERPRETER or UseResFileServer(): 81 try: 82 get_file_contents_with_yield(cls.__resBuiltFile__) 83 except RuntimeError as exc: 84 if str(exc) != 'Tasklet killed': 85 log.exception('Could not get cFSD file at %s', resolvedBuiltFile) 86 return 87 88 if not os.path.exists(resolvedBuiltFile): 89 log.error('Could not find cFSD file at %s', resolvedBuiltFile) 90 return 91 loaded = cls.__loader__.load(resolvedBuiltFile) 92 if loaded is None: 93 log.error('Could not load cFSD file at %s', resolvedBuiltFile) 94 return loaded 95 else: 96 log.info('Trying to load regular FSD file at %s', cls.__resBuiltFile__) 97 return binaryLoader.LoadFSDDataForCFG(cls.__resBuiltFile__) 98 99 @classmethod 100 def GetAutobuildFilePath(cls): 101 clientAutobuildFilePath = cls._GetAutobuildBuiltFilePath(cls.__clientAutobuildBuiltFile__) 102 serverAutobuildFilePath = cls._GetAutobuildBuiltFilePath(cls.__serverAutobuildBuiltFile__) 103 if not clientAutobuildFilePath and not serverAutobuildFilePath: 104 log.error("Failed to import binary autobuild data for BuiltDataLoader class '%s'", cls.__name__) 105 return None 106 tryClientFirst = not monolithconfig.on_proxy() and not monolithconfig.on_server() 107 if tryClientFirst: 108 return clientAutobuildFilePath or serverAutobuildFilePath 109 return serverAutobuildFilePath or clientAutobuildFilePath 110 111 @classmethod 112 def __LoadBinaryFromAutobuildFolder(cls): 113 autobuildFilePath = cls.GetAutobuildFilePath() 114 if cls.__loader__ is not NO_BINARY_LOADER: 115 if cls.__loader__ is None: 116 raise NoBinaryLoaderError() 117 log.info('Trying to load cFSD file from autobuild folder at %s', autobuildFilePath) 118 loaded = cls.__loader__.load(autobuildFilePath) 119 if loaded is None: 120 log.error('Could not load cFSD file from autobuild folder at %s', autobuildFilePath) 121 return loaded 122 log.info('Trying to load regular FSD file from autobuild folder at %s', autobuildFilePath) 123 return binaryLoader.LoadFSDDataInPython(autobuildFilePath) 124 125 @classmethod 126 def __LoadBinary(cls): 127 if useResData: 128 return cls.__LoadBinaryFromResFolder() 129 return cls.__LoadBinaryFromAutobuildFolder() 130 131 @classmethod 132 def GetData(cls): 133 if cls.__binary__ is None: 134 cls.__binary__ = cls.__LoadBinary() 135 return cls.__binary__ 136 137 @classmethod 138 def IsReloadEnabled(cls): 139 return not IS_PACKAGED and FSD_DATA_RELOAD 140 141 @classmethod 142 def CheckReloadDataFromDisk(cls): 143 if not cls.__binary__ or not cls.IsReloadEnabled(): 144 return False 145 autobuildFilePath = cls.GetAutobuildFilePath() 146 if autobuildFilePath: 147 timeStamp = os.path.getmtime(autobuildFilePath) 148 if timeStamp > cls.__autoBuildFileTimeStamp__: 149 cls.__autoBuildFileTimeStamp__ = timeStamp 150 log.info('%s: Reloading FSD data from autoBuild folder', cls.__name__) 151 tries = 10 152 while tries: 153 try: 154 cls.ReloadDataFromDisk() 155 return True 156 except IOError as error: 157 tries -= 1 158 if not tries: 159 raise 160 log.debug('%s: Failed to reload FSD data from autoBuild folder. %s. Retries left: %d', cls.__name__, error, tries) 161 time.sleep(0.1) 162 163 @classmethod 164 def ReloadDataFromDisk(cls, *args): 165 cls.__binary__ = cls.__LoadBinaryFromAutobuildFolder() 166 if cls.onReload: 167 cls.onReload() 168 169 @classmethod 170 def ConnectToOnReload(cls, callback): 171 if not cls.onReload: 172 cls.onReload = Signal() 173 cls.onReload.connect(callback)