1

所以,这个问题比较复杂。我会尽力解释。任何帮助将不胜感激。提前致谢!

我正在构建一个使用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 = None

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 没有在 Game 模型中更新。这是我的游戏和玩家模型:
http://pastebin.com/t66qgeeb - 游戏模型
http://pastebin.com/7FjpeSLx - 玩家模型

如您所见,Player 模型通过 User 与 Game 具有多对多的关系。此外,我在 Django 模型类中保留了许多非持久变量(用于正在玩的游戏)。我的猜测是这可能与我正在抓取与我的游戏相关的所有玩家,将它们放入 player_list,然后尝试更新它们的事实有关?而且 memcached 没有做那么深的副本?我不知道,我一直在绞尽脑汁想弄清楚。任何帮助都将不胜感激。谢谢!

4

2 回答 2

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))

在使用键/值存储时,您应该如何思考只是一个想法。

于 2012-07-31T06:03:33.933 回答
1

您的“用于测试目的”部分并没有真正测试任何东西。它不仅遍历属于原始“the_game”对象的玩家列表,而不是刚刚从缓存中获取的“other_game”,打印语句还打印局部变量“secret”的值,而不是值player.secret_key 的。

于 2012-07-30T21:51:33.417 回答