1.HTTP Cache概要
HTTP Cache是接收HTTP(S)請(qǐng)求并決定何時(shí)以及如何從磁盤(pán)高速緩存或從網(wǎng)絡(luò)獲取數(shù)據(jù)的模塊。緩存作為網(wǎng)絡(luò)堆棧的一部分存在于瀏覽器進(jìn)程中。它不應(yīng)該與Blink的內(nèi)存緩存混淆,后者位于渲染器進(jìn)程中,并且與資源加載器緊密耦合。
邏輯上,緩存位于內(nèi)容編碼邏輯和傳輸編碼邏輯之間,這意味著它處理傳輸編碼屬性并使用服務(wù)器設(shè)置的內(nèi)容編碼存儲(chǔ)資源。
緩存實(shí)現(xiàn)了HttpTransactionFactory接口,因此HttpCache :: Transaction(它是HttpTransaction的實(shí)現(xiàn))將是與用于獲取大多數(shù)URLRequests的URLRequestJob相關(guān)聯(lián)的事務(wù)。
每個(gè)配置文件(以及每個(gè)隔離的應(yīng)用程序)都有一個(gè)HttpCache實(shí)例。實(shí)際上,配置文件可能包含兩個(gè)緩存實(shí)例:一個(gè)用于常規(guī)請(qǐng)求,另一個(gè)用于媒體請(qǐng)求。
請(qǐng)注意,因?yàn)镠ttpCache是負(fù)責(zé)從磁盤(pán)或網(wǎng)絡(luò)提供請(qǐng)求的人,它實(shí)際上擁有創(chuàng)建網(wǎng)絡(luò)事務(wù)的HttpTransactionFactory,以及用于從磁盤(pán)提供請(qǐng)求的disk_cache :: Backend。當(dāng)HttpCache被銷毀時(shí)(通常在配置文件數(shù)據(jù)消失時(shí)),磁盤(pán)后端和網(wǎng)絡(luò)層(HttpTransactionFactory)都會(huì)消失。
緩存外部可能有代碼,用于保存指向磁盤(pán)緩存后端的指針的副本。在這種情況下,要求始終保持真正的所有權(quán),這意味著這些代碼必須由高速緩存?zhèn)鬟f地?fù)碛校ㄒ员愫蠖似茐呐c保留指針的代碼的銷毀同步發(fā)生)。
2.HTTP Cache操作
HTTP Cache負(fù)責(zé):
- 創(chuàng)建和管理磁盤(pán)緩存后端。
這主要是初始化問(wèn)題。創(chuàng)建緩存時(shí)沒(méi)有后端(但具有后端工廠),后端由第一個(gè)需要后端的請(qǐng)求按需創(chuàng)建。 HttpCache具有將請(qǐng)求排隊(duì)的所有邏輯,直到創(chuàng)建后端。
- 創(chuàng)建HttpCache :: Transactions。
- 建和管理HttpCache :: Transactions用于與磁盤(pán)后端交互的ActiveEntries。
- ActiveEntry是一個(gè)小對(duì)象,表示磁盤(pán)高速緩存條目以及有權(quán)訪問(wèn)它的所有事務(wù)。 Writer,讀者列表和待處理事務(wù)列表(等待成為Writer或讀者)是ActiveEntry的一部分。
緩存具有用于創(chuàng)建或打開(kāi)磁盤(pán)緩存條目的代碼,并將它們放在ActiveEntry上。它還具有連接和從ActiveEntry中刪除事務(wù)的所有邏輯。
- 強(qiáng)制執(zhí)行緩存鎖定。
緩存實(shí)現(xiàn)單個(gè)寫(xiě)入器 - 多個(gè)讀取器鎖定,以便在任何給定時(shí)間只有一個(gè)網(wǎng)絡(luò)請(qǐng)求同一資源在飛行中。
請(qǐng)注意,緩存鎖定的存在意味著沒(méi)有浪費(fèi)帶寬同時(shí)重新獲取相同的資源。另一方面,它強(qiáng)制請(qǐng)求等待,直到先前的請(qǐng)求完成下載資源(Writer)才能開(kāi)始讀取它,這對(duì)于長(zhǎng)期存在的請(qǐng)求尤其麻煩。簡(jiǎn)單地繞過(guò)緩存以用于后續(xù)請(qǐng)求不是一個(gè)可行的解決方案,因?yàn)楫?dāng)渲染器經(jīng)歷回溯的影響時(shí)會(huì)引入一致性問(wèn)題,如接收比其已經(jīng)接收的版本更舊的資源版本(但是它跳過(guò)瀏覽器緩存)。
HTTP緩存的大部分邏輯實(shí)際上是由緩存事務(wù)實(shí)現(xiàn)的。
3.Sparse Entries
HTTP緩存支持對(duì)任何資源使用備用條目。稀疏條目通常由媒體資源使用(想想大型視頻或音頻文件),一般的想法是只能存儲(chǔ)資源的某些部分,并能夠從磁盤(pán)返回這些部分。
用于告訴緩存它應(yīng)該創(chuàng)建稀疏條目而不是常規(guī)條目的機(jī)制是通過(guò)從調(diào)用者發(fā)出字節(jié)范圍請(qǐng)求。這告訴緩存調(diào)用者準(zhǔn)備處理字節(jié)范圍,因此緩存可以存儲(chǔ)字節(jié)范圍。請(qǐng)注意,如果緩存已經(jīng)為請(qǐng)求的URL存儲(chǔ)了資源,則發(fā)出字節(jié)范圍請(qǐng)求將不會(huì)將該資源“升級(jí)”為稀疏條目;實(shí)際上,通常無(wú)法將常規(guī)條目轉(zhuǎn)換為稀疏條目,反之亦然。
一旦HttpCache創(chuàng)建了稀疏條目,磁盤(pán)緩存后端將負(fù)責(zé)以有效的方式存儲(chǔ)字節(jié)范圍,并且它將能夠驅(qū)逐部分資源而不會(huì)丟棄整個(gè)條目。例如,當(dāng)觀看長(zhǎng)視頻時(shí),后端可以丟棄電影的第一部分,同時(shí)仍然存儲(chǔ)當(dāng)前正被接收的部分(并呈現(xiàn)給用戶)。如果用戶返回幾分鐘,則可以從緩存中提供內(nèi)容。如果用戶尋找已經(jīng)被驅(qū)逐的部分,那么該部分可以再次獲取視頻。
在任何給定時(shí)間,高速緩存都可能存儲(chǔ)了資源的一組部分(其不一定匹配用戶請(qǐng)求的任何實(shí)際字節(jié)范圍),其中散布有丟失的數(shù)據(jù)。為了滿足給定的請(qǐng)求,HttpCache可能必須為丟失的部分發(fā)出一系列字節(jié)范圍的網(wǎng)絡(luò)請(qǐng)求,同時(shí)根據(jù)需要從磁盤(pán)或網(wǎng)絡(luò)返回?cái)?shù)據(jù)。換句話說(shuō),當(dāng)處理稀疏條目時(shí),HttpCache :: Transaction將根據(jù)需要合成網(wǎng)絡(luò)字節(jié)范圍請(qǐng)求。
4.Truncated Entries
緩存將生成字節(jié)范圍請(qǐng)求的第二種情況是在連接丟失之前未完全接收到常規(guī)條目(非稀疏)(或者調(diào)用者取消了請(qǐng)求)。在這種情況下,緩存將嘗試從磁盤(pán)提供資源的第一部分,并為資源的其余部分發(fā)出字節(jié)范圍請(qǐng)求。處理截?cái)鄺l目的大部分邏輯與支持備用條目所需的邏輯相同。
5.Byte-Range Requests
如上所述,字節(jié)范圍請(qǐng)求用于觸發(fā)稀疏條目的創(chuàng)建(如果先前未存儲(chǔ)資源)。從用戶的角度來(lái)看,緩存將透明地實(shí)現(xiàn)字節(jié)范圍請(qǐng)求和來(lái)自稀疏,截?cái)嗷蛘l目的常規(guī)請(qǐng)求的任何組合。毋庸置疑,如果客戶端使用字節(jié)范圍請(qǐng)求,則應(yīng)準(zhǔn)備好處理該請(qǐng)求的含義,因?yàn)楸仨毚_定何時(shí)可以將請(qǐng)求組合在一起,范圍適用于什么(通過(guò)線路字節(jié))等。
6.HttpCache::Transaction
大部分緩存邏輯由緩存事務(wù)實(shí)現(xiàn)。在實(shí)現(xiàn)的中心,有一個(gè)非常大的狀態(tài)機(jī)(可能是網(wǎng)絡(luò)堆棧中最常見(jiàn)的模式,考慮到問(wèn)題的異步性質(zhì))。請(qǐng)注意,在主交換機(jī)實(shí)現(xiàn)之前,有一個(gè)注釋塊記錄了狀態(tài)機(jī)的最常見(jiàn)流模式。
這是狀態(tài)機(jī)的一般(非詳盡)圖表:
此圖不是為了跟蹤代碼的最新版本,而是提供狀態(tài)機(jī)轉(zhuǎn)換的大致概述。對(duì)于常規(guī)條目,流程相對(duì)簡(jiǎn)單,但是緩存可以生成大量網(wǎng)絡(luò)請(qǐng)求來(lái)完成涉及稀疏條目的單個(gè)請(qǐng)求,這樣就可以回到START_PARTIAL_CACHE_VALIDATION。請(qǐng)記住,每個(gè)單獨(dú)的網(wǎng)絡(luò)請(qǐng)求都可能失敗,或者服務(wù)器可能具有更新版本的資源...盡管通常在我們處理請(qǐng)求時(shí)這種服務(wù)器行為將導(dǎo)致錯(cuò)誤情況。
|