Skip to content

同步

bae 的同步是 coven 的同步:bae 宣告自己的表與 blob,coven 處理其餘工作。本頁說明這些機制套用到 bae 時的樣子;coven 自己的文件完整涵蓋各個部分。

coven 擁有 SQLite 連線,因此 bae 提交的每次寫入都會經過它。當一個變更同步表的 transaction 提交時,coven 會在同一個 transaction 中記錄每一列的變更及其涉及的欄位,因此已提交的變更不會遺失,即使 App 隨後立刻當機。沒有 diffing,沒有 dirty flag:捕捉是連線的屬性,寫入不可能被漏掉。變更會先在裝置上等待,直到傳送時才加密與簽署,因此寫入既不需要金鑰也不需要網路。

資料庫在雲端主目錄中的全部歷史是一條編號的物件序列。每個物件包含一台裝置的一批變更、一個管理項目、封存給某位成員的金鑰,或一則 snapshot 公告。每台裝置依序套用它們,從不跳過,因此所有裝置對發生了什麼、何時發生都有共識。裝置只有在套用之前的所有物件後,才會新增下一個物件。

一次同步程序會從裝置最後套用的物件開始往前讀取,直到遇到缺少的物件,逐一檢查簽章並套用,把此裝置排隊的變更以一個新物件傳送,然後完成新狀態要求的工作:分享或取消分享存取權、產生 snapshot、刪除舊歷史。對一個沒有變動的資料庫,一次同步程序只需要兩個請求,不論其規模多大。

同步程序會在本機變更後、閒置計時器上,以及按下 立即同步 時立即執行。失敗會依同一個退避計畫重試,任何無法繼續的事項都會說明它在等待什麼,bae 會在同步狀態列中顯示這些內容。

兩台裝置分開時編輯同一個資料庫是正常情況,不是例外。當它們的變更相遇時:

  • 對不同行或不同欄的編輯都會套用。在筆電上編輯發行版本年份,同時在桌面上編輯其廠牌,會得到兩者。
  • 對同一列同一欄的編輯會依時間戳記排序:較晚的編輯勝出,且每個裝置上結果都確定且相同。
  • 刪除勝過並行編輯:對已被刪除的列所做的編輯不論何時抵達都會失敗,因此一台裝置刪除的發行版本,即使另一台裝置在同一段時間編輯過它,仍會保持刪除。

coven 會把每個被取代的值保留為遺失值;bae 不顯示也不捨棄其中任何一個,因此沒有衝突 UI。無論抵達順序如何,每個裝置都會收斂到相同結果。

加入或還原的裝置不會從頭重放歷史。裝置會產生 snapshot,也就是資料庫在序列中某一點的完整狀態;當資料庫與每個私人圈子都有 snapshot 後,之前的歷史就會被刪除。新裝置載入最新的 snapshot,然後只套用其後的內容。離開時間超過所保留歷史的裝置也會這麼做,並保留自己尚未傳送的編輯。

bae 的架構只有一個遷移,裝置傳送的每項變更都會記錄其所用的架構版本。裝置遇到來自比自己更新架構的變更時會停在那裡,在 App 更新前不套用其後的任何內容;沒有內容遺失,也沒有內容被錯誤套用。

比架構版本更大的單位是相容時代:烘焙進每個二進位程式的固定 coven 修訂版。兩個建置只能在同一時代內同步;coven 傳輸格式破壞相容就是新的時代,並使每個 App 的主版本增加。1.0 前,每個建置都是時代零,格式變更不做遷移。

提供者儲存加密的變更、snapshot、成員資格記錄與檔案;它可以計算物件數量、觀察大小與時間,並看到每個物件由哪個帳號寫入,但不能讀取任何內容。裝置拉取的每個物件都會先驗證簽章與成員資格,才會碰到資料庫:儲存空間是被動且不受信任的信箱。請見加密與身分與成員資格。