python - Google App Engine memcache.Client.cas() 因缺少 key 而不断返回 False

标签 python google-app-engine caching google-app-engine-python

以下是在 Google App Engine 上运行的 Python Flask 应用程序的一部分:

@app.route('/blabla', methods=['GET'])
def blabla():
    # memcache.add('key', None)  # this "fixes" it!  
    memcache_client = memcache.Client()
    while True:
        value = memcache_client.gets('key')
        if value is None:  # First time
            updated_value = 'Bla'
        else:
            updated_value = value + ', bla'
        if memcache_client.cas('key', updated_value):
            return updated_value

从空缓存开始,如果我们向/blabla 发出连续的 GET 请求,我希望请求返回:

Bla
Bla, bla
Bla, bla, bla
.
.

(如果由于某种原因在 .gets()cas() 之间的某个时刻缓存被刷新,那么我希望序列重新启动,没问题.)

但是我们什么也没得到,因为 memcache_client.cas() 永远返回 False,因此程序陷入了 while -环形。显然,发生这种情况是因为 key 'key' 一开始就不存在。

我知道这一点,因为如果我取消注释 memcache.add('key', None),它就可以工作,因为这样 key 就存在并且 .cas() code> 很高兴并返回 True。但是,如果在 .add().gets() 之间有其他进程要刷新缓存,我们就会回到我们开始的地方,缺少 key ,.cas() 将无限期地返回返回 False。所以这不是一个好的解决方案。

如果一开始就缺少 key ,为什么 .cas() 不起作用?或者至少,为什么 .cas() 不接受 initial_value= 参数,就像它的兄弟 decr() 一样。 ?这是一个错误还是一个功能?除了 Guido van Rossum 在他的 single blog post on the matter 中提到的之外,我在任何地方都找不到正确的记录。 ——提到 assert,他使 .gets() 不返回 None,他说:

Aside 2: The assert is kind of naive; in practice you'll have to somehow deal with counter initialization.

Dank je wel Guido——请问有人知道怎么做吗?

最佳答案

好吧,我明白了。

@app.route('/blabla', methods=['GET'])
def blabla():
    memcache_client = memcache.Client()
    while True:

        if memcache.add('key', 'Bla'):
            # That's all folks!
            return 'Bla'

        # add() failed => the key must already exist, we have to compare-and-set.

        value = memcache_client.gets(key_name)

        if value is None:
            # At the time add() failed the key existed, but now gets() is returning None,
            # so somebody must have deleted the cache entry in between.
            # Let's start from scratch.
            continue

        updated_value = value + ', bla'

        if memcache_client.cas(key_name, updated_value):
            return updated_value
        else:
            continue

它比我希望的要复杂,但它有效。

最后一个else: continue是多余的,但我写它是为了明确我们将继续尝试,直到成功。

尽管在实践中,您必须以某种方式处理多次重试后的放弃。

关于python - Google App Engine memcache.Client.cas() 因缺少 key 而不断返回 False,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41308544/

相关文章:

java - 云存储 - 上传图像时文件的内容类型显示为数据

java - OrientDB性能测试禁用缓存

javascript - 使 Angular 中的所有 $http 缓存失效

python - 使用 scrapy 爬虫进行虚假地理定位

python - email.header.decode_headers() 抛出 HeaderParseError

python 2.7 : How to use BeautifulSoup in Google App Engine?

android - ImageDownloader 的最大硬缓存大小

python - 我的初学者项目出错

python - Ubuntu OpenCV:加载视频文件时程序崩溃

java - 使用 App Engine 配置 ReSTLet