首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >配置自动重新加载模板并为应用程序引擎中的jinja2启用字节码缓存

配置自动重新加载模板并为应用程序引擎中的jinja2启用字节码缓存
EN

Stack Overflow用户
提问于 2014-01-24 10:28:38
回答 2查看 1.4K关注 0票数 0

如何在Appengine中将jinja2配置为:

  1. 更新模板时自动重新加载。
  2. 启用字节码缓存,以便在每个实例之间共享。我更喜欢jinja2在编译模板时生成字节码,并将其存储到数据存储中。因此,下一个实例将加载字节码,而不是重复编译模板。
EN

回答 2

Stack Overflow用户

发布于 2014-01-24 18:12:08

我使用app engine memcache Client()添加了如下bcc::

代码语言:javascript
复制
loader = dynloaders.DynLoader()     # init Function loader
bcc = MemcachedBytecodeCache(memcache.Client(), prefix='jinja2/bytecode/', timeout=None)
return Environment(auto_reload=True, cache_size=100, loader=FunctionLoader(loader.load_dyn_all),
                   bytecode_cache=bcc)

我的函数加载程序:

代码语言:javascript
复制
def html(self, cid):

    def _html_txt_up_to_date():  # closure to check if template is up to date

        return CMSUpdates.check_no_update(cid, template.modified)

    template = ndb.Key('Templates', cid, parent=self.parent_key).get()
    if not template:
        logging.error('DynLoader (HTML/TXT): %s' % cid)
        return None              # raises TemplateNotFound exception

    return template.content, None, _html_txt_up_to_date

模板模型使用template.modified : ndb.DateTimeProperty(auto_now=True)

闭包功能:

代码语言:javascript
复制
class CMSUpdates(ndb.Model):                                                                        
    updates = ndb.JsonProperty()

    @classmethod
    def check_no_update(cls, cid, cid_modified):                                                      

        cms_updates = cls.get_or_insert('cms_updates', updates=dict()).updates
        if cid in cms_updates:   # cid modified has dt microseconds
            if cid_modified >= datetime.strptime(cms_updates[cid], '%Y-%m-%d %H:%M:%S'):
                if (datetime.now() - timedelta(days=1)) > cid_modified:
                    del cms_updates[cid]
                    cls(id='cms_updates', updates=cms_updates).put_async()
                return True
            return False         # reload the template
        return True                    
票数 3
EN

Stack Overflow用户

发布于 2014-01-24 10:28:38

几个星期以来我一直在寻找解决方案。最后我想出来了,我想和大家分享我的代码。我的代码中有4个python源文件。

TemplateEngine.py,ContentRenderer.py,TestContent.py & Update_Template.py

文件: TemplateEngine.py

注意:

我现在使用= datetime.utcnow() + timedelta(hours=8),因为我的时区是GMT+8

您必须使用ndb.BlobProperty来存储字节码,ndb.TextProperty将无法工作!

代码语言:javascript
复制
from google.appengine.ext import ndb
from datetime import datetime,timedelta

class SiteTemplates(ndb.Model):
  name = ndb.StringProperty(indexed=True, required=True)
  data = ndb.TextProperty()
  uptodate = ndb.BooleanProperty(required=True)

class SiteTemplateBytecodes(ndb.Model):
  key = ndb.StringProperty(indexed=True, required=True)
  data = ndb.BlobProperty(required=True)
  mod_datetime = ndb.DateTimeProperty(required=True)

class LocalCache(jinja2.BytecodeCache):

  def load_bytecode(self, bucket):
    q = SiteTemplateBytecodes.query(SiteTemplateBytecodes.key == bucket.key)
    if q.count() > 0:
      r = q.get()
      bucket.bytecode_from_string(r.data)

  def dump_bytecode(self, bucket):
    now = datetime.utcnow() + timedelta(hours=8)
    q = SiteTemplateBytecodes.query(SiteTemplateBytecodes.key == bucket.key)
    if q.count() > 0:
      r = q.get()
      r.data = bucket.bytecode_to_string()
      r.mod_datetime = now
    else:
      r = SiteTemplateBytecodes(key=bucket.key, data=bucket.bytecode_to_string(), mod_datetime=now)
    r.put()

def Update_Template_Source(tn, source):
  try:
    q = SiteTemplates.query(SiteTemplates.name == tn)
    if q.count() == 0:
      u = mkiniTemplates(name=tn, data=source, uptodate=False)
    else:
      u = q.get()
      u.name=tn
      u.data=source
      u.uptodate=False
    u.put()
    return True
  except Exception,e:
    logging.exception(e)
    return False

def Get_Template_Source(tn):
  uptodate = False

  def Template_Uptodate():
    return uptodate

  try:
    q = SiteTemplates.query(SiteTemplates.name == tn)
    if q.count() > 0:
      r = q.get()
      uptodate = r.uptodate

      if r.uptodate == False:
        r.uptodate=True
        r.put()

      return r.data, tn, Template_Uptodate
    else:
      return None
  except Exception,e:
    logging.exception(e)
    return None

文件: ContentRenderer.py

注意:设置cache_size=0,非常重要,否则字节码缓存功能将被禁用。我不知道为什么。

代码语言:javascript
复制
from TemplateEngine import Get_Template_Source
import jinja2 

def Render(tn,tags):
  global te
  return te.Render(tn, tags)

bcc = LocalCache()
te = jinja2.Environment(loader=jinja2.FunctionLoader(Get_Template_Source), cache_size=0, extensions=['jinja2.ext.autoescape'], bytecode_cache=bcc)

文件: Update_Template.py

注意:使用Update_Template_Source()将模板源更新为数据存储。

代码语言:javascript
复制
from TemplateEngine import Update_Template_Source
template_source = '<html><body>hello word to {{title}}!</body></html>'
if Update_Template_Source('my-template.html', template_source):
  print 'template is updated'
else:
  print 'error when updating template source'

文件: TestContent.py

注意:做些测试

代码语言:javascript
复制
from ContentRenderer import Render
print Render('my-template.htmnl', {'title':'human'})
'hello world to human!'

您将意识到,即使您在您的应用程序中有超过20个实例,延迟时间不会增加,甚至您更新您的模板。模板源将在5到10秒内更新。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21330257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档