2014-06-23 22 views
0

我希望能夠阻止從用戶的本地實例(存在多個用戶的位置)向中央CouchDB實例「推送」(或複製) - 如果存在任何衝突 - 實質上是複製功能從像Git或Mercurial這樣的用戶,在推送到中央服務器之前,用戶必須解決其本地副本上的衝突(因此服務器可以保持「乾淨」)。CouchDB阻止在衝突時進行復制

據我所見,有兩種選擇;如果存在衝突,則阻止用戶提交(儘管如果沒有實際完成複製,我看不到任何方法),或者完成複製,查看是否有任何衝突,然後刪除推送的複製(以及關聯文件)是否存在衝突(儘管如果在文件被重新刪除之前完成了拉取,並且效率有點低下,這也可能導致不希望的行爲)。

因此,要燒掉,理想情況下,我想複製如果有衝突回滾,並通知我發生了衝突(我不關心衝突的性質,因爲然後我可以啓動一個拉請求複製來複制本地數據庫中的中央數據庫)。

有沒有辦法實現我錯過的任何一種方法?

回答

0

雖然它可能不是最好的解決方案,但我做了一些更復雜的事情;

  1. 向中央數據庫發出複製請求,指定複製標識爲[RequestingMacAddress]。[Guid]。
  2. 當向中央數據庫發出複製推送請求時,我使用自定義視圖(使用相同的MAC地址)檢查最後一個請求標識(在中央數據庫上)。
  3. 我按降序拉取_changes,並確保數據庫上最近的更改是上面指定的[RequestingMacAddress]。[GUID],或者是另一個請求(到另一臺機器),並且沒有任務當前處於活動狀態(例如,推送複製正在從另一臺機器進行)。
  4. 如果一切順利 - 允許推複製繼續,否則出錯。

如果有的話,我們會尋找更好的解決方案。

0

您可以嘗試使用validate_doc_update函數來實現此目的。 AFAIK你可以訪問新文檔中的_conflicts屬性來檢查是否會有一些衝突。但我從來沒有嘗試過。

也許這樣的功能會工作:

function(newDoc, oldDoc, userCtx, secObj) { 
    if (newDoc._conflicts && newDoc._conflicts.length) { 
    throw({forbidden: 'Your change would cause conflicts. Try resolving the conflicts locally before replicating.'}); 
    } 
} 

只要確保這個validate_doc_update功能只適用於中央數據庫的設計文檔存在,否則,用戶將不能夠「拉」相沖突改變他們的本地數據庫。

請讓我知道這是否行得通!

+0

謝謝伯恩哈德,我會放手給你回覆。我正在處理的另一個選項是比較該機器最近一次拉複製的checkpoint_seq(使用機器的MAC作爲複製ID的一部分),然後檢查_changes以確定是否存在後續更改。如果它的工作原理,你的解決方案更漂亮! – Ian

+1

從我看到的 - 我稱爲鍵(newDoc)並記錄對象屬性 - 似乎不幸的是它只有_id,_rev和_revisions。我猜如果它被刪除,那麼它可能會得到如文檔所示的附加屬性_deleted。 – Ian

+0

感謝您的信息,不幸的是,這不起作用... –