2011-10-12 61 views
0

我想創建一個實現Redis哈希接口的虛擬包裝類(mongoengine Document)。例如:併發的Mongoengine文檔一致性

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(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。怎麼了?

回答

0

這是一個純粹的競爭條件問題。我的芹菜工人可能會同時獲得一個實例並對其執行不同的操作,然後保存,不再一致。