搜尋

複製品大圖

Jan 02, 2025 pm 08:23 PM

複製快取

這是一個幫助實現本地優先軟體的框架。 Git 同樣可以透過推和拉來幫助組織同步任務。

Replicache 在後台非同步同步伺服器數據,消除伺服器往返並實現即時 UI 變更。

複製零件

Replicache 由多個元素組成。

複製快取

Replicache 可以被視為瀏覽器內的鍵值存儲,其中包含內部類似 git 的操作。先寫入內存,後同步。

您的申請

這是我們創建的應用程序,就像網頁應用程式一樣。它是 Replicache 中儲存狀態的實體。變異器和訂閱的實作是為了改變和回應狀態

你的伺服器

它的存在是為了儲存最可靠的資料。連接到伺服器的資料庫中儲存的狀態優先於應用程式中的狀態。

伺服器必須實作push(上游)和pull(下游)才能與客戶端的Replicache通訊。

  • push(上游):Replicache 將變更傳送到推播端點。變異器在伺服器和應用程式上實現,並且此推送端點執行此變異器來更改資料庫的狀態。

  • pull(下游):當定期或明確要求時,Replicache 會向伺服器發送拉取請求。伺服器傳回客戶端所需的更改,以使其與伺服器的狀態相同。

  • poke:雖然客戶端會週期性的發送一個pull request,但是為了更即時的展示,當服務端有變化時,就是服務端給客戶端一個提示的信號提出拉取請求。它不攜帶任何數據。

同步

應用程式和伺服器已同步到最新狀態。下圖清楚地展示了這個過程。它展示了定期從伺服器拉取狀態變更並更新 UI 的過程,以及客戶端上的狀態變更如何先更新 UI,然後推送到伺服器

Replicache Big Picture
來源

客戶端、客戶端群組、快取

記憶體中的副本稱為客戶端。

import {Replicache} from "replicache";

const rep = new Replicache({
  name: userID,
  ...
});

console.log(rep.clientID);

每次點擊通常都有一個客戶端。客戶端是不穩定的並且遵循選項卡的生命週期。擁有唯一的 clientID。

客戶端群組是一組共享本機資料的客戶端。即使離線時,該客戶端群組內的客戶端也會共用狀態。

Client Group 使用磁碟上的持久緩存,該緩存透過 Replicache 建構函數的 name 參數進行區分。屬於具有相同名稱的客戶端群組的所有客戶端共享相同的快取。

客戶視角

客戶端在持久化快取中有一個鍵值對的有序映射,稱為客戶端視圖。客戶端視圖是應用程式數據,與伺服器數據同步。之所以稱為客戶端視圖,是因為不同的客戶端可能在不同的客戶端視圖中擁有伺服器資料。這意味著每個客戶端看到的伺服器狀態都不同。

存取客戶端視圖非常快速。讀取延遲小於 1 毫秒,大多數裝置的吞吐量為 500MB/s。

建議您直接從 Client View 讀取並使用它,而不是使用 useState 從 React 等地方單獨複製 Client View 並將其上傳到記憶體。當 mutator 更改 Client View 時,會觸發訂閱,從而更新 UI

訂閱

Subscribe 函數接收 ReadTransaction 參數並實作從 Replicache 讀取。每當此訂閱因副本資料變更而過期時,就會再次執行訂閱功能。如果此結果發生變化,則值會更新,UI 也會更新。

如果您透過訂閱配置 UI,則可以始終保持最新狀態。

import {Replicache} from "replicache";

const rep = new Replicache({
  name: userID,
  ...
});

console.log(rep.clientID);

突變

Mutation 是指改變 Replicache 資料的任務。接收突變並實際更改資料的主體稱為突變者。

啟動時,Replicache 中會註冊幾個 Mutators,但它們實際上只是命名函數。下面的createTodo和markTodoComplete都是透過WriteTransaction改變Replicache資料的變異器。

const todos = useSubscribe(rep, async tx => {
  return await tx.scan({prefix: 'todo/'}).toArray();
});
return (
  
    {todos.map(todo => (
  • {todo.text}
  • ))}
);

Mutator 的工作原理如下。當mutator運行時,資料發生變化,與之相關的訂閱被觸發,UI也發生變化。

const rep = new Replicache({
  ...
  mutators: {
    createTodo,
    markTodoComplete,
  },
});

async function createTodo(tx: WriteTransaction, todo: Todo) {
  await tx.set(`/todo/${todo.id}`, todo);
}

async function markTodoComplete(tx: WriteTransaction,
    {id, complete}: {id: string, complete: boolean}) {
  const key = `/todo/${id}`;
  const todo = await tx.get(key);
  if (!todo) {
    return;
  }
  todo.complete = complete;
  await tx.set(key, todo);
}

在內部,Mutator 創造了一種稱為突變的東西。它就像一個執行記錄,但 Replicache 創建了以下突變。

await rep.mutate.createTodo({id: nanoid(), text: "take out the trash"});

這些突變被標記為待處理,直到它們被推送到伺服器並完全同步。

同步詳情

現在,這裡詳細介紹Sync,它可以說是Replicache的核心。同步已在伺服器上完成。

副本同步模型

(從現在開始,「狀態」一詞是指由多個鍵值對組成的資料(鍵值空間)的狀態。)

Replicache 試圖解決的同步問題是在多個客戶端同時更改相同狀態並且存在以下情況時發生的。

  1. 伺服器的狀態是事實的來源。它被表示為規範。
  2. 客戶端本地狀態的變化會立即反映出來。這就是所謂的投機。
  3. 伺服器必須僅套用一次更改,且結果必須是可預測的。應用於伺服器的變更必須能夠合理地與客戶端上的本機變更合併。

其中的最後一項是將伺服器更改與本地狀態“合理合併”,這是一個有趣的主題。為了‘合理合併’,必須考慮以下情況。

  • 如果本地變更尚未套用到伺服器。在這種情況下,即使從伺服器檢索到新狀態,您也需要確保本機變更不會從應用程式的 UI 中消失。從伺服器接收到新狀態後,任何現有的本機變更都必須在伺服器狀態之上重新執行。

  • 當客戶端上所做的本機變更已傳送至伺服器並反映在伺服器狀態中。在這種情況下,請注意不要兩次應用本地更改。不應重新套用本地變更

  • 如果有其他客戶端已將伺服器狀態變更為相同狀態。在這種情況下,與第一種情況一樣,必須根據從伺服器接收的狀態重做本機變更。但是,由於相同資源可能會發生衝突,因此必須仔細規劃合併邏輯。將此邏輯寫入 Mutator 中。

我們來看看Mutator的操作流程。

本地執行

變異器在本地運行,副本的值根據變異器邏輯變化。同時,該客戶端建立一個mutation,其mutationId依序增加。突變會作為待處理的突變進行排隊

待處理的突變被傳送到伺服器上實作的推播端點(replicache-push)。

變異透過執行伺服器上實現的變異器來改變規範狀態。在應用突變時,該客戶端的最後一個突變 ID 會被更新,並成為一個值,讓您知道當該客戶端進行下一次拉取時要重新應用哪個突變

本地應用的待定突變會產生推測結果,而應用於伺服器的突變會產生規範結果。應用於伺服器的變異已被確認,不會再次在本地執行。即使相同的突變會傳回不同的結果,伺服器的規範結果也會優先,因此客戶端的結果會改變

Replicache 定期向拉取端點 (replicache-pull) 發送請求,以檢索最新狀態並更新 UI。

拉取要求包含cookie和clientGroupId,並傳回新的cookie、修補程式和lastMutationIDChanges。

Cookie用來區分客戶端持有的伺服器狀態。任何可以追蹤伺服器和客戶端狀態差異程度的值就足夠了。您可以將其視為一個全域“版本”,只要資料庫狀態發生變化,該版本就會發生變化。或者,您可以使用 cookie 策略來追蹤更具體的資料範圍。

lastMutationIdChanges 是一個值,表示伺服器最後為每個客戶端套用的突變 ID。 mutationID 小於該值的所有突變不應再被視為待處理而是已確認。

變基

當客戶端收到拉取時,補丁必須套用於本機狀態。然而,由於待處理的突變會影響目前的本地狀態,因此補丁不能直接應用於本地狀態。相反,恢復本地掛起的突變,首先應用作為拉取接收的補丁,然後再次應用本地掛起的突變。

為了實現這種撤銷和重新應用,Replicache 的設計與 Git 類似。您可以將伺服器的狀態視為主分支,將由本機掛起的突變變更的狀態視為開發分支,接收從伺服器到主分支的拉取,並將開發變基到主分支。

rebase過程中可能出現的衝突將在下面單獨討論。

Poke,如上所述,是伺服器告訴客戶端拉取的提示訊息。

衝突解決

在 Replicache 這樣的分散式系統中,合併衝突是不可避免的。拉推過程中需要合併。合併的方式應該使合併結果可預測並符合應用程式的目的。

如果是會議室預訂應用,發生衝突時只能批准一個請求。因此,你必須採用合併方式,只批准先預約的客戶。

另一方面,如果它是一個Todo應用程序,Todo列表的目的是即使添加同時發生,兩個更改也會被批准。

以下兩種情況會發生合併衝突。

  1. 本地變更何時應用到伺服器。這是因為本地應用時的狀態和伺服器上應用時的狀態可能不同。

  2. 變基時。這是因為申請時的狀態可能會有所不同。

Replicache 認識到合併方法必須根據應用程式的目的以不同的方式實現,因此它允許開發人員實現它。開發者可以透過 Mutator 來實現這個邏輯。

以上是複製品大圖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

node.js流帶打字稿node.js流帶打字稿Apr 30, 2025 am 08:22 AM

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python vs. JavaScript:性能和效率注意事項Python vs. JavaScript:性能和效率注意事項Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

幕後:什麼語言能力JavaScript?幕後:什麼語言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來:趨勢和預測Python和JavaScript的未來:趨勢和預測Apr 27, 2025 am 12:21 AM

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器