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

Side by Side Diff: net/http/http_stream_factory_impl_job_controller.cc

Issue 2332193003: JobController3: Move MarkAlternativeServiceBroken to job controller (Closed)
Patch Set: move logic to job controller Created 4 years, 3 months 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
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_stream_factory_impl_job_controller.h" 5 #include "net/http/http_stream_factory_impl_job_controller.h"
6 6
7 #include "base/metrics/histogram_macros.h" 7 #include "base/metrics/histogram_macros.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/values.h" 10 #include "base/values.h"
(...skipping 20 matching lines...) Expand all
31 HttpStreamFactoryImpl* factory, 31 HttpStreamFactoryImpl* factory,
32 HttpStreamRequest::Delegate* delegate, 32 HttpStreamRequest::Delegate* delegate,
33 HttpNetworkSession* session, 33 HttpNetworkSession* session,
34 JobFactory* job_factory) 34 JobFactory* job_factory)
35 : factory_(factory), 35 : factory_(factory),
36 session_(session), 36 session_(session),
37 job_factory_(job_factory), 37 job_factory_(job_factory),
38 request_(nullptr), 38 request_(nullptr),
39 delegate_(delegate), 39 delegate_(delegate),
40 is_preconnect_(false), 40 is_preconnect_(false),
41 alternative_service_is_broken_(false),
41 job_bound_(false), 42 job_bound_(false),
42 main_job_is_blocked_(false), 43 main_job_is_blocked_(false),
43 bound_job_(nullptr), 44 bound_job_(nullptr),
44 can_start_alternative_proxy_job_(false), 45 can_start_alternative_proxy_job_(false),
45 ptr_factory_(this) { 46 ptr_factory_(this) {
46 DCHECK(factory); 47 DCHECK(factory);
47 } 48 }
48 49
49 HttpStreamFactoryImpl::JobController::~JobController() { 50 HttpStreamFactoryImpl::JobController::~JobController() {
50 main_job_.reset(); 51 main_job_.reset();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 if (alternative_job_) { 159 if (alternative_job_) {
159 alternative_job_->SetPriority(priority); 160 alternative_job_->SetPriority(priority);
160 } 161 }
161 } 162 }
162 163
163 void HttpStreamFactoryImpl::JobController::OnStreamReady( 164 void HttpStreamFactoryImpl::JobController::OnStreamReady(
164 Job* job, 165 Job* job,
165 const SSLConfig& used_ssl_config, 166 const SSLConfig& used_ssl_config,
166 const ProxyInfo& used_proxy_info) { 167 const ProxyInfo& used_proxy_info) {
167 DCHECK(job); 168 DCHECK(job);
169 MaybeReportAlternativeServiceBroken(job);
168 170
169 if (job_bound_ && bound_job_ != job) { 171 if (job_bound_ && bound_job_ != job) {
170 // We have bound a job to the associated Request, |job| has been orphaned. 172 // We have bound a job to the associated Request, |job| has been orphaned.
171 OnOrphanedJobComplete(job); 173 OnOrphanedJobComplete(job);
172 return; 174 return;
173 } 175 }
174 std::unique_ptr<HttpStream> stream = job->ReleaseStream(); 176 std::unique_ptr<HttpStream> stream = job->ReleaseStream();
175 DCHECK(stream); 177 DCHECK(stream);
176 178
177 MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(), 179 MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(),
178 job->using_spdy()); 180 job->using_spdy());
179 181
180 if (!request_) 182 if (!request_)
181 return; 183 return;
182 DCHECK(!factory_->for_websockets_); 184 DCHECK(!factory_->for_websockets_);
183 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type()); 185 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type());
184 OnJobSucceeded(job); 186 OnJobSucceeded(job);
185 request_->OnStreamReady(used_ssl_config, used_proxy_info, stream.release()); 187 request_->OnStreamReady(used_ssl_config, used_proxy_info, stream.release());
186 } 188 }
187 189
188 void HttpStreamFactoryImpl::JobController::OnBidirectionalStreamImplReady( 190 void HttpStreamFactoryImpl::JobController::OnBidirectionalStreamImplReady(
189 Job* job, 191 Job* job,
190 const SSLConfig& used_ssl_config, 192 const SSLConfig& used_ssl_config,
191 const ProxyInfo& used_proxy_info) { 193 const ProxyInfo& used_proxy_info) {
192 DCHECK(job); 194 DCHECK(job);
195 MaybeReportAlternativeServiceBroken(job);
193 196
194 if (job_bound_ && bound_job_ != job) { 197 if (job_bound_ && bound_job_ != job) {
195 // We have bound a job to the associated Request, |job| has been orphaned. 198 // We have bound a job to the associated Request, |job| has been orphaned.
196 OnOrphanedJobComplete(job); 199 OnOrphanedJobComplete(job);
197 return; 200 return;
198 } 201 }
199 202
200 MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(), 203 MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(),
201 job->using_spdy()); 204 job->using_spdy());
202 205
203 if (!request_) 206 if (!request_)
204 return; 207 return;
205 std::unique_ptr<BidirectionalStreamImpl> stream = 208 std::unique_ptr<BidirectionalStreamImpl> stream =
206 job->ReleaseBidirectionalStream(); 209 job->ReleaseBidirectionalStream();
207 DCHECK(stream); 210 DCHECK(stream);
208 DCHECK(!factory_->for_websockets_); 211 DCHECK(!factory_->for_websockets_);
209 DCHECK_EQ(HttpStreamRequest::BIDIRECTIONAL_STREAM, request_->stream_type()); 212 DCHECK_EQ(HttpStreamRequest::BIDIRECTIONAL_STREAM, request_->stream_type());
210 213
211 OnJobSucceeded(job); 214 OnJobSucceeded(job);
212 request_->OnBidirectionalStreamImplReady(used_ssl_config, used_proxy_info, 215 request_->OnBidirectionalStreamImplReady(used_ssl_config, used_proxy_info,
213 stream.release()); 216 stream.release());
214 } 217 }
215 218
216 void HttpStreamFactoryImpl::JobController::OnWebSocketHandshakeStreamReady( 219 void HttpStreamFactoryImpl::JobController::OnWebSocketHandshakeStreamReady(
217 Job* job, 220 Job* job,
218 const SSLConfig& used_ssl_config, 221 const SSLConfig& used_ssl_config,
219 const ProxyInfo& used_proxy_info, 222 const ProxyInfo& used_proxy_info,
220 WebSocketHandshakeStreamBase* stream) { 223 WebSocketHandshakeStreamBase* stream) {
221 DCHECK(job); 224 DCHECK(job);
225 MaybeReportAlternativeServiceBroken(job);
222 226
223 MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(), 227 MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(),
224 job->using_spdy()); 228 job->using_spdy());
225 229
226 if (!request_) 230 if (!request_)
227 return; 231 return;
228 DCHECK(factory_->for_websockets_); 232 DCHECK(factory_->for_websockets_);
229 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type()); 233 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type());
230 DCHECK(stream); 234 DCHECK(stream);
231 235
(...skipping 17 matching lines...) Expand all
249 if (!request_) 253 if (!request_)
250 return; 254 return;
251 DCHECK_NE(OK, status); 255 DCHECK_NE(OK, status);
252 DCHECK(job); 256 DCHECK(job);
253 257
254 if (!bound_job_) { 258 if (!bound_job_) {
255 if (main_job_ && alternative_job_) { 259 if (main_job_ && alternative_job_) {
256 // Hey, we've got other jobs! Maybe one of them will succeed, let's just 260 // Hey, we've got other jobs! Maybe one of them will succeed, let's just
257 // ignore this failure. 261 // ignore this failure.
258 factory_->request_map_.erase(job); 262 factory_->request_map_.erase(job);
259 // Notify all the other jobs that this one failed.
260 if (job->job_type() == MAIN) { 263 if (job->job_type() == MAIN) {
261 alternative_job_->MarkOtherJobComplete(*job);
262 main_job_.reset(); 264 main_job_.reset();
263 } else { 265 } else {
264 DCHECK(job->job_type() == ALTERNATIVE); 266 DCHECK(job->job_type() == ALTERNATIVE);
265 main_job_->MarkOtherJobComplete(*job);
266 alternative_job_.reset(); 267 alternative_job_.reset();
267 } 268 }
268 return; 269 return;
269 } else { 270 } else {
270 BindJob(job); 271 BindJob(job);
271 } 272 }
272 } 273 }
273 274
274 request_->OnStreamFailed(status, used_ssl_config); 275 request_->OnStreamFailed(status, used_ssl_config);
275 } 276 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 base::Unretained(alternative_job_.get()), 398 base::Unretained(alternative_job_.get()),
398 request_->stream_type())); 399 request_->stream_type()));
399 } 400 }
400 401
401 void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady( 402 void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady(
402 Job* job, 403 Job* job,
403 const base::WeakPtr<SpdySession>& spdy_session, 404 const base::WeakPtr<SpdySession>& spdy_session,
404 bool direct) { 405 bool direct) {
405 DCHECK(job); 406 DCHECK(job);
406 DCHECK(job->using_spdy()); 407 DCHECK(job->using_spdy());
408 MaybeReportAlternativeServiceBroken(job);
407 409
408 bool is_job_orphaned = job_bound_ && bound_job_ != job; 410 bool is_job_orphaned = job_bound_ && bound_job_ != job;
409 411
410 // Cache these values in case the job gets deleted. 412 // Cache these values in case the job gets deleted.
411 const SSLConfig used_ssl_config = job->server_ssl_config(); 413 const SSLConfig used_ssl_config = job->server_ssl_config();
412 const ProxyInfo used_proxy_info = job->proxy_info(); 414 const ProxyInfo used_proxy_info = job->proxy_info();
413 const bool was_npn_negotiated = job->was_npn_negotiated(); 415 const bool was_npn_negotiated = job->was_npn_negotiated();
414 const NextProto negotiated_protocol = job->negotiated_protocol(); 416 const NextProto negotiated_protocol = job->negotiated_protocol();
415 const bool using_spdy = job->using_spdy(); 417 const bool using_spdy = job->using_spdy();
416 const BoundNetLog net_log = job->net_log(); 418 const BoundNetLog net_log = job->net_log();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 base::Bind(&NetLogHttpStreamJobDelayCallback, main_job_wait_time_)); 499 base::Bind(&NetLogHttpStreamJobDelayCallback, main_job_wait_time_));
498 500
499 main_job_->Resume(); 501 main_job_->Resume();
500 main_job_wait_time_ = base::TimeDelta(); 502 main_job_wait_time_ = base::TimeDelta();
501 } 503 }
502 504
503 void HttpStreamFactoryImpl::JobController::MaybeResumeMainJob( 505 void HttpStreamFactoryImpl::JobController::MaybeResumeMainJob(
504 Job* job, 506 Job* job,
505 const base::TimeDelta& delay) { 507 const base::TimeDelta& delay) {
506 DCHECK(job == main_job_.get() || job == alternative_job_.get()); 508 DCHECK(job == main_job_.get() || job == alternative_job_.get());
509 if (job == alternative_job_.get())
510 MaybeMarkAlternativeServiceBroken(job);
511
507 if (!main_job_is_blocked_ || job != alternative_job_.get() || !main_job_) 512 if (!main_job_is_blocked_ || job != alternative_job_.get() || !main_job_)
508 return; 513 return;
509 514
510 main_job_is_blocked_ = false; 515 main_job_is_blocked_ = false;
511 516
512 if (!main_job_->is_waiting()) 517 if (!main_job_->is_waiting())
513 return; 518 return;
514 519
515 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 520 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
516 FROM_HERE, 521 FROM_HERE,
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 // another Job completes first. 730 // another Job completes first.
726 // TODO(mbelshe): Revisit this when we implement ip connection pooling of 731 // TODO(mbelshe): Revisit this when we implement ip connection pooling of
727 // SpdySessions. Do we want to orphan the jobs for a different hostname so 732 // SpdySessions. Do we want to orphan the jobs for a different hostname so
728 // they complete? Or do we want to prevent connecting a new SpdySession if 733 // they complete? Or do we want to prevent connecting a new SpdySession if
729 // we've already got one available for a different hostname where the ip 734 // we've already got one available for a different hostname where the ip
730 // address matches up? 735 // address matches up?
731 CancelJobs(); 736 CancelJobs();
732 return; 737 return;
733 } 738 }
734 if (!bound_job_) { 739 if (!bound_job_) {
735 if (main_job_ && alternative_job_) { 740 if (main_job_ && alternative_job_)
736 job->ReportJobSucceededForRequest(); 741 job->ReportJobSucceededForRequest();
737 // Notify all the other jobs that this one succeeded.
738 if (job->job_type() == MAIN) {
739 alternative_job_->MarkOtherJobComplete(*job);
740 } else {
741 DCHECK(job->job_type() == ALTERNATIVE);
742 main_job_->MarkOtherJobComplete(*job);
743 }
744 }
745 BindJob(job); 742 BindJob(job);
746 return; 743 return;
747 } 744 }
748 DCHECK(bound_job_); 745 DCHECK(bound_job_);
749 } 746 }
750 747
751 void HttpStreamFactoryImpl::JobController::MarkRequestComplete( 748 void HttpStreamFactoryImpl::JobController::MarkRequestComplete(
752 bool was_npn_negotiated, 749 bool was_npn_negotiated,
753 NextProto negotiated_protocol, 750 NextProto negotiated_protocol,
754 bool using_spdy) { 751 bool using_spdy) {
755 if (request_) 752 if (request_)
756 request_->Complete(was_npn_negotiated, negotiated_protocol, using_spdy); 753 request_->Complete(was_npn_negotiated, negotiated_protocol, using_spdy);
757 } 754 }
758 755
756 void HttpStreamFactoryImpl::JobController::MaybeMarkAlternativeServiceBroken(
757 Job* job) {
758 if (job->job_type() == MAIN || !job->alternative_broken())
759 return;
760
761 alternative_service_is_broken_ = true;
762 if (job->alternative_proxy_server().is_valid()) {
763 broken_alternative_proxy_server_ = job->alternative_proxy_server();
764 } else {
765 DCHECK(!broken_alternative_proxy_server_.is_valid());
766 broken_alternative_service_ = job->alternative_service();
767 }
768 }
769
770 void HttpStreamFactoryImpl::JobController::MaybeReportAlternativeServiceBroken(
771 Job* job) {
772 // Only report QUIC broken alternative service when main job succeeds.
773 if (job->job_type() == ALTERNATIVE)
774 return;
Ryan Hamilton 2016/09/13 23:23:15 As discussed offline, I think we need to make sure
775
776 if (!alternative_service_is_broken_)
777 return;
778
779 if (broken_alternative_proxy_server_.is_valid()) {
780 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate;
781 if (proxy_delegate)
782 proxy_delegate->OnAlternativeProxyBroken(
783 broken_alternative_proxy_server_);
784 } else {
785 HistogramBrokenAlternateProtocolLocation(
786 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT);
787 session_->http_server_properties()->MarkAlternativeServiceBroken(
788 broken_alternative_service_);
789 }
790 session_->quic_stream_factory()->OnTcpJobCompleted(true);
791 }
792
759 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { 793 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() {
760 if (!request_ && !main_job_ && !alternative_job_) { 794 if (!request_ && !main_job_ && !alternative_job_) {
761 DCHECK(!bound_job_); 795 DCHECK(!bound_job_);
762 factory_->OnJobControllerComplete(this); 796 factory_->OnJobControllerComplete(this);
763 } 797 }
764 } 798 }
765 799
766 GURL HttpStreamFactoryImpl::JobController::ApplyHostMappingRules( 800 GURL HttpStreamFactoryImpl::JobController::ApplyHostMappingRules(
767 const GURL& url, 801 const GURL& url,
768 HostPortPair* endpoint) { 802 HostPortPair* endpoint) {
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 if (!session_->params().enable_quic || 1037 if (!session_->params().enable_quic ||
1004 session_->quic_stream_factory()->IsQuicDisabled( 1038 session_->quic_stream_factory()->IsQuicDisabled(
1005 alternative_proxy_server->host_port_pair().port())) { 1039 alternative_proxy_server->host_port_pair().port())) {
1006 return false; 1040 return false;
1007 } 1041 }
1008 } 1042 }
1009 1043
1010 return true; 1044 return true;
1011 } 1045 }
1012 } 1046 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698