Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1939)

Unified Diff: net/http/http_cache_transaction.cc

Issue 793823002: Let prefetched resources skip cache revalidation once for a short duration. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments from PS2 Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/http/http_cache_transaction.cc
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 7139abbdd79db0645bc37137d486365ad8fbbea8..955848c15b0954bddc28e724099790ac6c115611 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -27,6 +27,7 @@
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/time/clock.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/base/completion_callback.h"
@@ -951,6 +952,12 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_CACHE_READ_RESPONSE_COMPLETE:
rv = DoCacheReadResponseComplete(rv);
break;
+ case STATE_TOGGLE_UNUSED_SINCE_PREFETCH:
+ rv = DoCacheToggleUnusedSincePrefetch();
rvargas (doing something else) 2014/12/24 02:15:24 DCHECK rv == ok?
jkarlin 2015/01/08 16:13:03 Done.
+ break;
+ case STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE:
rvargas (doing something else) 2014/12/24 02:15:24 These states have to be incorporated on the commen
jkarlin 2015/01/08 16:13:03 Done.
+ rv = DoCacheToggleUnusedSincePrefetchComplete(rv);
+ break;
case STATE_CACHE_WRITE_RESPONSE:
DCHECK_EQ(OK, rv);
rv = DoCacheWriteResponse();
@@ -1534,6 +1541,7 @@ int HttpCache::Transaction::DoUpdateCachedResponse() {
response_.response_time = new_response_->response_time;
response_.request_time = new_response_->request_time;
response_.network_accessed = new_response_->network_accessed;
+ response_.unused_since_prefetch = new_response_->unused_since_prefetch;
if (response_.headers->HasHeaderValue("cache-control", "no-store")) {
if (!entry_->doomed) {
@@ -1567,6 +1575,7 @@ int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) {
cache_->ConvertWriterToReader(entry_);
mode_ = READ;
}
+
// We no longer need the network transaction, so destroy it.
final_upload_progress_ = network_trans_->GetUploadProgress();
ResetNetworkTransaction();
@@ -1707,6 +1716,40 @@ int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
if (response_.headers->GetContentLength() == current_size)
truncated_ = false;
+ if (response_.unused_since_prefetch ||
+ (!response_.unused_since_prefetch &&
rvargas (doing something else) 2014/12/24 02:15:24 !response_.unused_since_prefetch seems unnecessary
jkarlin 2015/01/08 16:13:03 Thanks!
+ request_->load_flags & LOAD_PREFETCH)) {
+ // Either this is the first use of an entry since it was prefetched or
+ // this is a prefetch. The value of response.unused_since_prefetch is valid
+ // for this transaction but the bit needs to be flipped in storage.
+ next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH;
rvargas (doing something else) 2014/12/24 02:15:24 looks like this is not really toggle, as two conse
jkarlin 2015/01/08 16:13:04 Nice catch on two consecutive prefetches. Fixed an
+ return OK;
+ }
+
+ return DoCacheReadResponseCompleteContinuation();
rvargas (doing something else) 2014/12/24 02:15:24 This begs to be a dedicated state on the machine.
jkarlin 2015/01/08 16:13:03 Done.
+}
+
+int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch() {
+ // Write back the toggled value for the next use of this entry.
+ response_.unused_since_prefetch = !response_.unused_since_prefetch;
+
+ // TODO(jkarlin): If DoUpdateCachedResponse is also called for this
+ // transaction then metadata will be written to cache twice. If prefetching
+ // becomes more common, consider combining the writes.
+ target_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE;
+ next_state_ = STATE_CACHE_WRITE_RESPONSE;
+ return OK;
+}
+
+int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetchComplete(
+ int result) {
+ // Restore the original value for this transaction.
+ response_.unused_since_prefetch = !response_.unused_since_prefetch;
+
+ return DoCacheReadResponseCompleteContinuation();
+}
+
+int HttpCache::Transaction::DoCacheReadResponseCompleteContinuation() {
// We now have access to the cache entry.
//
// o if we are a reader for the transaction, then we can start reading the
@@ -1720,6 +1763,7 @@ int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
// conditionalized request (if-modified-since / if-none-match). We check
// if the request headers define a validation request.
//
+ int result = ERR_FAILED;
switch (mode_) {
case READ:
UpdateTransactionPattern(PATTERN_ENTRY_USED);
@@ -2172,6 +2216,7 @@ int HttpCache::Transaction::BeginCacheValidation() {
// TODO(ricea): Is this pattern okay for asynchronous revalidations?
UpdateTransactionPattern(PATTERN_ENTRY_USED);
RecordOfflineStatus(effective_load_flags_, OFFLINE_STATUS_FRESH_CACHE);
+
rvargas (doing something else) 2014/12/24 02:15:24 ?
jkarlin 2015/01/08 16:13:03 Done.
return SetupEntryForRead();
} else {
// Make the network request conditional, to see if we may reuse our cached
@@ -2344,6 +2389,15 @@ ValidationType HttpCache::Transaction::RequiresValidation() {
if (effective_load_flags_ & LOAD_PREFERRING_CACHE)
return VALIDATION_NONE;
+ if (response_.unused_since_prefetch &&
+ response_.headers->GetCurrentAge(
+ response_.request_time, response_.response_time,
+ cache_->clock_->Now()) < TimeDelta::FromMinutes(kPrefetchReuseMins)) {
+ // The first use of a resource after prefetch within a short window skips
+ // validation.
+ return VALIDATION_NONE;
+ }
+
if (effective_load_flags_ & (LOAD_VALIDATE_CACHE | LOAD_ASYNC_REVALIDATION))
return VALIDATION_SYNCHRONOUS;
@@ -2351,8 +2405,9 @@ ValidationType HttpCache::Transaction::RequiresValidation() {
return VALIDATION_SYNCHRONOUS;
ValidationType validation_required_by_headers =
- response_.headers->RequiresValidation(
- response_.request_time, response_.response_time, Time::Now());
+ response_.headers->RequiresValidation(response_.request_time,
+ response_.response_time,
+ cache_->clock_->Now());
if (validation_required_by_headers == VALIDATION_ASYNCHRONOUS) {
// Asynchronous revalidation is only supported for GET and HEAD methods.
@@ -2413,7 +2468,8 @@ bool HttpCache::Transaction::ConditionalizeRequest() {
response_.headers->GetFreshnessLifetimes(response_.response_time);
if (lifetimes.staleness > TimeDelta()) {
TimeDelta current_age = response_.headers->GetCurrentAge(
- response_.request_time, response_.response_time, Time::Now());
+ response_.request_time, response_.response_time,
+ cache_->clock_->Now());
custom_request_->extra_headers.SetHeader(
kFreshnessHeader,

Powered by Google App Engine
This is Rietveld 408576698