class Modules(object): """ This class is a modules manager for the application. It keeps list of loaded modules and can load modules on demand """ def __init__(self, app): self.app = weakref.ref(app) self.modules_lock = Lock() self.loaded_modules = dict() self.not_auto_loaded = set() self.modules_locked_by = None def load(self, modules, silent=False, auto_loaded=False): """ Load requested modules. modules - list of module names (format: "mg.group.Class" means silent - don't fail on ImportError auto_loaded - remove this modules on full reload "import Class from mg.group") """ t = Tasklet.current() if getattr(t, "modules_locked", False): return self._load(modules, silent, auto_loaded) else: wasLocked = False if self.modules_lock.is_locked(): wasLocked = True with self.modules_lock: self.modules_locked_by = traceback.format_stack() t.modules_locked = True res = self._load(modules, silent, auto_loaded) t.modules_locked = False self.modules_locked_by = None return res def _load(self, modules, silent=False, auto_loaded=False): "The same as load but without locking" errors = 0 app = self.app() for mod in modules: if not auto_loaded: self.not_auto_loaded.add(mod) if mod not in self.loaded_modules: m = re_module_path.match(mod) if not m: raise ModuleError("Invalid module name: %s" % mod) (module_name, class_name) = m.group(1, 2) module = sys.modules.get(module_name) app.inst.modules.add(module_name) if not module: try: try: __import__(module_name, globals(), locals(), [], -1) except ImportError as e: if silent: logging.getLogger( "%s:mg.core.Modules" % self.app().inst.instid).exception(e) else: raise module = sys.modules.get(module_name) except Exception as e: errors += 1 module = sys.modules.get(module_name) if module: logging.getLogger( "%s:mg.core.Modules" % self.app().inst.instid).exception(e) else: raise if module: cls = module.__dict__[class_name] obj = cls(app, mod) self.loaded_modules[mod] = obj obj._register() else: app.inst.modules.remove(module_name) return errors def clear(self): "Remove all modules" with self.modules_lock: self.loaded_modules.clear() def load_all(self): "Load all available modules" with self.modules_lock: self.modules_locked_by = traceback.format_stack() t = Tasklet.current() t.modules_locked = True # removing automatically loaded modules modules = [] complete = set() for mod in self.loaded_modules.keys(): if mod in self.not_auto_loaded: modules.append(mod) self.loaded_modules.clear() self.app().hooks.clear() self._load(modules) repeat = True while repeat: repeat = False for name, mod in self.loaded_modules.items(): if name not in complete: children = mod.child_modules() self._load(children, auto_loaded=True, silent=True) complete.add(name) repeat = True t.modules_locked = False self.modules_locked_by = None
class Modules(object): """ This class is a modules manager for the application. It keeps list of loaded modules and can load modules on demand """ def __init__(self, app): self.app = weakref.ref(app) self.modules_lock = Lock() self.loaded_modules = dict() self.not_auto_loaded = set() self.modules_locked_by = None def load(self, modules, silent=False, auto_loaded=False): """ Load requested modules. modules - list of module names (format: "mg.group.Class" means silent - don't fail on ImportError auto_loaded - remove this modules on full reload "import Class from mg.group") """ t = Tasklet.current() if getattr(t, "modules_locked", False): return self._load(modules, silent, auto_loaded) else: wasLocked = False if self.modules_lock.is_locked(): wasLocked = True with self.modules_lock: self.modules_locked_by = traceback.format_stack() t.modules_locked = True res = self._load(modules, silent, auto_loaded) t.modules_locked = False self.modules_locked_by = None return res def _load(self, modules, silent=False, auto_loaded=False): "The same as load but without locking" errors = 0 app = self.app() for mod in modules: if not auto_loaded: self.not_auto_loaded.add(mod) if mod not in self.loaded_modules: m = re_module_path.match(mod) if not m: raise ModuleError("Invalid module name: %s" % mod) (module_name, class_name) = m.group(1, 2) module = sys.modules.get(module_name) app.inst.modules.add(module_name) if not module: try: try: __import__(module_name, globals(), locals(), [], -1) except ImportError as e: if silent: logging.getLogger("%s:mg.core.Modules" % self.app().inst.instid).exception(e) else: raise module = sys.modules.get(module_name) except Exception as e: errors += 1 module = sys.modules.get(module_name) if module: logging.getLogger("%s:mg.core.Modules" % self.app().inst.instid).exception(e) else: raise if module: cls = module.__dict__[class_name] obj = cls(app, mod) self.loaded_modules[mod] = obj obj._register() else: app.inst.modules.remove(module_name) return errors def clear(self): "Remove all modules" with self.modules_lock: self.loaded_modules.clear() def load_all(self): "Load all available modules" with self.modules_lock: self.modules_locked_by = traceback.format_stack() t = Tasklet.current() t.modules_locked = True # removing automatically loaded modules modules = [] complete = set() for mod in self.loaded_modules.keys(): if mod in self.not_auto_loaded: modules.append(mod) self.loaded_modules.clear() self.app().hooks.clear() self._load(modules) repeat = True while repeat: repeat = False for name, mod in self.loaded_modules.items(): if name not in complete: children = mod.child_modules() self._load(children, auto_loaded=True, silent=True) complete.add(name) repeat = True t.modules_locked = False self.modules_locked_by = None