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

Side by Side Diff: content/browser/loader/async_revalidation_driver.cc

Issue 1041993004: content::ResourceDispatcherHostImpl changes for stale-while-revalidate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@s-w-r-yhirano-patch
Patch Set: Remove unnecessary deferral logic from AsyncRevalidationDriver Created 5 years, 1 month 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/loader/async_revalidation_driver.h"
6
7 #include "base/location.h"
Bence 2015/11/17 13:12:21 What do you need this include for?
Adam Rice 2015/11/17 17:45:51 For FROM_HERE. Added a comment.
8 #include "base/logging.h"
Bence 2015/11/17 13:12:21 Please include base/macros.h for DCHECK.
Adam Rice 2015/11/17 17:45:51 Is is going to move there? It is currently in base
Bence 2015/11/17 21:34:27 You are right. Sorry.
9 #include "base/metrics/user_metrics_action.h"
10 #include "base/single_thread_task_runner.h"
Bence 2015/11/17 13:12:21 What do you need this include for?
Adam Rice 2015/11/17 17:45:51 base::ThreadTaskRunnerHandle::Get() returns a Sing
11 #include "base/thread_task_runner_handle.h"
12 #include "base/time/time.h"
13 #include "content/public/browser/user_metrics.h"
14 #include "net/base/net_errors.h"
15 #include "net/cert/cert_status_flags.h"
16 #include "net/http/http_transaction_factory.h"
Bence 2015/11/17 13:12:21 What do you need this include for?
Adam Rice 2015/11/17 17:45:51 It looks like a mistake. I have removed it.
17
18 #include "net/ssl/ssl_info.h"
19 #include "net/url_request/url_request.h"
Bence 2015/11/17 13:12:21 Please remove this include, because you already in
Adam Rice 2015/11/17 17:45:51 Thanks, done.
20 #include "net/url_request/url_request_context.h"
21 #include "net/url_request/url_request_status.h"
22
23 using base::TimeDelta;
24 using base::TimeTicks;
Bence 2015/11/17 13:12:21 Please remove both these forward declarations, bec
Adam Rice 2015/11/17 17:45:51 Done.
25
26 namespace content {
27
28 namespace {
29 // This matches the maximum allocation size of AsyncResourceHandler.
30 const int kReadBufSize = 32 * 1024;
31 const int kReadTimeoutSeconds = 5 * 60;
32 }
33
34 // The use of base::Unretained() in the initialisation of read_timer_ is safe
35 // because base::Timer guarantees not to call the callback after being
36 // destroyed.
37 AsyncRevalidationDriver::AsyncRevalidationDriver(
38 scoped_ptr<net::URLRequest> request,
39 scoped_ptr<ResourceThrottle> throttle,
40 const base::Closure& completion_callback)
41 : read_timer_(FROM_HERE,
42 TimeDelta::FromSeconds(kReadTimeoutSeconds),
43 base::Bind(&AsyncRevalidationDriver::OnReadTimeout,
44 base::Unretained(this)),
45 false),
46 request_(request.Pass()),
47 throttle_(throttle.Pass()),
48 completion_callback_(completion_callback),
49 weak_ptr_factory_(this) {
50 request_->set_delegate(this);
51 throttle_->set_controller(this);
52 }
53
54 AsyncRevalidationDriver::~AsyncRevalidationDriver() {
55 weak_ptr_factory_.InvalidateWeakPtrs();
56 // Run ResourceThrottle destructor before we tear-down the rest of our state
57 // as the ResourceThrottle may want to inspect the URLRequest and other state.
58 throttle_.reset();
59 }
60
61 void AsyncRevalidationDriver::StartRequest() {
62 RecordAction(base::UserMetricsAction("AsyncRevalidationCreated"));
63 // Give the handler a chance to delay the URLRequest from being started.
64 bool defer_start = false;
65 throttle_->WillStartRequest(&defer_start);
66
67 if (defer_start) {
68 RecordDefer();
69 } else {
70 StartRequestInternal();
71 }
72 }
73
74 void AsyncRevalidationDriver::CancelRequest() {
75 CancelRequestInternal(net::ERR_ABORTED);
76 }
77
78 void AsyncRevalidationDriver::OnReceivedRedirect(
79 net::URLRequest* unused,
80 const net::RedirectInfo& redirect_info,
81 bool* defer) {
82 DCHECK_EQ(request_.get(), unused);
83
Bence 2015/11/17 13:12:21 Please add a comment along the lines of "The reval
Adam Rice 2015/11/17 17:45:51 Done.
84 DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec();
85 RecordAction(base::UserMetricsAction("AsyncRevalidationRedirected"));
86 CancelRequest();
87 }
88
89 void AsyncRevalidationDriver::OnAuthRequired(
90 net::URLRequest* unused,
91 net::AuthChallengeInfo* auth_info) {
92 DCHECK_EQ(request_.get(), unused);
93 // This error code doesn't have exactly the right semantics, but it should
94 // be sufficient to narrow down the problem in net logs.
95 request_->CancelWithError(net::ERR_ACCESS_DENIED);
96 }
97
98 void AsyncRevalidationDriver::OnBeforeNetworkStart(net::URLRequest* unused,
99 bool* defer) {
100 DCHECK_EQ(request_.get(), unused);
101
102 // Verify that the ResourceScheduler does not defer here.
103 throttle_->WillStartUsingNetwork(defer);
104 DCHECK(!defer);
105 }
106
107 void AsyncRevalidationDriver::OnResponseStarted(net::URLRequest* unused) {
108 DCHECK_EQ(request_.get(), unused);
109
110 DVLOG(1) << "OnResponseStarted: " << request_->url().spec();
111
112 if (!request_->status().is_success()) {
113 DCHECK(!has_already_failed_);
114 has_already_failed_ = true;
Bence 2015/11/17 13:12:21 Consider moving these two lines (DCHECK and set |h
Adam Rice 2015/11/17 17:45:51 Done. I changed ResponseCompleted() to reset the c
115 ResponseCompleted();
116 return;
117 }
118
119 const net::HttpResponseInfo& response_info = request_->response_info();
120 if (!response_info.response_time.is_null() && response_info.was_cached) {
121 // The cached entry was revalidated. No need to read it in.
122 ResponseCompleted();
123 return;
124 }
125
126 bool defer = false;
127 throttle_->WillProcessResponse(&defer);
128 DCHECK(!defer);
129
130 if (request_->status().is_success()) {
131 StartReading(false); // Read the first chunk.
132 } else {
133 DCHECK(!has_already_failed_);
134 has_already_failed_ = true;
135 ResponseCompleted();
136 }
137 }
138
139 void AsyncRevalidationDriver::OnReadCompleted(net::URLRequest* unused,
140 int bytes_read) {
141 DCHECK_EQ(request_.get(), unused);
142 DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\""
143 << " bytes_read = " << bytes_read;
144
145 // bytes_read == -1 always implies an error.
146 if (bytes_read == -1 || !request_->status().is_success()) {
147 if (!has_already_failed_) {
148 has_already_failed_ = true;
149 ResponseCompleted();
150 }
151 return;
152 }
153
154 DCHECK_GE(bytes_read, 0);
155 DCHECK(request_->status().is_success());
156 DCHECK(!is_deferred());
157
158 if (bytes_read > 0) {
159 StartReading(true); // Read the next chunk.
160 } else {
161 // URLRequest reported an EOF. Call ResponseCompleted.
Bence 2015/11/17 13:12:21 Consider removing "Call ResponseCompleted." as it
Adam Rice 2015/11/17 17:45:51 Done.
162 DCHECK_EQ(0, bytes_read);
163 ResponseCompleted();
164 }
165 }
166
167 void AsyncRevalidationDriver::Resume() {
168 DCHECK(is_deferred_);
169 is_deferred_ = false;
170 StartRequestInternal();
171 }
172
173 void AsyncRevalidationDriver::Cancel() {
174 NOTREACHED();
175 }
176
177 void AsyncRevalidationDriver::CancelAndIgnore() {
178 NOTREACHED();
179 }
180
181 void AsyncRevalidationDriver::CancelWithError(int error_code) {
182 NOTREACHED();
183 }
184
185 void AsyncRevalidationDriver::StartRequestInternal() {
186 DCHECK(!request_->is_pending());
187
188 // This can happen if Resume() is called after CancelRequest().
189 // Since CancelRequest() has already been called, it isn't necessary
190 // to call ResponseCompleted().
Bence 2015/11/17 13:12:21 Consider adding DCHECK(has_already_failed_) to doc
Adam Rice 2015/11/17 17:45:51 In this case CancelRequestInternal calls ResponseC
191 if (!request_->status().is_success())
192 return;
193
194 request_->Start();
195 }
196
197 void AsyncRevalidationDriver::CancelRequestInternal(int error) {
198 DVLOG(1) << "CancelRequestInternal: " << request_->url().spec();
199
200 bool was_pending = request_->is_pending();
201
202 request_->CancelWithError(error);
203
204 if (!was_pending) {
205 // If the request isn't in flight, then we won't get an asynchronous
206 // notification from the request, so we have to signal ourselves to finish
207 // this request.
208 base::ThreadTaskRunnerHandle::Get()->PostTask(
209 FROM_HERE, base::Bind(&AsyncRevalidationDriver::ResponseCompleted,
210 weak_ptr_factory_.GetWeakPtr()));
211 }
212 }
213
214 void AsyncRevalidationDriver::CompleteResponseStarted() {
215 bool defer = false;
216 throttle_->WillProcessResponse(&defer);
217 DCHECK(!defer);
218 }
219
220 void AsyncRevalidationDriver::StartReading(bool is_continuation) {
221 int bytes_read = 0;
222 ReadMore(&bytes_read);
223
224 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
225 if (request_->status().is_io_pending())
226 return;
227
228 if (!is_continuation || bytes_read <= 0) {
229 OnReadCompleted(request_.get(), bytes_read);
230 } else {
231 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO
232 // thread in case the URLRequest can provide data synchronously.
233 base::ThreadTaskRunnerHandle::Get()->PostTask(
234 FROM_HERE,
235 base::Bind(&AsyncRevalidationDriver::OnReadCompleted,
236 weak_ptr_factory_.GetWeakPtr(), request_.get(), bytes_read));
237 }
238 }
239
240 void AsyncRevalidationDriver::ReadMore(int* bytes_read) {
241 DCHECK(!is_deferred());
242
243 if (!read_buffer_)
244 read_buffer_ = new net::IOBuffer(kReadBufSize);
245
246 read_timer_.Reset();
247 request_->Read(read_buffer_.get(), kReadBufSize, bytes_read);
248
249 // No need to check the return value here as we'll detect errors by
250 // inspecting the URLRequest's status.
251 }
252
253 void AsyncRevalidationDriver::ResponseCompleted() {
254 DVLOG(1) << "ResponseCompleted: " << request_->url().spec();
255 completion_callback_.Run();
256 }
257
258 void AsyncRevalidationDriver::OnReadTimeout() {
259 RecordAction(base::UserMetricsAction("AsyncRevalidationTimeout"));
260 CancelRequestInternal(net::ERR_TIMED_OUT);
261 }
262
263 void AsyncRevalidationDriver::RecordDefer() {
264 request_->LogBlockedBy(throttle_->GetNameForLogging());
265 DCHECK(!is_deferred_);
266 is_deferred_ = true;
267 }
268
269 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698