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 

然后,我使用 celery 执行一些任务。在此之前,我初始化了一个 HashModel 对象,任务在该对象上执行一些操作。但是由于多处理,我注意到一些不一致的地方。不同的进程“获得”对象的不同“快照”,这无论如何都是自然的。为了绕过这个问题,我每次都重新初始化对象,以便每次都能获得“几乎”新鲜的快照。

问题:有没有办法避免重新初始化?我可以在上面的类中添加一些代码以及哪些代码来自动执行此操作吗?

编辑:回答:看来,mongoengine.Document.reload() 函数可以做到这一点。我更新了我的代码以显示与我的下一个问题相关的所有内容:

回到 celery 任务中,出现了这个问题:当我 hset(a_key, a_value) 时,然后当我尝试检查它是否存在时,有时 hexists(a_key) 返回 False。即使我强迫它去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 回答