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

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

Issue 2332193003: JobController3: Move MarkAlternativeServiceBroken to job controller (Closed)
Patch Set: nit 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_job_is_failed_(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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 request_->OnBidirectionalStreamImplReady(used_ssl_config, used_proxy_info, 213 request_->OnBidirectionalStreamImplReady(used_ssl_config, used_proxy_info,
213 stream.release()); 214 stream.release());
214 } 215 }
215 216
216 void HttpStreamFactoryImpl::JobController::OnWebSocketHandshakeStreamReady( 217 void HttpStreamFactoryImpl::JobController::OnWebSocketHandshakeStreamReady(
217 Job* job, 218 Job* job,
218 const SSLConfig& used_ssl_config, 219 const SSLConfig& used_ssl_config,
219 const ProxyInfo& used_proxy_info, 220 const ProxyInfo& used_proxy_info,
220 WebSocketHandshakeStreamBase* stream) { 221 WebSocketHandshakeStreamBase* stream) {
221 DCHECK(job); 222 DCHECK(job);
222
223 MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(), 223 MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(),
224 job->using_spdy()); 224 job->using_spdy());
225 225
226 if (!request_) 226 if (!request_)
227 return; 227 return;
228 DCHECK(factory_->for_websockets_); 228 DCHECK(factory_->for_websockets_);
229 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type()); 229 DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type());
230 DCHECK(stream); 230 DCHECK(stream);
231 231
232 OnJobSucceeded(job); 232 OnJobSucceeded(job);
233 request_->OnWebSocketHandshakeStreamReady(used_ssl_config, used_proxy_info, 233 request_->OnWebSocketHandshakeStreamReady(used_ssl_config, used_proxy_info,
234 stream); 234 stream);
235 } 235 }
236 236
237 void HttpStreamFactoryImpl::JobController::OnStreamFailed( 237 void HttpStreamFactoryImpl::JobController::OnStreamFailed(
238 Job* job, 238 Job* job,
239 int status, 239 int status,
240 const SSLConfig& used_ssl_config) { 240 const SSLConfig& used_ssl_config) {
241 if (job->job_type() == ALTERNATIVE)
242 OnAlternativeJobFailed(job);
243
241 MaybeResumeMainJob(job, base::TimeDelta()); 244 MaybeResumeMainJob(job, base::TimeDelta());
242 245
243 if (job_bound_ && bound_job_ != job) { 246 if (job_bound_ && bound_job_ != job) {
244 // We have bound a job to the associated Request, |job| has been orphaned. 247 // We have bound a job to the associated Request, |job| has been orphaned.
245 OnOrphanedJobComplete(job); 248 OnOrphanedJobComplete(job);
246 return; 249 return;
247 } 250 }
248 251
249 if (!request_) 252 if (!request_)
250 return; 253 return;
251 DCHECK_NE(OK, status); 254 DCHECK_NE(OK, status);
252 DCHECK(job); 255 DCHECK(job);
253 256
254 if (!bound_job_) { 257 if (!bound_job_) {
255 if (main_job_ && alternative_job_) { 258 if (main_job_ && alternative_job_) {
256 // Hey, we've got other jobs! Maybe one of them will succeed, let's just 259 // Hey, we've got other jobs! Maybe one of them will succeed, let's just
257 // ignore this failure. 260 // ignore this failure.
258 factory_->request_map_.erase(job); 261 factory_->request_map_.erase(job);
259 // Notify all the other jobs that this one failed.
260 if (job->job_type() == MAIN) { 262 if (job->job_type() == MAIN) {
261 alternative_job_->MarkOtherJobComplete(*job);
262 main_job_.reset(); 263 main_job_.reset();
263 } else { 264 } else {
264 DCHECK(job->job_type() == ALTERNATIVE); 265 DCHECK(job->job_type() == ALTERNATIVE);
265 main_job_->MarkOtherJobComplete(*job);
266 alternative_job_.reset(); 266 alternative_job_.reset();
267 } 267 }
268 return; 268 return;
269 } else { 269 } else {
270 BindJob(job); 270 BindJob(job);
271 } 271 }
272 } 272 }
273 273
274 request_->OnStreamFailed(status, used_ssl_config); 274 request_->OnStreamFailed(status, used_ssl_config);
275 } 275 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 const bool was_npn_negotiated = job->was_npn_negotiated(); 413 const bool was_npn_negotiated = job->was_npn_negotiated();
414 const NextProto negotiated_protocol = job->negotiated_protocol(); 414 const NextProto negotiated_protocol = job->negotiated_protocol();
415 const bool using_spdy = job->using_spdy(); 415 const bool using_spdy = job->using_spdy();
416 const BoundNetLog net_log = job->net_log(); 416 const BoundNetLog net_log = job->net_log();
417 417
418 // Cache this so we can still use it if the JobController is deleted. 418 // Cache this so we can still use it if the JobController is deleted.
419 HttpStreamFactoryImpl* factory = factory_; 419 HttpStreamFactoryImpl* factory = factory_;
420 420
421 // Notify |request_|. 421 // Notify |request_|.
422 if (!is_preconnect_ && !is_job_orphaned) { 422 if (!is_preconnect_ && !is_job_orphaned) {
423 if (job->job_type() == MAIN && alternative_job_is_failed_)
424 ReportBrokenAlternativeService();
425
423 DCHECK(request_); 426 DCHECK(request_);
424 427
425 // The first case is the usual case. 428 // The first case is the usual case.
426 if (!job_bound_) { 429 if (!job_bound_) {
427 BindJob(job); 430 BindJob(job);
428 } 431 }
429 432
430 MarkRequestComplete(was_npn_negotiated, negotiated_protocol, using_spdy); 433 MarkRequestComplete(was_npn_negotiated, negotiated_protocol, using_spdy);
431 434
432 std::unique_ptr<HttpStream> stream; 435 std::unique_ptr<HttpStream> stream;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 base::Bind(&NetLogHttpStreamJobDelayCallback, main_job_wait_time_)); 500 base::Bind(&NetLogHttpStreamJobDelayCallback, main_job_wait_time_));
498 501
499 main_job_->Resume(); 502 main_job_->Resume();
500 main_job_wait_time_ = base::TimeDelta(); 503 main_job_wait_time_ = base::TimeDelta();
501 } 504 }
502 505
503 void HttpStreamFactoryImpl::JobController::MaybeResumeMainJob( 506 void HttpStreamFactoryImpl::JobController::MaybeResumeMainJob(
504 Job* job, 507 Job* job,
505 const base::TimeDelta& delay) { 508 const base::TimeDelta& delay) {
506 DCHECK(job == main_job_.get() || job == alternative_job_.get()); 509 DCHECK(job == main_job_.get() || job == alternative_job_.get());
510
507 if (!main_job_is_blocked_ || job != alternative_job_.get() || !main_job_) 511 if (!main_job_is_blocked_ || job != alternative_job_.get() || !main_job_)
508 return; 512 return;
509 513
510 main_job_is_blocked_ = false; 514 main_job_is_blocked_ = false;
511 515
512 if (!main_job_->is_waiting()) 516 if (!main_job_->is_waiting())
513 return; 517 return;
514 518
515 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 519 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
516 FROM_HERE, 520 FROM_HERE,
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 // because we *WANT* to cancel the unnecessary Jobs from other requests if 728 // because we *WANT* to cancel the unnecessary Jobs from other requests if
725 // another Job completes first. 729 // another Job completes first.
726 // TODO(mbelshe): Revisit this when we implement ip connection pooling of 730 // 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 731 // 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 732 // 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 733 // we've already got one available for a different hostname where the ip
730 // address matches up? 734 // address matches up?
731 CancelJobs(); 735 CancelJobs();
732 return; 736 return;
733 } 737 }
738
739 if (job->job_type() == MAIN && alternative_job_is_failed_)
740 ReportBrokenAlternativeService();
741
734 if (!bound_job_) { 742 if (!bound_job_) {
735 if (main_job_ && alternative_job_) { 743 if (main_job_ && alternative_job_)
736 job->ReportJobSucceededForRequest(); 744 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); 745 BindJob(job);
746 return; 746 return;
747 } 747 }
748 DCHECK(bound_job_); 748 DCHECK(bound_job_);
749 } 749 }
750 750
751 void HttpStreamFactoryImpl::JobController::MarkRequestComplete( 751 void HttpStreamFactoryImpl::JobController::MarkRequestComplete(
752 bool was_npn_negotiated, 752 bool was_npn_negotiated,
753 NextProto negotiated_protocol, 753 NextProto negotiated_protocol,
754 bool using_spdy) { 754 bool using_spdy) {
755 if (request_) 755 if (request_)
756 request_->Complete(was_npn_negotiated, negotiated_protocol, using_spdy); 756 request_->Complete(was_npn_negotiated, negotiated_protocol, using_spdy);
757 } 757 }
758 758
759 void HttpStreamFactoryImpl::JobController::OnAlternativeJobFailed(Job* job) {
760 DCHECK_EQ(job->job_type(), ALTERNATIVE);
761
762 alternative_job_is_failed_ = true;
763
764 if (job->alternative_proxy_server().is_valid()) {
765 broken_alternative_proxy_server_ = job->alternative_proxy_server();
766 } else {
767 DCHECK(!broken_alternative_proxy_server_.is_valid());
768 broken_alternative_service_ = job->alternative_service();
769 }
770
771 if (!request_ || (job_bound_ && bound_job_ != job)) {
772 // If |request_| is gone and |job| is still running, it must be successfully
773 // served by |main_job_|. Or if |request_| already has a different Job
774 // bound,
775 // |main_job_| must succeed.
Ryan Hamilton 2016/09/14 23:13:04 // If |request_| is gone then it must have been su
776 ReportBrokenAlternativeService();
777 }
778 }
779
780 void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() {
781 DCHECK(broken_alternative_service_.protocol !=
782 UNINITIALIZED_ALTERNATE_PROTOCOL ||
783 broken_alternative_proxy_server_.is_valid());
784
785 if (broken_alternative_proxy_server_.is_valid()) {
786 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate;
787 if (proxy_delegate)
788 proxy_delegate->OnAlternativeProxyBroken(
789 broken_alternative_proxy_server_);
790 } else {
791 HistogramBrokenAlternateProtocolLocation(
792 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT);
793 session_->http_server_properties()->MarkAlternativeServiceBroken(
794 broken_alternative_service_);
795 }
796 session_->quic_stream_factory()->OnTcpJobCompleted(true);
797 }
798
759 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { 799 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() {
760 if (!request_ && !main_job_ && !alternative_job_) { 800 if (!request_ && !main_job_ && !alternative_job_) {
761 DCHECK(!bound_job_); 801 DCHECK(!bound_job_);
762 factory_->OnJobControllerComplete(this); 802 factory_->OnJobControllerComplete(this);
763 } 803 }
764 } 804 }
765 805
766 GURL HttpStreamFactoryImpl::JobController::ApplyHostMappingRules( 806 GURL HttpStreamFactoryImpl::JobController::ApplyHostMappingRules(
767 const GURL& url, 807 const GURL& url,
768 HostPortPair* endpoint) { 808 HostPortPair* endpoint) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 // Check that QUIC is enabled globally, and it is not disabled. 1040 // Check that QUIC is enabled globally, and it is not disabled.
1001 if (!session_->params().enable_quic || 1041 if (!session_->params().enable_quic ||
1002 session_->quic_stream_factory()->IsQuicDisabled()) { 1042 session_->quic_stream_factory()->IsQuicDisabled()) {
1003 return false; 1043 return false;
1004 } 1044 }
1005 } 1045 }
1006 1046
1007 return true; 1047 return true;
1008 } 1048 }
1009 } 1049 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698