2012-07-30 80 views
1

所以,這個問題相當詳細。我會盡力解釋。任何幫助將不勝感激。提前致謝!Django memcached不一致

我正在構建一個使用tornadio2 + Memcached的應用程序,並且在嘗試從緩存中取出時發現了一些令人困惑的事情。

對於初學者來說,這裏是我的broadcast_to_players()函數:

def broadcast_to_players(self, g_id, event, message, update_secret=False, dont_update_self=False): 
    the_game = cache.get(g_id) 
    for player in the_game.player_list: 
     if update_secret == True: 
      secret = self.get_secret() 
      message['k'] = secret 
      player.secret_key = secret 
     if dont_update_self == True: 
      if not self.session_id == player.session_id: 
       single_session = self.session.server._sessions.get(player.session_id) 
       single_session.conn.emit(event, message) 
     else: 
      single_session = self.session.server._sessions.get(player.session_id) 
      single_session.conn.emit(event, message) 
    cache.set(g_id, the_game) 

    ## FOR TESTING PURPOSES ## 
    if update_secret == True: 
     other_game = cache.get(g_id) 
     for player in other_game.player_list: 
      print "player.secret_key in broadcast_to_players = %s" % player.secret_key 

正如你所看到的,它抓住the_game從緩存中,做的東西給它,修改的消息,在我player_list更新的球員,發送消息。然後,它將遊戲設置爲緩存。之後,(爲了測試目的)我再次抓住它並測試每個玩家的secret_key值是否在緩存中。他們這樣做。

然而,當我試圖再次抓住從緩存中的同一個遊戲,它說,SECRET_KEY =無

def check_player(self, g_id, key): 
    the_game = cache.get(g_id) #I'm able to 
    the_player = None 
    for player in the_game.player_list: 
     if player.secret_key == key: 
      the_player = player 
    return the_player 

該遊戲被緩存,但player_list沒有在遊戲模式進行更新。這裏是我的比賽,球員模型:
http://pastebin.com/t66qgeeb - 遊戲模式
http://pastebin.com/7FjpeSLx - 玩家模型

正如你所看到的,播放器模式有許多一對多的關係,以遊戲,通過用戶。另外,我在Django模型類中保留了許多非持久變量(用於玩遊戲)。我的猜測是,這可能與我抓住與我的遊戲相關的所有玩家,將它們放入player_list,然後嘗試更新它們有關。而memcached不會做那麼深的副本?我不知道,而且我一直在試圖弄清楚自己的大腦。任何幫助都將不勝感激。謝謝!

回答

2

好的。讓我們逐點移動:

  1. 請勿將大對象放在memcached中 - 您將很有可能錯過 。
  2. 在這種情況下 - 拆分鍵。遊戲中必須有一個鍵,一個關鍵球員列表和每個球員的鍵。
  3. 通過密鑰player_<g_id>_<key>將玩家存儲在內存緩存中 - 那麼您將可以輕鬆獲得玩家。

讓我們把它放在一起:

def broadcast_to_players(self, g_id, event, message, update_secret=False, dont_update_self=False): 
    the_game = cache.get(g_id) 
    player_list = cache.get('game_%s_players' % g_id) #Getting list of players ids 
    for player_key in player_list: 
     player = cache.get('game_%s_%s' % (g_id, player_key)) 
     if update_secret == True: 
      secret = self.get_secret() 
      message['k'] = secret 
      player.secret_key = secret 
      player.save() #We are storing secret in db, right? 
      cache.set('game_secret_%s_%s' % (g_id, secret), player_key) #Making player availiable in game by secret 
      cache.set('player_%s_secret' % (player_key,), secret) #Making player secret available by player id 
     if dont_update_self == True: 
      if not self.session_id == player.session_id: 
       single_session = self.session.server._sessions.get(player.session_id) 
       single_session.conn.emit(event, message) 
     else: 
      single_session = self.session.server._sessions.get(player.session_id) 
      single_session.conn.emit(event, message) 
    cache.set(g_id, the_game) 

def check_player(self, g_id, key): 
    return cache.get('game_secret_%s_%s' % (g_id, key)) 

這是唯一的想法,你應該怎麼想的,與鍵/值存儲裝置工作時。

+0

感謝您的建議!這很有意義,並且確實不太複雜。我以前的做事方式造成了競爭狀況 - 有時緩存在需要之後被保存。這更有意義。再次感謝。 – 2012-07-31 15:28:25

1

您的「用於測試目的」部分並不是真的測試任何東西。它不僅遍歷屬於原始'the_game'對象的玩家列表,而不是剛剛從緩存中獲得的'other_game',則打印語句將打印局部變量'secret'的值,而不是player.secret_key的值。

+0

是的,這是我做的一個非常糟糕的測試。我更新了它,現在測試一些東西。不過,同樣的結果。它從緩存中抓取它,但由於某種原因不會通過函數調用持續存在。 – 2012-07-30 21:59:01