HTTP Cache(轉譯)

總覽
 
HTTP緩存是接收HTTP(S)請求並確定何時以及如何從磁盤緩存或從網絡中獲取數據的模塊。 緩存位於瀏覽器進程中,作爲網絡堆棧的一部分。 它不應與Blink的內存中緩存混淆,後者位於渲染器進程中,並且與資源加載器緊密耦合。
 
從邏輯上講,緩存位於內容編碼邏輯和傳輸編碼邏輯之間,這意味着緩存處理傳輸編碼屬性,並使用服務器設置的內容編碼來存儲資源。
 
緩存實現了HttpTransactionFactory接口,因此HttpCache :: Transaction(這是HttpTransaction的實現)將是與URLRequestJob關聯的事務,用於獲取大多數URLRequests。
 
每個配置文件(以及每個隔離的應用程序)都有一個HttpCache實例。 實際上,配置文件可能包含兩個緩存實例:一個實例用於常規請求,另一個實例用於媒體請求。
 
請注意,由於HttpCache是負責處理來自磁盤或來自網絡的請求,因此它實際上擁有創建網絡事務的HttpTransactionFactory和用於處理來自磁盤的請求的disk_cache :: Backend。 當HttpCache被銷燬時(通常在配置文件數據消失時),磁盤後端和網絡層(HttpTransactionFactory)都消失了。
 
緩存之外可能存在一些代碼,這些代碼保留指向磁盤緩存後端的指針的副本。 在這種情況下,要求始終保持真實所有權,這意味着此類代碼必須由緩存以過渡方式擁有(以便後端銷燬與保存指針的代碼同步發生)。
 

運作方式

 
緩存負責:
 
  • 創建和管理磁盤緩存後端。
 
這主要是初始化問題。 創建的緩存不包含後端(但具有後端工廠),並且後端是根據需要一個請求的第一個請求按需創建的。 HttpCache具有將請求排隊的所有邏輯,直到創建後端爲止。
 
  • 創建 HttpCache::Transactions.
  • 創建和管理由HttpCache :: Transactions與磁盤後端進行交互的ActiveEntries。
 
ActiveEntry是一個小對象,代表磁盤緩存項和有權訪問它的所有事務。 Writer,Reader列表和未決事務列表(等待成爲Writer或Reader)是ActiveEntry的一部分。
 
緩存具有用於創建或打開磁盤緩存項並將其放置在ActiveEntry上的代碼。 它還具有在ActiveEntry上附加事務或從ActiveEntry除去事務的所有邏輯。
 
  • 強制執行緩存鎖定。
 
緩存實現了一個寫入器-多個讀取器鎖,因此在任何給定時間只有一個網絡請求同一資源。
 
請注意,緩存鎖的存在意味着不會浪費帶寬,同時重新獲取同一資源。 另一方面,它迫使請求等待一個先前的請求完成下載資源(Writer)之後才能開始從中讀取資源,這對於長期存在的請求特別麻煩。 簡單地繞過緩存以處理後續請求不是一個可行的解決方案,因爲當渲染器遇到時光倒流的影響時,它將引入一致性問題,例如,在接收到的資源版本早於已接收的版本時(但是 跳過了瀏覽器緩存)。
 

HTTP緩存的大部分邏輯實際上是由緩存事務實現的。

 

稀疏條目

 
HTTP緩存支持對任何資源使用備用條目。 稀疏條目通常由媒體資源(例如大的視頻或音頻文件)使用,並且一般的想法是隻能存儲資源的某些部分,並能夠將這些部分從磁盤中送回。
 
通過從調用方發出字節範圍請求來告知緩存應創建稀疏條目而不是常規條目的機制。 這告訴緩存,調用者已準備好處理字節範圍,因此緩存可以存儲字節範圍。 請注意,如果緩存中已經存儲了用於請求的URL的資源,則發出字節範圍請求不會將該資源“升級”爲稀疏條目; 實際上,通常沒有辦法將常規條目轉換爲稀疏條目,反之亦然。
 
一旦HttpCache創建了一個稀疏條目,磁盤緩存後端將負責以一種有效的方式存儲字節範圍,並且它將能夠逐出資源的一部分而不會丟棄整個條目。 例如,當觀看長視頻時,後端可以丟棄電影的第一部分,同時仍存儲當前正在接收(並呈現給用戶)的部分。 如果用戶返回幾分鐘,則可以從緩存中提供內容。 如果用戶尋找已被逐出的部分,則可以再次獲取視頻。
 
在任何給定的時間,緩存都有可能存儲了一組資源部分(不一定與用戶請求的任何實際字節範圍相匹配),並散佈了丟失的數據。 爲了滿足給定的請求,HttpCache可能必須針對丟失的部分發出一系列字節範圍的網絡請求,同時根據需要從磁盤或從網絡返回數據。 換句話說,當處理稀疏條目時,HttpCache :: Transaction將根據需要合成網絡字節範圍請求。

截斷的條目

高速緩存將生成字節範圍請求的第二種情況是,在丟失連接之前(或調用者取消了請求之前)沒有完全接收到常規條目(非稀疏)。 在這種情況下,緩存將嘗試從磁盤上服務資源的第一部分,並對資源的其餘部分發出字節範圍請求。 處理截斷條目的大部分邏輯與支持備用條目所需的邏輯相同。
 

字節範圍請求

 
如上所述,字節範圍請求用於觸發稀疏條目的創建(如果先前未存儲資源)。 從用戶的角度來看,緩存將透明地滿足來自稀疏,截斷或普通條目的字節範圍請求和常規請求的任何組合。 毋庸置疑,如果客戶端使用字節範圍請求,則應準備處理該請求的含義,因爲必須確定何時可以將請求組合在一起,範圍適用於什麼。
 

HttpCache::Transaction

 
大部分緩存邏輯由緩存事務實現。 在實現的中心有一個非常大的狀態機(考慮到問題的異步性質,這可能是網絡堆棧中最常見的模式)。 請注意,在主開關實現之前,有大量註釋記錄了狀態機最常見的流模式。
 
這是狀態機的一般圖(並非詳盡無遺):
 
 
該圖並不意味着跟蹤代碼的最新版本,而是提供狀態機轉換的大致概貌。 對於常規條目而言,該流程相對簡單,但是高速緩存可以生成許多網絡請求來滿足涉及稀疏條目的單個請求,這一事實使得它可以追溯到START_PARTIAL_CACHE_VALIDATION。 請記住,每個單獨的網絡請求都可能失敗,或者服務器可能具有資源的較新版本...儘管通常,當我們處理請求時,這種服務器行爲將導致錯誤情況。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章