【问题标题】:How to reload bytecode from the datastore in app engine如何从应用引擎中的数据存储区重新加载字节码
【发布时间】:2012-11-24 15:55:50
【问题描述】:

我创建了一个导入钩子(基于PEP 302),用于从数据库中动态加载python字节码(编译后的python代码)。

import dyn_imports.test   #@UnresolvedImport

这工作正常,但如果我更改模块并重新加载模块,模块会重新加载但我看不到更改。

这就是我创建字节码的方式:

code_object = compile(db.Text(dyn.py_source).encode(), dyn.name.encode(), 'exec')
key_name = 'dyn_imports.' + name
dynmod = models.Dynmods(key_name = key_name, name = key_name, bytecode = db.Blob(marshal.dumps(code_object)))
dynmod.put()
reload(sys.modules[key_name])             # reload the updated code

reload() 执行导入钩子的 load_module 部分。
这是import hook类中load_module函数的简化版:

def load_module(self, mod_name):
    mod = imp.new_module(mod_name)
    mod.__loader__ = self
    dynmod = models.Dynmods.get_by_key_name(mod_name)    # load from DB
    mod.__file__ = mod_name
    exec marshal.loads(db.Blob(dynmod.bytecode)) in mod.__dict__
    sys.modules[mod_name] = mod
    return mod

当我关闭实例时,它工作正常。

更新:我还使用 py 源代码而不是字节码测试了导入加载器。这也不起作用。我已经在开发服务器上完成了大部分测试。

我创建了一个 Jinja2 module loader before,它从数据存储区加载 Jinja 编译的模板(= py 源)。当我重新创建 Jinja 环境并从 sys.modules 中删除模块(编译模板)时,新模块会重新加载,而无需重新启动实例。那么我在这里做错了什么?

【问题讨论】:

    标签: google-app-engine import python-2.7 hook jinja2


    【解决方案1】:

    我找到了解决办法。除了重新加载更改的模块之外,我还必须重新加载所有使用(导入)此模块的模块。我做了一些测试,效果很好。正确的顺序也很重要。所以现在我必须弄清楚,如何创建一个导入依赖图并使用它来重新加载模块。

    但这是一个新问题。

    当模块导入动态模块时,我会创建一个依赖项列表。使用这个列表,我可以重新加载依赖模块。我还必须标记我的 GAE appid 的其他实例。这些其他实例必须重新加载标记的动态模块(如果使用)并重新加载此其他实例中动态模块的依赖模块。

    为了为每个实例创建唯一的实例 ID,我添加了类变量:

    instance = datetime.datetime.utcnow()
    

    到导入钩子类。 setter 实例使用 Memcache 来标记其他实例。此标志包含每个重新加载的动态模块:标志设置器实例和动态模块的重新加载日期时间戳。其他(标志获取器)实例可以检查是否必须重新加载动态模块。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-08
      • 2013-02-08
      • 2012-04-11
      相关资源
      最近更新 更多