1

を逃すためにfalseを返す続けて次のGoogleのApp Engine上で動作しているのPythonフラスコアプリケーションの一部です:私たちが作る場合は、空のキャッシュを皮切りGoogle App Engineのmemcache.Client.casは()キー

@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 -loopでスタックされます。どうやらこれは、キー'key'が最初に存在しないために起こります。

memcache.add('key', None)のコメントを外すと、キーが存在し、.cas()がうれしくてTrueが返されるため、これは分かります。しかし、.add().gets()の間にキャッシュをフラッシュする他のプロセスがあった場合は、キーが見つからずに開始したところに戻り、.cas()は無期限にFalseを返します。だから、それは良い解決策ではありません。

.cas()が最初にキーが見つからない場合はどうしたらいいですか?または、少なくとも.cas()initial_value=パラメータを兄弟のように受け入れないのですか?decr()?バグか機能ですか?私はグイド・ヴァンロッサムはassertに-reffering彼single blog post on the matterでそれを暗示彼は.gets()Noneを返さないことになることを除いて、これはどこでも適切に文書を見つけることができない、と彼は言う:脇

2:アサート一種のナイーブです。実際には、カウンターの初期化に何とか対処しなければなりません。

デンジャー・ウェル・ギドー誰にも分かりますか?

答えて

1

私はそれを理解しました。

@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は重複していますが、私たちが成功するまで続けようとしていることを明確にするために書いています。

実際には、いくつかの再試行の後で何とかしてあきらめる必要があります。