0

Redis ハッシュのインターフェースを実装するダミーのラッパー クラス (mongoengine Document ) を作成しようとしています。例えば:

class HashModel(mongoengine.Document):
    '''
    Represents a dictionary with a name.
    Interface similar to Redis Hashes
    '''
    name = mongoengine.StringField()
    adict = mongoengine.DictField()

    def safe_reload(self): # because it fails if no object present
        try: self.reload()
        except:pass

    def fix_key(self, key): # for mongoengine validation ( if you really read my code, please also answer why does mongoengine need that ) 
        return key.replace(".","").replace("$","") 

    def hset(self, key, value):
        self.safe_reload()
        self.adict["%s" % self.fix_key(key)] = value  
        self.save(safe=True)
        return True

    def hexists(self, key):
        self.safe_reload()
        key = "%s" % self.fix_key(key)
        return key in self.adict 

次に、セロリを使用していくつかのタスクを実行します。その前に、タスクがいくつかの操作を実行する HashModel オブジェクトを初期化します。しかし、マルチプロセッシングのため、いくつかの矛盾に気付きました。プロセスが異なれば、オブジェクトの別の「スナップショット」が「取得」されますが、これは当然のことです。この問題を回避するために、オブジェクトを毎回再初期化して、毎回「ほぼ」新しいスナップショットを取得します。

質問: 再初期化を回避する方法はありますか? 上記のクラスにコードを追加して、それを自動的に行うことはできますか?

編集: 回答: mongoengine.Document.reload() 関数がこれを行うようです。次の問題に関連するすべてを表示するようにコードを更新しました。

セロリ タスクに戻ると、この問題が発生しました。hset に強制しても、次のようになります。

    while True:
        self.handler.hset(a_key, a_value)
        if self.handler.hexists(a_key): 
            break

後である時点で (他の場所で a_key を削除せずに)、hexists(a_key) が False を返すことがあります。どうしてですか????

4

1 に答える 1

1

これは純粋な競合状態の問題です。私のセロリワーカーはインスタンスを同時に取得し、それに対してさまざまな操作を実行してから保存することができ、一貫性がなくなります..

于 2011-10-21T16:56:42.267 に答える