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

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

Issue 1952423002: JobController 2: Remove reference between HttpStreamFactoryImpl::Jobs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@Job_Controller_1
Patch Set: More tests with Resume logic Created 4 years, 5 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 "net/base/host_mapping_rules.h" 11 #include "net/base/host_mapping_rules.h"
11 #include "net/http/bidirectional_stream_impl.h" 12 #include "net/http/bidirectional_stream_impl.h"
12 #include "net/http/transport_security_state.h" 13 #include "net/http/transport_security_state.h"
13 #include "net/spdy/spdy_session.h" 14 #include "net/spdy/spdy_session.h"
14 15
15 namespace net { 16 namespace net {
16 17
18 // Returns parameters associated with the delay of the HTTP stream job.
19 std::unique_ptr<base::Value> NetLogHttpStreamJobDelayCallback(
20 base::TimeDelta delay,
21 NetLogCaptureMode /* capture_mode */) {
22 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
23 dict->SetInteger("resume_after_ms", static_cast<int>(delay.InMilliseconds()));
24 return std::move(dict);
25 }
26
17 HttpStreamFactoryImpl::JobController::JobController( 27 HttpStreamFactoryImpl::JobController::JobController(
18 HttpStreamFactoryImpl* factory, 28 HttpStreamFactoryImpl* factory,
19 HttpStreamRequest::Delegate* delegate, 29 HttpStreamRequest::Delegate* delegate,
20 HttpNetworkSession* session, 30 HttpNetworkSession* session,
21 JobFactory* job_factory) 31 JobFactory* job_factory)
22 : factory_(factory), 32 : factory_(factory),
23 session_(session), 33 session_(session),
24 job_factory_(job_factory), 34 job_factory_(job_factory),
25 request_(nullptr), 35 request_(nullptr),
26 delegate_(delegate), 36 delegate_(delegate),
27 is_preconnect_(false), 37 is_preconnect_(false),
28 job_bound_(false), 38 job_bound_(false),
29 bound_job_(nullptr) { 39 main_job_is_blocked_(false),
40 bound_job_(nullptr),
41 ptr_factory_(this) {
30 DCHECK(factory); 42 DCHECK(factory);
31 } 43 }
32 44
33 HttpStreamFactoryImpl::JobController::~JobController() { 45 HttpStreamFactoryImpl::JobController::~JobController() {
34 main_job_.reset(); 46 main_job_.reset();
35 alternative_job_.reset(); 47 alternative_job_.reset();
36 bound_job_ = nullptr; 48 bound_job_ = nullptr;
37 } 49 }
38 50
39 bool HttpStreamFactoryImpl::JobController::for_websockets() { 51 bool HttpStreamFactoryImpl::JobController::for_websockets() {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 OnJobSucceeded(job); 228 OnJobSucceeded(job);
217 request_->OnWebSocketHandshakeStreamReady(used_ssl_config, used_proxy_info, 229 request_->OnWebSocketHandshakeStreamReady(used_ssl_config, used_proxy_info,
218 stream); 230 stream);
219 } 231 }
220 232
221 void HttpStreamFactoryImpl::JobController::OnStreamFailed( 233 void HttpStreamFactoryImpl::JobController::OnStreamFailed(
222 Job* job, 234 Job* job,
223 int status, 235 int status,
224 const SSLConfig& used_ssl_config, 236 const SSLConfig& used_ssl_config,
225 SSLFailureState ssl_failure_state) { 237 SSLFailureState ssl_failure_state) {
238 MaybeResumeMainJob(job, base::TimeDelta());
239
226 if (job_bound_ && bound_job_ != job) { 240 if (job_bound_ && bound_job_ != job) {
227 // We have bound a job to the associated Request, |job| has been orphaned. 241 // We have bound a job to the associated Request, |job| has been orphaned.
228 OnOrphanedJobComplete(job); 242 OnOrphanedJobComplete(job);
229 return; 243 return;
230 } 244 }
231 245
232 if (!request_) 246 if (!request_)
233 return; 247 return;
234 DCHECK_NE(OK, status); 248 DCHECK_NE(OK, status);
235 DCHECK(job); 249 DCHECK(job);
(...skipping 19 matching lines...) Expand all
255 } 269 }
256 270
257 request_->OnStreamFailed(status, used_ssl_config, ssl_failure_state); 271 request_->OnStreamFailed(status, used_ssl_config, ssl_failure_state);
258 } 272 }
259 273
260 void HttpStreamFactoryImpl::JobController::OnCertificateError( 274 void HttpStreamFactoryImpl::JobController::OnCertificateError(
261 Job* job, 275 Job* job,
262 int status, 276 int status,
263 const SSLConfig& used_ssl_config, 277 const SSLConfig& used_ssl_config,
264 const SSLInfo& ssl_info) { 278 const SSLInfo& ssl_info) {
279 MaybeResumeMainJob(job, base::TimeDelta());
280
265 if (job_bound_ && bound_job_ != job) { 281 if (job_bound_ && bound_job_ != job) {
266 // We have bound a job to the associated Request, |job| has been orphaned. 282 // We have bound a job to the associated Request, |job| has been orphaned.
267 OnOrphanedJobComplete(job); 283 OnOrphanedJobComplete(job);
268 return; 284 return;
269 } 285 }
270 286
271 if (!request_) 287 if (!request_)
272 return; 288 return;
273 DCHECK_NE(OK, status); 289 DCHECK_NE(OK, status);
274 if (!bound_job_) 290 if (!bound_job_)
275 BindJob(job); 291 BindJob(job);
276 292
277 request_->OnCertificateError(status, used_ssl_config, ssl_info); 293 request_->OnCertificateError(status, used_ssl_config, ssl_info);
278 } 294 }
279 295
280 void HttpStreamFactoryImpl::JobController::OnHttpsProxyTunnelResponse( 296 void HttpStreamFactoryImpl::JobController::OnHttpsProxyTunnelResponse(
281 Job* job, 297 Job* job,
282 const HttpResponseInfo& response_info, 298 const HttpResponseInfo& response_info,
283 const SSLConfig& used_ssl_config, 299 const SSLConfig& used_ssl_config,
284 const ProxyInfo& used_proxy_info, 300 const ProxyInfo& used_proxy_info,
285 HttpStream* stream) { 301 HttpStream* stream) {
302 MaybeResumeMainJob(job, base::TimeDelta());
303
286 if (job_bound_ && bound_job_ != job) { 304 if (job_bound_ && bound_job_ != job) {
287 // We have bound a job to the associated Request, |job| has been orphaned. 305 // We have bound a job to the associated Request, |job| has been orphaned.
288 OnOrphanedJobComplete(job); 306 OnOrphanedJobComplete(job);
289 return; 307 return;
290 } 308 }
291 309
292 if (!bound_job_) 310 if (!bound_job_)
293 BindJob(job); 311 BindJob(job);
294 if (!request_) 312 if (!request_)
295 return; 313 return;
296 request_->OnHttpsProxyTunnelResponse(response_info, used_ssl_config, 314 request_->OnHttpsProxyTunnelResponse(response_info, used_ssl_config,
297 used_proxy_info, stream); 315 used_proxy_info, stream);
298 } 316 }
299 317
300 void HttpStreamFactoryImpl::JobController::OnNeedsClientAuth( 318 void HttpStreamFactoryImpl::JobController::OnNeedsClientAuth(
301 Job* job, 319 Job* job,
302 const SSLConfig& used_ssl_config, 320 const SSLConfig& used_ssl_config,
303 SSLCertRequestInfo* cert_info) { 321 SSLCertRequestInfo* cert_info) {
322 MaybeResumeMainJob(job, base::TimeDelta());
323
304 if (job_bound_ && bound_job_ != job) { 324 if (job_bound_ && bound_job_ != job) {
305 // We have bound a job to the associated Request, |job| has been orphaned. 325 // We have bound a job to the associated Request, |job| has been orphaned.
306 OnOrphanedJobComplete(job); 326 OnOrphanedJobComplete(job);
307 return; 327 return;
308 } 328 }
309 if (!request_) 329 if (!request_)
310 return; 330 return;
311 if (!bound_job_) 331 if (!bound_job_)
312 BindJob(job); 332 BindJob(job);
313 333
314 request_->OnNeedsClientAuth(used_ssl_config, cert_info); 334 request_->OnNeedsClientAuth(used_ssl_config, cert_info);
315 } 335 }
316 336
317 void HttpStreamFactoryImpl::JobController::OnNeedsProxyAuth( 337 void HttpStreamFactoryImpl::JobController::OnNeedsProxyAuth(
318 Job* job, 338 Job* job,
319 const HttpResponseInfo& proxy_response, 339 const HttpResponseInfo& proxy_response,
320 const SSLConfig& used_ssl_config, 340 const SSLConfig& used_ssl_config,
321 const ProxyInfo& used_proxy_info, 341 const ProxyInfo& used_proxy_info,
322 HttpAuthController* auth_controller) { 342 HttpAuthController* auth_controller) {
343 MaybeResumeMainJob(job, base::TimeDelta());
344
323 if (job_bound_ && bound_job_ != job) { 345 if (job_bound_ && bound_job_ != job) {
324 // We have bound a job to the associated Request, |job| has been orphaned. 346 // We have bound a job to the associated Request, |job| has been orphaned.
325 OnOrphanedJobComplete(job); 347 OnOrphanedJobComplete(job);
326 return; 348 return;
327 } 349 }
328 350
329 if (!request_) 351 if (!request_)
330 return; 352 return;
331 if (!bound_job_) 353 if (!bound_job_)
332 BindJob(job); 354 BindJob(job);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 used_proxy_info, was_npn_negotiated, 414 used_proxy_info, was_npn_negotiated,
393 protocol_negotiated, using_spdy, net_log); 415 protocol_negotiated, using_spdy, net_log);
394 } 416 }
395 if (is_job_orphaned) { 417 if (is_job_orphaned) {
396 OnOrphanedJobComplete(job); 418 OnOrphanedJobComplete(job);
397 } 419 }
398 } 420 }
399 421
400 void HttpStreamFactoryImpl::JobController::OnPreconnectsComplete(Job* job) { 422 void HttpStreamFactoryImpl::JobController::OnPreconnectsComplete(Job* job) {
401 DCHECK_EQ(main_job_.get(), job); 423 DCHECK_EQ(main_job_.get(), job);
424 DCHECK(!bound_job_);
402 main_job_.reset(); 425 main_job_.reset();
403 factory_->OnPreconnectsCompleteInternal(); 426 factory_->OnPreconnectsCompleteInternal();
404 MaybeNotifyFactoryOfCompletion(); 427 MaybeNotifyFactoryOfCompletion();
405 } 428 }
406 429
407 void HttpStreamFactoryImpl::JobController::OnOrphanedJobComplete( 430 void HttpStreamFactoryImpl::JobController::OnOrphanedJobComplete(
408 const Job* job) { 431 const Job* job) {
409 if (job->job_type() == MAIN) { 432 if (job->job_type() == MAIN) {
410 DCHECK_EQ(main_job_.get(), job); 433 DCHECK_EQ(main_job_.get(), job);
411 main_job_.reset(); 434 main_job_.reset();
412 } else { 435 } else {
413 DCHECK_EQ(alternative_job_.get(), job); 436 DCHECK_EQ(alternative_job_.get(), job);
414 alternative_job_.reset(); 437 alternative_job_.reset();
415 } 438 }
416 439
417 MaybeNotifyFactoryOfCompletion(); 440 MaybeNotifyFactoryOfCompletion();
418 } 441 }
419 442
420 void HttpStreamFactoryImpl::JobController::AddConnectionAttemptsToRequest( 443 void HttpStreamFactoryImpl::JobController::AddConnectionAttemptsToRequest(
421 Job* job, 444 Job* job,
422 const ConnectionAttempts& attempts) { 445 const ConnectionAttempts& attempts) {
423 if (is_preconnect_ || (job_bound_ && bound_job_ != job)) 446 if (is_preconnect_ || (job_bound_ && bound_job_ != job))
424 return; 447 return;
425 448
426 DCHECK(request_); 449 DCHECK(request_);
427 request_->AddConnectionAttempts(attempts); 450 request_->AddConnectionAttempts(attempts);
428 } 451 }
429 452
453 void HttpStreamFactoryImpl::JobController::ResumeMainJob() {
454 main_job_->net_log().AddEvent(
455 NetLog::TYPE_HTTP_STREAM_JOB_DELAYED,
456 base::Bind(&NetLogHttpStreamJobDelayCallback, main_job_wait_time_));
457
458 main_job_->Resume();
459 main_job_wait_time_ = base::TimeDelta();
460 }
461
462 void HttpStreamFactoryImpl::JobController::MaybeResumeMainJob(
463 Job* job,
464 const base::TimeDelta& delay) {
465 DCHECK(job == main_job_.get() || job == alternative_job_.get());
466 if (!main_job_is_blocked_)
467 return;
468
469 if (job == alternative_job_.get() && main_job_) {
Ryan Hamilton 2016/07/12 00:21:45 nit: I recommend reversing the polarity of this ch
Zhongyi Shi 2016/07/12 23:03:12 Done.
470 main_job_is_blocked_ = false;
471 if (main_job_->is_waiting()) {
472 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
473 FROM_HERE,
474 base::Bind(&HttpStreamFactoryImpl::JobController::ResumeMainJob,
475 ptr_factory_.GetWeakPtr()),
476 main_job_wait_time_);
477 }
478 }
479 }
480
481 void HttpStreamFactoryImpl::JobController::OnConnectionInitialized(Job* job,
482 int rv) {
Ryan Hamilton 2016/07/12 00:21:45 can we do DCHECK(main_job_is_blocked_)?
Zhongyi Shi 2016/07/12 23:03:12 No, we couldn't. OnConnectionInitialized is called
483 if (rv != OK && rv != ERR_SPDY_SESSION_ALREADY_EXISTS) {
Ryan Hamilton 2016/07/12 00:21:45 I think perhaps we should move this ERR_SPDY_SESSI
Zhongyi Shi 2016/07/12 23:03:12 Done.
484 // Resume the main job as there's an error raised in connection
485 // initiation except the case where we find an existing SPDY session for
486 // this Job.
487 return MaybeResumeMainJob(job, main_job_wait_time_);
488 }
489 }
490
491 bool HttpStreamFactoryImpl::JobController::ShouldWait(Job* job) {
492 // The alternative job never waits.
493 if (job == alternative_job_.get())
494 return false;
495
496 if (!main_job_is_blocked_ && main_job_wait_time_.is_zero())
497 return false;
498
499 if (!main_job_wait_time_.is_zero()) {
500 main_job_is_blocked_ = false;
501 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
502 FROM_HERE,
503 base::Bind(&HttpStreamFactoryImpl::JobController::ResumeMainJob,
504 ptr_factory_.GetWeakPtr()),
505 main_job_wait_time_);
506 }
Ryan Hamilton 2016/07/12 00:21:45 Should this be: if (main_job_is_blocked_) retur
Zhongyi Shi 2016/07/12 23:03:12 Done! Hmmm, you are right. We should never run in
507 return true;
508 }
509
430 void HttpStreamFactoryImpl::JobController::SetSpdySessionKey( 510 void HttpStreamFactoryImpl::JobController::SetSpdySessionKey(
431 Job* job, 511 Job* job,
432 const SpdySessionKey& spdy_session_key) { 512 const SpdySessionKey& spdy_session_key) {
433 if (is_preconnect_ || (job_bound_ && bound_job_ != job)) 513 if (is_preconnect_ || (job_bound_ && bound_job_ != job))
434 return; 514 return;
435 515
436 DCHECK(request_); 516 DCHECK(request_);
437 if (!request_->HasSpdySessionKey()) { 517 if (!request_->HasSpdySessionKey()) {
438 RequestSet& request_set = 518 RequestSet& request_set =
439 factory_->spdy_session_request_map_[spdy_session_key]; 519 factory_->spdy_session_request_map_[spdy_session_key];
(...skipping 29 matching lines...) Expand all
469 } 549 }
470 550
471 const BoundNetLog* HttpStreamFactoryImpl::JobController::GetNetLog( 551 const BoundNetLog* HttpStreamFactoryImpl::JobController::GetNetLog(
472 Job* job) const { 552 Job* job) const {
473 if (is_preconnect_ || (job_bound_ && bound_job_ != job)) 553 if (is_preconnect_ || (job_bound_ && bound_job_ != job))
474 return nullptr; 554 return nullptr;
475 DCHECK(request_); 555 DCHECK(request_);
476 return &request_->net_log(); 556 return &request_->net_log();
477 } 557 }
478 558
559 void HttpStreamFactoryImpl::JobController::SetWaitTimeForMainJob(
560 const base::TimeDelta& delay) {
561 main_job_wait_time_ = delay;
Ryan Hamilton 2016/07/12 00:21:45 DCHECK(main_job_is_blocked);
Zhongyi Shi 2016/07/12 23:03:12 Nooo. This method is called by the Job without kno
562 }
563
479 WebSocketHandshakeStreamBase::CreateHelper* HttpStreamFactoryImpl:: 564 WebSocketHandshakeStreamBase::CreateHelper* HttpStreamFactoryImpl::
480 JobController::websocket_handshake_stream_create_helper() { 565 JobController::websocket_handshake_stream_create_helper() {
481 DCHECK(request_); 566 DCHECK(request_);
482 return request_->websocket_handshake_stream_create_helper(); 567 return request_->websocket_handshake_stream_create_helper();
483 } 568 }
484 569
485 void HttpStreamFactoryImpl::JobController::CreateJobs( 570 void HttpStreamFactoryImpl::JobController::CreateJobs(
486 const HttpRequestInfo& request_info, 571 const HttpRequestInfo& request_info,
487 RequestPriority priority, 572 RequestPriority priority,
488 const SSLConfig& server_ssl_config, 573 const SSLConfig& server_ssl_config,
(...skipping 25 matching lines...) Expand all
514 HostPortPair alternative_destination(alternative_service.host_port_pair()); 599 HostPortPair alternative_destination(alternative_service.host_port_pair());
515 ignore_result( 600 ignore_result(
516 ApplyHostMappingRules(request_info.url, &alternative_destination)); 601 ApplyHostMappingRules(request_info.url, &alternative_destination));
517 602
518 alternative_job_.reset(job_factory_->CreateJob( 603 alternative_job_.reset(job_factory_->CreateJob(
519 this, ALTERNATIVE, session_, request_info, priority, server_ssl_config, 604 this, ALTERNATIVE, session_, request_info, priority, server_ssl_config,
520 proxy_ssl_config, alternative_destination, origin_url, 605 proxy_ssl_config, alternative_destination, origin_url,
521 alternative_service, net_log.net_log())); 606 alternative_service, net_log.net_log()));
522 AttachJob(alternative_job_.get()); 607 AttachJob(alternative_job_.get());
523 608
524 main_job_->WaitFor(alternative_job_.get()); 609 main_job_is_blocked_ = true;
525 // Make sure to wait until we call WaitFor(), before starting
526 // |alternative_job|, otherwise |alternative_job| will not notify |job|
527 // appropriately.
528 alternative_job_->Start(request_->stream_type()); 610 alternative_job_->Start(request_->stream_type());
529 } 611 }
530 // Even if |alternative_job| has already finished, it will not have notified 612 // Even if |alternative_job| has already finished, it will not have notified
531 // the request yet, since we defer that to the next iteration of the 613 // the request yet, since we defer that to the next iteration of the
532 // MessageLoop, so starting |main_job_| is always safe. 614 // MessageLoop, so starting |main_job_| is always safe.
533 main_job_->Start(request_->stream_type()); 615 main_job_->Start(request_->stream_type());
534 } 616 }
535 617
536 void HttpStreamFactoryImpl::JobController::AttachJob(Job* job) { 618 void HttpStreamFactoryImpl::JobController::AttachJob(Job* job) {
537 DCHECK(job); 619 DCHECK(job);
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 first_alternative_service = alternative_service; 894 first_alternative_service = alternative_service;
813 } 895 }
814 896
815 // Ask delegate to mark QUIC as broken for the origin. 897 // Ask delegate to mark QUIC as broken for the origin.
816 if (quic_advertised && quic_all_broken && delegate != nullptr) 898 if (quic_advertised && quic_all_broken && delegate != nullptr)
817 delegate->OnQuicBroken(); 899 delegate->OnQuicBroken();
818 900
819 return first_alternative_service; 901 return first_alternative_service;
820 } 902 }
821 } 903 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698