客户端未在GAE python上设置缓存值

客户端未在GAE python上设置缓存值,python,google-app-engine,caching,memcached,Python,Google App Engine,Caching,Memcached,我正在尝试将memcache添加到部署在GAE上的webapp中,为此,我使用memcache.Client()来防止任何赛车条件造成的损坏: from google.appengine.api import memcache client = memcache.Client() class BlogFront(BlogHandler): def get(self): global client val = client.gets(FRO

我正在尝试将memcache添加到部署在GAE上的webapp中,为此,我使用
memcache.Client()
来防止任何赛车条件造成的损坏:

from google.appengine.api import memcache

client = memcache.Client()
class BlogFront(BlogHandler):
    def get(self):       
        global client 
        val = client.gets(FRONT_PAGE_KEY)
        posts = list()

        if val is not None:
            posts = list(val)
        else:
            posts = db.GqlQuery("select * from Post order by created desc limit 10")
            client.cas(FRONT_PAGE_KEY, list(posts))

        self.render('front.html', posts = posts)
为了测试这个问题,我在一个博客的首页上显示了10条最新的条目。如果缓存中没有任何内容,我会通过请求命中数据库,否则我只会将缓存结果呈现给用户

问题是,无论我做什么,我总是得到
val==None
,这意味着我总是用一个无用的请求访问数据库

我已对文件进行了筛选:

看来我做的每件事都是正确的。我错过了什么


(注:我是python新手,如果这是延迟错误,请容忍我xD)

我怀疑client.cas调用失败,因为没有对象。也许client.cas仅用于更新和现有对象(如果当前没有对象,则不用于设置新对象)?您可以尝试client.add()(如果已存在具有指定密钥的对象,则该操作将失败,我认为这是您想要的?),而不是google.appengine.api import memcache中的client.cas()

class BlogFront(BlogHandler):
    def get(self):       
        client = memcache.Client() 
        client.gets(FRONT_PAGE_KEY)
        client.cas(FRONT_PAGE_KEY, 'my content')
出于一个我还无法理解的原因,解决方案在于在调用
cas
之前先调用
get


我想我现在会继续使用memcache非线程安全版本的代码…

现在不要担心竞争条件。只需使用“添加”和“获取”使其尽可能简单地工作即可。如果您试图保存的内容超出了memcache中单个对象的大小限制,这可能会解释您的问题。如果我将
client.get(key)
client.cas(key,val)
替换为
memcache.get(key)
memcache.set(key,val)
所有操作都非常正常。问题在于使用memcache。客户端和竞争条件是一个真正的问题:那么你就对了。你的“新手”把我甩了:P不知道……真的有比赛条件吗?它是如何在你的处境中表现出来的?您并没有真正更新一个需要原子化的值。唯一可能出现的真正问题是狗堆效应。此外,您甚至似乎没有正确使用CAS,因为您当前的方法无法防止竞争条件,它只会检测到竞争条件。您需要一个循环和一次重试,因为只有文档和CAS更新,它不会添加。请看我在这里链接的文档中的示例,文章是页面中唯一的动态元素吗?如果是这样,为什么要缓存帖子并重新呈现页面,为什么不缓存呈现的页面呢?我想使用
cas
,因为cas可以防止竞争条件,而
add
不能:S同样,如果没有对象,那么客户端将没有,并且会发生异常,对吗?事实并非如此:SI不同意add不能防止种族状况。添加“[s]设置一个键的值,当且仅当该项不在memcache中。”(from)re:“另外,如果没有对象,那么客户端将没有,并且会发生异常,对吗?”不,我不确定您为什么认为在这种情况下客户端将没有。客户端由“memcache.client()”创建。如果没有对象,则val为None。这段代码用于更新缓存。Add不允许这样做,而cas允许这样做,即我可以使用cas更新密钥的值