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

ゲームはキャッシュされていますが、game モデルで player_list が更新されていません。これが私のゲームとプレーヤーのモデルです:
http://pastebin.com/t66qgeeb - ゲームモデル
http://pastebin.com/7FjpeSLx - プレーヤーモデル

ご覧のとおり、Player モデルは User を介して Game と多対多の関係にあります。また、Django モデル クラスに保持している (プレイ中のゲーム用の) 非永続変数が多数あります。私の推測では、自分のゲームに関連付けられているすべてのプレーヤーを取得し、それらを player_list に入れてから更新しようとしているという事実と関係があるのではないでしょうか? そして、memcached はそれほど深いコピーを行いませんか? 私にはわかりません、そして私はそれを理解しようとして頭を悩ませてきました。どんな助けでも大歓迎です。ありがとう!

4

2 に答える 2

2

Ok。ポイントごとに移動しましょう。

  1. memcached に大きなオブジェクトを置かないでください。見逃す可能性が高くなります。
  2. この場合 - 鍵を分割します。ゲーム用のキー、キー プレーヤー リスト、およびゲーム内の各プレーヤー用のキーが 1 つずつ必要です。
  3. プレーヤーをキーで memcache に保存する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

「テスト目的」セクションは、実際には何もテストしていません。キャッシュから取得したばかりの「other_game」ではなく、元の「the_game」オブジェクトに属するプレーヤー リストを繰り返し処理するだけでなく、print ステートメントは値ではなく、ローカル変数「secret」の値を出力します。 player.secret_key の。

于 2012-07-30T21:51:33.417 に答える