HTTP Cache
 
Overview
 
The HTTP Cache is the module that receives HTTP(S) requests and decides when and how to fetch data from the Disk Cache or from the network. The cache lives in the browser process, as part of the network stack. It should not be confused with Blink's in-memory cache, which lives in the renderer process and it's tightly coupled with the resource loader.
 
Logically the cache sits between the content-encoding logic and the transfer-encoding logic, which means that it deals with transfer-encoding properties and stores resources with the content-encoding set by the server.
 
The cache implements the HttpTransactionFactory interface, so an HttpCache::Transaction (which is an implementation of HttpTransaction) will be the transaction associated with the URLRequestJob used to fetch most URLRequests.
 
There's an instance of an HttpCache for every profile (and for every isolated app). In fact, a profile may contain two instances of the cache: one for regular requests and another one for media requests.
 
Note that because the HttpCache is the one in charge of serving requests either from disk or from the network, it actually owns the HttpTransactionFactory that creates network transactions, and the disk_cache::Backend that is used to serve requests from disk. When the HttpCache is destroyed (usually when the profile data goes away), both the disk backend and the network layer (HttpTransactionFactory) go away.
 
There may be code outside of the cache that keeps a copy of the pointer to the disk cache backend. In that case, it is a requirement that the real ownership is maintained at all times, which means that such code has to be owned transitively by the cache (so that backend destruction happen synchronously with the destruction of the code that kept the pointer).
 

Operation

 
The cache is responsible for:
 
  • Create and manage the disk cache backend.
 

This is mostly an initialization problem. The cache is created without a backend (but with a backend factory), and the backend is created on-demand by the first request that needs one. The HttpCache has all the logic to queue requests until the backend is created.

 
  • Create HttpCache::Transactions.
 
  • Create and manage ActiveEntries that are used by HttpCache::Transactions to interact with the disk backend.
 
An ActiveEntry is a small object that represents a disk cache entry and all the transactions that have access to it. The Writer, the list of Readers and the list of pending transactions (waiting to become Writer or Readers) are part of the ActiveEntry.
 
The cache has the code to create or open disk cache entries and place them on an ActiveEntry. It also has all the logic to attach and remove a transaction to and from ActiveEntry.
 
  • Enforce the cache lock.
 
The cache implements a single writer - multiple reader lock so that only one network request for the same resource is in flight at any given time.
 
Note that the existence of the cache lock means that no bandwidth is wasted re-fetching the same resource simultaneously. On the other hand, it forces requests to wait until a previous request finishes downloading a resource (the Writer) before they can start reading from it, which is particularly troublesome for long lived requests. Simply bypassing the cache for subsequent requests is not a viable solution as it will introduce consistency problems when a renderer experiences the effect of going back in time, as in receiving a version of the resource that is older than a version that it already received (but which skipped the browser cache).
 

The bulk of the logic of the HTTP cache is actually implemented by the cache transaction.

 

Sparse Entries

 
The HTTP Cache supports using spares entries for any resource. Sparse entries are generally used by media resources (think large video or audio files), and the general idea is to be able to store only some parts of the resource, and being able to serve those parts back from disk.
 
The mechanism that is used to tell the cache that it should create a sparse entry instead of a regular entry is by issuing a byte-range request from the caller. That tells the cache that the caller is prepared to deal with byte ranges, so the cache may store byte ranges. Note that if the cache already has a resource stored for the requested URL, issuing a byte range request will not "upgrade" that resource to be a sparse entry; in fact, in general there is no way to transform a regular entry into a sparse entry or vice-versa.
 
Once the HttpCache creates a sparse entry, the disk cache backend will be in charge of storing the byte ranges in an efficient way, and it will be able to evict part of a resource without throwing the whole entry away. For example, when watching a long video, the backend can discard the first part of the movie while still storing the part that is currently being received (and presented to the user). If the user goes back a few minutes, content can be served from the cache. If the user seeks to a portion that was already evicted, that part the video can be fetched again.
 
At any given time, it is possible for the cache to have stored a set of sections of a resource (which don't necessarily match any actual byte-range requested by the user) interspersed with missing data. In order to fulfill a given request, the HttpCache may have to issue a series of byte-range network requests for the missing parts, while returning data as needed either from disk or from the network. In other words, when dealing with sparse entries, the HttpCache::Transaction will synthesize network byte-range requests as needed.
 

Truncated Entries

 
A second scenario where the cache will generate byte-range request is when a regular entry (not sparse) was not completely received before the connection was lost (or the caller cancelled the request). In that case, the cache will attempt to serve the first part of the resource from disk, and issue a byte range request for the remainder of the resource. A large part of the logic to handle truncated entries is the same logic needed to support spares entries.
 

Byte-Range Requests

 
As explained above, byte-range requests are used to trigger the creation of sparse entries (if the resource was not previously stored). From the user point of view, the cache will transparently fulfill any combination of byte-range requests and regular requests either from sparse, truncated or normal entries. Needless to say, if a client uses byte-range requests it should be prepared to deal with the implications of that request, as having to determine when requests can be combined together, what a range applies to (over the wire bytes) etc.
 

HttpCache::Transaction

 
The bulk of the cache logic is implemented by the cache transaction. At the center of the implementation there is a very large state machine (probably the most common pattern in the network stack, given the asynchronous nature of the problem). Note that there's a block of comments that document the most common flow patterns for the state machine, just before the main switch implementation.
 
This is a general (not exhaustive) diagram of the state machine:
 
 
This diagram is not meant to track the latest version of the code, but rather to provide a rough overview of what the state machine transitions look like. The flow is relatively straight forward for regular entries, but the fact that the cache can generate a number of network requests to fulfill a single request that involves sparse entries make it so that there is a big loop going back to START_PARTIAL_CACHE_VALIDATION. Remember that each individual network request can fail, or the server may have a more recent version of the resource... although in general, that kind of server behavior while we are working with a request will result in an error condition.

Network Stack‎ : HTTP Cache的更多相关文章

  1. Network Stack‎ : Disk Cache

    Disk Cache 目录 1 Overview 2 External Interface 3 Disk Structure 3.1 Cache Address 3.2 Index File Stru ...

  2. Network Stack

    Network Stack 目录 1 Overview 2 Code Layout 3 Anatomy of a Network Request (focused on HTTP) 3.1 URLRe ...

  3. Queueing in the Linux Network Stack !!!!!!!!!!!!!!!

    https://www.coverfire.com/articles/queueing-in-the-linux-network-stack/ Queueing in the Linux Networ ...

  4. Contiki Network Stack

    一.协议栈 主要有两大网络协议栈,uIP和Rime这两大协议栈(network stack): The uIP TCP/IP stack, which provides us with IPv4 ne ...

  5. Network Stack‎ : HTTP authentication

    HTTP authentication As specified in RFC 2617, HTTP supports authentication using the WWW-Authenticat ...

  6. 谷歌开发者工具 Network:Disable cache 和 Preserve log

    参考博文地址:https://my.oschina.net/af666/blog/871793 Network Disable cache(禁止缓存):勾上,修改代码之后,刷新页面没有更新,看有没有禁 ...

  7. Network Stack‎ : CookieMonster

    CookieMonster   The CookieMonster is the class in Chromium which handles in-browser storage, managem ...

  8. XV6学习(16)Lab net: Network stack

    最后一个实验了,代码在Github上. 这一个实验其实挺简单的,就是要实现网卡的e1000_transmit和e1000_recv函数.不过看以前的实验好像还要实现上层socket相关的代码,今年就只 ...

  9. Monitoring and Tuning the Linux Networking Stack: Receiving Data

    http://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/ ...

随机推荐

  1. MySQL锁定状态查看命令

    1 show processlist; SHOW PROCESSLIST显示哪些线程正在运行.您也可以使用mysqladmin processlist语句得到此信息.如果您有SUPER权限,您可以看到 ...

  2. EEPlat PaaS中的多租户数据隔离模式

    EEPlat PaaS支持三种租户的数据隔离技术:Sparce Column.tenantId字段隔离.每一个租户独立数据库. 1)Sparce Column,和Salesforce Appforce ...

  3. leetCode(38):Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  4. linux 下同步异步,堵塞非堵塞的一些想法

    补充: 发现一个更好的解释样例:同步是一件事我们从头到尾尾随着完毕.异步是别人完毕我们仅仅看结果. 堵塞是完毕一件事的过程中可能会遇到一些情况让我们等待(挂起).非堵塞就是发生这些情况时我们跨过. 比 ...

  5. 安卓开发--HttpDemo02

    package com.cnn.httpdemo02; import android.app.Activity; import android.os.Bundle; import android.vi ...

  6. No mapping found for HTTP request with URI [/test2/test/add.json] in DispatcherServlet with name 'dispatcher'

    查看spring-mvc.xml中扫描包路径配置是否正确: <!-- 扫描controller(controller层注入) --> <context:component-scan ...

  7. javascript 优秀写法

    http://www.csdn.net/article/2014-01-06/2818025-Useful-JavaScript-Tips-Best-Practices

  8. CSS3动画闪跳

    Alloy Team首页的元素Hover效果 效果预览 <!DOCTYPE html> <html lang="en"> <head> < ...

  9. ES6中的let、contst

    一 let 1.let 局部变量 不会变量提升,在运用时候要先声明在调用,var 全局变量 会产生变量提升: 2.在块级作用域中纯在let const,他所生命的变量就绑定在这个区域,未经过声明调用会 ...

  10. PKU 3281 Dining 网络流 (抄模板)

    题意: 农夫约翰为他的牛准备了F种食物和D种饮料.每头牛都有各自喜欢的食物和饮料,而每种食物或饮料只能分配给一头牛.最多能有多少头牛可以同时得到各自喜欢的食物和饮料? 思路: 用 s -> 食物 ...