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

Side by Side Diff: webkit/browser/appcache/appcache_update_job.cc

Issue 207163002: more uma stats (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "webkit/browser/appcache/appcache_update_job.h" 5 #include "webkit/browser/appcache/appcache_update_job.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 net::LOAD_DISABLE_INTERCEPT); 124 net::LOAD_DISABLE_INTERCEPT);
125 if (existing_response_headers_.get()) 125 if (existing_response_headers_.get())
126 AddConditionalHeaders(existing_response_headers_.get()); 126 AddConditionalHeaders(existing_response_headers_.get());
127 request_->Start(); 127 request_->Start();
128 } 128 }
129 129
130 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( 130 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect(
131 net::URLRequest* request, const GURL& new_url, bool* defer_redirect) { 131 net::URLRequest* request, const GURL& new_url, bool* defer_redirect) {
132 DCHECK(request_ == request); 132 DCHECK(request_ == request);
133 // Redirect is not allowed by the update process. 133 // Redirect is not allowed by the update process.
134 job_->MadeProgress();
134 request->Cancel(); 135 request->Cancel();
135 result_ = REDIRECT_ERROR; 136 result_ = REDIRECT_ERROR;
136 OnResponseCompleted(); 137 OnResponseCompleted();
137 } 138 }
138 139
139 void AppCacheUpdateJob::URLFetcher::OnResponseStarted( 140 void AppCacheUpdateJob::URLFetcher::OnResponseStarted(
140 net::URLRequest *request) { 141 net::URLRequest *request) {
141 DCHECK(request == request_); 142 DCHECK(request == request_);
142 int response_code = -1; 143 int response_code = -1;
143 if (request->status().is_success()) 144 if (request->status().is_success()) {
144 response_code = request->GetResponseCode(); 145 response_code = request->GetResponseCode();
146 job_->MadeProgress();
147 }
145 if ((response_code / 100) == 2) { 148 if ((response_code / 100) == 2) {
146 149
147 // See http://code.google.com/p/chromium/issues/detail?id=69594 150 // See http://code.google.com/p/chromium/issues/detail?id=69594
148 // We willfully violate the HTML5 spec at this point in order 151 // We willfully violate the HTML5 spec at this point in order
149 // to support the appcaching of cross-origin HTTPS resources. 152 // to support the appcaching of cross-origin HTTPS resources.
150 // We've opted for a milder constraint and allow caching unless 153 // We've opted for a milder constraint and allow caching unless
151 // the resource has a "no-store" header. A spec change has been 154 // the resource has a "no-store" header. A spec change has been
152 // requested on the whatwg list. 155 // requested on the whatwg list.
153 // TODO(michaeln): Consider doing this for cross-origin HTTP resources too. 156 // TODO(michaeln): Consider doing this for cross-origin HTTP resources too.
154 if (url_.SchemeIsSecure() && 157 if (url_.SchemeIsSecure() &&
(...skipping 27 matching lines...) Expand all
182 result_ = NETWORK_ERROR; 185 result_ = NETWORK_ERROR;
183 OnResponseCompleted(); 186 OnResponseCompleted();
184 } 187 }
185 } 188 }
186 189
187 void AppCacheUpdateJob::URLFetcher::OnReadCompleted( 190 void AppCacheUpdateJob::URLFetcher::OnReadCompleted(
188 net::URLRequest* request, int bytes_read) { 191 net::URLRequest* request, int bytes_read) {
189 DCHECK(request_ == request); 192 DCHECK(request_ == request);
190 bool data_consumed = true; 193 bool data_consumed = true;
191 if (request->status().is_success() && bytes_read > 0) { 194 if (request->status().is_success() && bytes_read > 0) {
195 job_->MadeProgress();
192 data_consumed = ConsumeResponseData(bytes_read); 196 data_consumed = ConsumeResponseData(bytes_read);
193 if (data_consumed) { 197 if (data_consumed) {
194 bytes_read = 0; 198 bytes_read = 0;
195 while (request->Read(buffer_.get(), kBufferSize, &bytes_read)) { 199 while (request->Read(buffer_.get(), kBufferSize, &bytes_read)) {
196 if (bytes_read > 0) { 200 if (bytes_read > 0) {
197 data_consumed = ConsumeResponseData(bytes_read); 201 data_consumed = ConsumeResponseData(bytes_read);
198 if (!data_consumed) 202 if (!data_consumed)
199 break; // wait for async data processing, then read more 203 break; // wait for async data processing, then read more
200 } else { 204 } else {
201 break; 205 break;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 bytes_read, 276 bytes_read,
273 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); 277 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this)));
274 return false; // wait for async write completion to continue reading 278 return false; // wait for async write completion to continue reading
275 default: 279 default:
276 NOTREACHED(); 280 NOTREACHED();
277 } 281 }
278 return true; 282 return true;
279 } 283 }
280 284
281 void AppCacheUpdateJob::URLFetcher::OnResponseCompleted() { 285 void AppCacheUpdateJob::URLFetcher::OnResponseCompleted() {
286 if (request_->status().is_success())
287 job_->MadeProgress();
288
282 // Retry for 503s where retry-after is 0. 289 // Retry for 503s where retry-after is 0.
283 if (request_->status().is_success() && 290 if (request_->status().is_success() &&
284 request_->GetResponseCode() == 503 && 291 request_->GetResponseCode() == 503 &&
285 MaybeRetryRequest()) { 292 MaybeRetryRequest()) {
286 return; 293 return;
287 } 294 }
288 295
289 switch (fetch_type_) { 296 switch (fetch_type_) {
290 case MANIFEST_FETCH: 297 case MANIFEST_FETCH:
291 job_->HandleManifestFetchCompleted(this); 298 job_->HandleManifestFetchCompleted(this);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 // Add to fetch list or an existing entry if already fetched. 394 // Add to fetch list or an existing entry if already fetched.
388 if (!new_master_resource.is_empty()) { 395 if (!new_master_resource.is_empty()) {
389 AddMasterEntryToFetchList(host, new_master_resource, 396 AddMasterEntryToFetchList(host, new_master_resource,
390 is_new_pending_master_entry); 397 is_new_pending_master_entry);
391 } 398 }
392 } 399 }
393 return; 400 return;
394 } 401 }
395 402
396 // Begin update process for the group. 403 // Begin update process for the group.
404 MadeProgress();
397 group_->SetUpdateStatus(AppCacheGroup::CHECKING); 405 group_->SetUpdateStatus(AppCacheGroup::CHECKING);
398 if (group_->HasCache()) { 406 if (group_->HasCache()) {
399 update_type_ = UPGRADE_ATTEMPT; 407 update_type_ = UPGRADE_ATTEMPT;
400 NotifyAllAssociatedHosts(CHECKING_EVENT); 408 NotifyAllAssociatedHosts(CHECKING_EVENT);
401 } else { 409 } else {
402 update_type_ = CACHE_ATTEMPT; 410 update_type_ = CACHE_ATTEMPT;
403 DCHECK(host); 411 DCHECK(host);
404 NotifySingleHost(host, CHECKING_EVENT); 412 NotifySingleHost(host, CHECKING_EVENT);
405 } 413 }
406 414
407 if (!new_master_resource.is_empty()) { 415 if (!new_master_resource.is_empty()) {
408 AddMasterEntryToFetchList(host, new_master_resource, 416 AddMasterEntryToFetchList(host, new_master_resource,
409 is_new_pending_master_entry); 417 is_new_pending_master_entry);
410 } 418 }
411 419
412 FetchManifest(true); 420 FetchManifest(true);
413 } 421 }
414 422
415 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { 423 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() {
416 AppCacheResponseWriter* writer = 424 AppCacheResponseWriter* writer =
417 storage_->CreateResponseWriter(manifest_url_, 425 storage_->CreateResponseWriter(manifest_url_,
418 group_->group_id()); 426 group_->group_id());
419 stored_response_ids_.push_back(writer->response_id()); 427 stored_response_ids_.push_back(writer->response_id());
420 return writer; 428 return writer;
421 } 429 }
422 430
423 void AppCacheUpdateJob::HandleCacheFailure( 431 void AppCacheUpdateJob::HandleCacheFailure(
424 const std::string& error_message, 432 const std::string& error_message,
425 ResultType result) { 433 ResultType result,
434 const GURL& failed_resource_url) {
426 // 6.9.4 cache failure steps 2-8. 435 // 6.9.4 cache failure steps 2-8.
427 DCHECK(internal_state_ != CACHE_FAILURE); 436 DCHECK(internal_state_ != CACHE_FAILURE);
428 DCHECK(!error_message.empty()); 437 DCHECK(!error_message.empty());
429 DCHECK(result != UPDATE_OK); 438 DCHECK(result != UPDATE_OK);
430 internal_state_ = CACHE_FAILURE; 439 internal_state_ = CACHE_FAILURE;
440 LogHistogramStats(result, failed_resource_url);
431 CancelAllUrlFetches(); 441 CancelAllUrlFetches();
432 CancelAllMasterEntryFetches(error_message); 442 CancelAllMasterEntryFetches(error_message);
433 NotifyAllError(error_message); 443 NotifyAllError(error_message);
434 DiscardInprogressCache(); 444 DiscardInprogressCache();
435 internal_state_ = COMPLETED; 445 internal_state_ = COMPLETED;
436 AppCacheHistograms::CountUpdateJobResult(
437 result, manifest_url_.GetOrigin());
438 DeleteSoon(); // To unwind the stack prior to deletion. 446 DeleteSoon(); // To unwind the stack prior to deletion.
439 } 447 }
440 448
441 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) { 449 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) {
442 DCHECK(!manifest_fetcher_); 450 DCHECK(!manifest_fetcher_);
443 manifest_fetcher_ = new URLFetcher( 451 manifest_fetcher_ = new URLFetcher(
444 manifest_url_, 452 manifest_url_,
445 is_first_fetch ? URLFetcher::MANIFEST_FETCH : 453 is_first_fetch ? URLFetcher::MANIFEST_FETCH :
446 URLFetcher::MANIFEST_REFETCH, 454 URLFetcher::MANIFEST_REFETCH,
447 this); 455 this);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 ContinueHandleManifestFetchCompleted(true); 499 ContinueHandleManifestFetchCompleted(true);
492 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) { 500 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) {
493 ContinueHandleManifestFetchCompleted(false); 501 ContinueHandleManifestFetchCompleted(false);
494 } else if ((response_code == 404 || response_code == 410) && 502 } else if ((response_code == 404 || response_code == 410) &&
495 update_type_ == UPGRADE_ATTEMPT) { 503 update_type_ == UPGRADE_ATTEMPT) {
496 storage_->MakeGroupObsolete(group_, this); // async 504 storage_->MakeGroupObsolete(group_, this); // async
497 } else { 505 } else {
498 const char* kFormatString = "Manifest fetch failed (%d) %s"; 506 const char* kFormatString = "Manifest fetch failed (%d) %s";
499 std::string message = FormatUrlErrorMessage( 507 std::string message = FormatUrlErrorMessage(
500 kFormatString, manifest_url_, fetcher->result(), response_code); 508 kFormatString, manifest_url_, fetcher->result(), response_code);
501 HandleCacheFailure(message, fetcher->result()); 509 HandleCacheFailure(message, fetcher->result(), GURL());
502 } 510 }
503 } 511 }
504 512
505 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, 513 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group,
506 bool success) { 514 bool success) {
507 DCHECK(master_entry_fetches_.empty()); 515 DCHECK(master_entry_fetches_.empty());
508 CancelAllMasterEntryFetches("The cache has been made obsolete, " 516 CancelAllMasterEntryFetches("The cache has been made obsolete, "
509 "the manifest file returned 404 or 410"); 517 "the manifest file returned 404 or 410");
510 if (success) { 518 if (success) {
511 DCHECK(group->is_obsolete()); 519 DCHECK(group->is_obsolete());
512 NotifyAllAssociatedHosts(OBSOLETE_EVENT); 520 NotifyAllAssociatedHosts(OBSOLETE_EVENT);
513 internal_state_ = COMPLETED; 521 internal_state_ = COMPLETED;
514 MaybeCompleteUpdate(); 522 MaybeCompleteUpdate();
515 } else { 523 } else {
516 // Treat failure to mark group obsolete as a cache failure. 524 // Treat failure to mark group obsolete as a cache failure.
517 HandleCacheFailure("Failed to mark the cache as obsolete", DB_ERROR); 525 HandleCacheFailure("Failed to mark the cache as obsolete",
526 DB_ERROR, GURL());
518 } 527 }
519 } 528 }
520 529
521 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) { 530 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) {
522 DCHECK(internal_state_ == FETCH_MANIFEST); 531 DCHECK(internal_state_ == FETCH_MANIFEST);
523 532
524 if (!changed) { 533 if (!changed) {
525 DCHECK(update_type_ == UPGRADE_ATTEMPT); 534 DCHECK(update_type_ == UPGRADE_ATTEMPT);
526 internal_state_ = NO_UPDATE; 535 internal_state_ = NO_UPDATE;
527 536
528 // Wait for pending master entries to download. 537 // Wait for pending master entries to download.
529 FetchMasterEntries(); 538 FetchMasterEntries();
530 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps 539 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps
531 return; 540 return;
532 } 541 }
533 542
534 Manifest manifest; 543 Manifest manifest;
535 if (!ParseManifest(manifest_url_, manifest_data_.data(), 544 if (!ParseManifest(manifest_url_, manifest_data_.data(),
536 manifest_data_.length(), manifest)) { 545 manifest_data_.length(), manifest)) {
537 const char* kFormatString = "Failed to parse manifest %s"; 546 const char* kFormatString = "Failed to parse manifest %s";
538 const std::string message = base::StringPrintf(kFormatString, 547 const std::string message = base::StringPrintf(kFormatString,
539 manifest_url_.spec().c_str()); 548 manifest_url_.spec().c_str());
540 HandleCacheFailure(message, MANIFEST_ERROR); 549 HandleCacheFailure(message, MANIFEST_ERROR, GURL());
541 VLOG(1) << message; 550 VLOG(1) << message;
542 return; 551 return;
543 } 552 }
544 553
545 // Proceed with update process. Section 6.9.4 steps 8-20. 554 // Proceed with update process. Section 6.9.4 steps 8-20.
546 internal_state_ = DOWNLOADING; 555 internal_state_ = DOWNLOADING;
547 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); 556 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId());
548 BuildUrlFileList(manifest); 557 BuildUrlFileList(manifest);
549 inprogress_cache_->InitializeWithManifest(&manifest); 558 inprogress_cache_->InitializeWithManifest(&manifest);
550 559
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) { 613 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) {
605 if (response_code == 304 && fetcher->existing_entry().has_response_id()) { 614 if (response_code == 304 && fetcher->existing_entry().has_response_id()) {
606 // Keep the existing response. 615 // Keep the existing response.
607 entry.set_response_id(fetcher->existing_entry().response_id()); 616 entry.set_response_id(fetcher->existing_entry().response_id());
608 entry.set_response_size(fetcher->existing_entry().response_size()); 617 entry.set_response_size(fetcher->existing_entry().response_size());
609 inprogress_cache_->AddOrModifyEntry(url, entry); 618 inprogress_cache_->AddOrModifyEntry(url, entry);
610 } else { 619 } else {
611 const char* kFormatString = "Resource fetch failed (%d) %s"; 620 const char* kFormatString = "Resource fetch failed (%d) %s";
612 std::string message = FormatUrlErrorMessage( 621 std::string message = FormatUrlErrorMessage(
613 kFormatString, url, fetcher->result(), response_code); 622 kFormatString, url, fetcher->result(), response_code);
614 HandleCacheFailure(message, fetcher->result()); 623 HandleCacheFailure(message, fetcher->result(), url);
615 return; 624 return;
616 } 625 }
617 } else if (response_code == 404 || response_code == 410) { 626 } else if (response_code == 404 || response_code == 410) {
618 // Entry is skipped. They are dropped from the cache. 627 // Entry is skipped. They are dropped from the cache.
619 } else if (update_type_ == UPGRADE_ATTEMPT && 628 } else if (update_type_ == UPGRADE_ATTEMPT &&
620 fetcher->existing_entry().has_response_id()) { 629 fetcher->existing_entry().has_response_id()) {
621 // Keep the existing response. 630 // Keep the existing response.
622 // TODO(michaeln): Not sure this is a good idea. This is spec compliant 631 // TODO(michaeln): Not sure this is a good idea. This is spec compliant
623 // but the old resource may or may not be compatible with the new contents 632 // but the old resource may or may not be compatible with the new contents
624 // of the cache. Impossible to know one way or the other. 633 // of the cache. Impossible to know one way or the other.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 709
701 // In downloading case, update result is different if all master entries 710 // In downloading case, update result is different if all master entries
702 // failed vs. only some failing. 711 // failed vs. only some failing.
703 if (inprogress_cache_.get()) { 712 if (inprogress_cache_.get()) {
704 // Only count successful downloads to know if all master entries failed. 713 // Only count successful downloads to know if all master entries failed.
705 pending_master_entries_.erase(found); 714 pending_master_entries_.erase(found);
706 --master_entries_completed_; 715 --master_entries_completed_;
707 716
708 // Section 6.9.4, step 22.3. 717 // Section 6.9.4, step 22.3.
709 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { 718 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) {
710 HandleCacheFailure(message, fetcher->result()); 719 HandleCacheFailure(message, fetcher->result(), GURL());
711 return; 720 return;
712 } 721 }
713 } 722 }
714 } 723 }
715 724
716 DCHECK(internal_state_ != CACHE_FAILURE); 725 DCHECK(internal_state_ != CACHE_FAILURE);
717 FetchMasterEntries(); 726 FetchMasterEntries();
718 MaybeCompleteUpdate(); 727 MaybeCompleteUpdate();
719 } 728 }
720 729
(...skipping 21 matching lines...) Expand all
742 io_buffer.get(), 751 io_buffer.get(),
743 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, 752 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete,
744 base::Unretained(this))); 753 base::Unretained(this)));
745 } 754 }
746 } else { 755 } else {
747 VLOG(1) << "Request status: " << request->status().status() 756 VLOG(1) << "Request status: " << request->status().status()
748 << " error: " << request->status().error() 757 << " error: " << request->status().error()
749 << " response code: " << response_code; 758 << " response code: " << response_code;
750 ScheduleUpdateRetry(kRerunDelayMs); 759 ScheduleUpdateRetry(kRerunDelayMs);
751 if (response_code == 200) { 760 if (response_code == 200) {
752 HandleCacheFailure("Manifest changed during update", MANIFEST_ERROR); 761 HandleCacheFailure(
762 "Manifest changed during update", MANIFEST_ERROR, GURL());
753 } else { 763 } else {
754 const char* kFormatString = "Manifest re-fetch failed (%d) %s"; 764 const char* kFormatString = "Manifest re-fetch failed (%d) %s";
755 std::string message = FormatUrlErrorMessage( 765 std::string message = FormatUrlErrorMessage(
756 kFormatString, manifest_url_, fetcher->result(), response_code); 766 kFormatString, manifest_url_, fetcher->result(), response_code);
757 HandleCacheFailure(message, fetcher->result()); 767 HandleCacheFailure(message, fetcher->result(), GURL());
758 } 768 }
759 } 769 }
760 } 770 }
761 771
762 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { 772 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) {
763 if (result > 0) { 773 if (result > 0) {
764 scoped_refptr<net::StringIOBuffer> io_buffer( 774 scoped_refptr<net::StringIOBuffer> io_buffer(
765 new net::StringIOBuffer(manifest_data_)); 775 new net::StringIOBuffer(manifest_data_));
766 manifest_response_writer_->WriteData( 776 manifest_response_writer_->WriteData(
767 io_buffer.get(), 777 io_buffer.get(),
768 manifest_data_.length(), 778 manifest_data_.length(),
769 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, 779 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete,
770 base::Unretained(this))); 780 base::Unretained(this)));
771 } else { 781 } else {
772 HandleCacheFailure("Failed to write the manifest headers to storage", 782 HandleCacheFailure("Failed to write the manifest headers to storage",
773 DISKCACHE_ERROR); 783 DISKCACHE_ERROR, GURL());
774 } 784 }
775 } 785 }
776 786
777 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { 787 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) {
778 if (result > 0) { 788 if (result > 0) {
779 AppCacheEntry entry(AppCacheEntry::MANIFEST, 789 AppCacheEntry entry(AppCacheEntry::MANIFEST,
780 manifest_response_writer_->response_id(), 790 manifest_response_writer_->response_id(),
781 manifest_response_writer_->amount_written()); 791 manifest_response_writer_->amount_written());
782 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry)) 792 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry))
783 duplicate_response_ids_.push_back(entry.response_id()); 793 duplicate_response_ids_.push_back(entry.response_id());
784 StoreGroupAndCache(); 794 StoreGroupAndCache();
785 } else { 795 } else {
786 HandleCacheFailure("Failed to write the manifest data to storage", 796 HandleCacheFailure("Failed to write the manifest data to storage",
787 DISKCACHE_ERROR); 797 DISKCACHE_ERROR, GURL());
788 } 798 }
789 } 799 }
790 800
791 void AppCacheUpdateJob::StoreGroupAndCache() { 801 void AppCacheUpdateJob::StoreGroupAndCache() {
792 DCHECK(stored_state_ == UNSTORED); 802 DCHECK(stored_state_ == UNSTORED);
793 stored_state_ = STORING; 803 stored_state_ = STORING;
794 scoped_refptr<AppCache> newest_cache; 804 scoped_refptr<AppCache> newest_cache;
795 if (inprogress_cache_.get()) 805 if (inprogress_cache_.get())
796 newest_cache.swap(inprogress_cache_); 806 newest_cache.swap(inprogress_cache_);
797 else 807 else
(...skipping 20 matching lines...) Expand all
818 // and the proper cleanup to occur. 828 // and the proper cleanup to occur.
819 if (newest_cache != group->newest_complete_cache()) 829 if (newest_cache != group->newest_complete_cache())
820 inprogress_cache_ = newest_cache; 830 inprogress_cache_ = newest_cache;
821 831
822 ResultType result = DB_ERROR; 832 ResultType result = DB_ERROR;
823 std::string message("Failed to commit new cache to storage"); 833 std::string message("Failed to commit new cache to storage");
824 if (would_exceed_quota) { 834 if (would_exceed_quota) {
825 message.append(", would exceed quota"); 835 message.append(", would exceed quota");
826 result = QUOTA_ERROR; 836 result = QUOTA_ERROR;
827 } 837 }
828 HandleCacheFailure(message, result); 838 HandleCacheFailure(message, result, GURL());
829 } 839 }
830 } 840 }
831 841
832 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host, 842 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host,
833 EventID event_id) { 843 EventID event_id) {
834 std::vector<int> ids(1, host->host_id()); 844 std::vector<int> ids(1, host->host_id());
835 host->frontend()->OnEventRaised(ids, event_id); 845 host->frontend()->OnEventRaised(ids, event_id);
836 } 846 }
837 847
838 void AppCacheUpdateJob::NotifyAllAssociatedHosts(EventID event_id) { 848 void AppCacheUpdateJob::NotifyAllAssociatedHosts(EventID event_id) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 AppCacheEntry* entry = NULL; 914 AppCacheEntry* entry = NULL;
905 if (group_->newest_complete_cache()) 915 if (group_->newest_complete_cache())
906 entry = group_->newest_complete_cache()->GetEntry(manifest_url_); 916 entry = group_->newest_complete_cache()->GetEntry(manifest_url_);
907 if (!entry) { 917 if (!entry) {
908 // TODO(michaeln): This is just a bandaid to avoid a crash. 918 // TODO(michaeln): This is just a bandaid to avoid a crash.
909 // http://code.google.com/p/chromium/issues/detail?id=95101 919 // http://code.google.com/p/chromium/issues/detail?id=95101
910 if (service_->storage() == storage_) { 920 if (service_->storage() == storage_) {
911 // Use a local variable because service_ is reset in HandleCacheFailure. 921 // Use a local variable because service_ is reset in HandleCacheFailure.
912 AppCacheService* service = service_; 922 AppCacheService* service = service_;
913 HandleCacheFailure("Manifest entry not found in existing cache", 923 HandleCacheFailure("Manifest entry not found in existing cache",
914 DB_ERROR); 924 DB_ERROR, GURL());
915 AppCacheHistograms::AddMissingManifestEntrySample(); 925 AppCacheHistograms::AddMissingManifestEntrySample();
916 service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); 926 service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback());
917 } 927 }
918 return; 928 return;
919 } 929 }
920 930
921 // Load manifest data from storage to compare against fetched manifest. 931 // Load manifest data from storage to compare against fetched manifest.
922 manifest_response_reader_.reset( 932 manifest_response_reader_.reset(
923 storage_->CreateResponseReader(manifest_url_, 933 storage_->CreateResponseReader(manifest_url_,
924 group_->group_id(), 934 group_->group_id(),
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 break; 1318 break;
1309 case REFETCH_MANIFEST: 1319 case REFETCH_MANIFEST:
1310 DCHECK(stored_state_ == STORED); 1320 DCHECK(stored_state_ == STORED);
1311 NotifyAllFinalProgress(); 1321 NotifyAllFinalProgress();
1312 if (update_type_ == CACHE_ATTEMPT) 1322 if (update_type_ == CACHE_ATTEMPT)
1313 NotifyAllAssociatedHosts(CACHED_EVENT); 1323 NotifyAllAssociatedHosts(CACHED_EVENT);
1314 else 1324 else
1315 NotifyAllAssociatedHosts(UPDATE_READY_EVENT); 1325 NotifyAllAssociatedHosts(UPDATE_READY_EVENT);
1316 DiscardDuplicateResponses(); 1326 DiscardDuplicateResponses();
1317 internal_state_ = COMPLETED; 1327 internal_state_ = COMPLETED;
1318 AppCacheHistograms::CountUpdateJobResult( 1328 LogHistogramStats(UPDATE_OK, GURL());
1319 UPDATE_OK, manifest_url_.GetOrigin());
1320 break; 1329 break;
1321 case CACHE_FAILURE: 1330 case CACHE_FAILURE:
1322 NOTREACHED(); // See HandleCacheFailure 1331 NOTREACHED(); // See HandleCacheFailure
1323 break; 1332 break;
1324 default: 1333 default:
1325 break; 1334 break;
1326 } 1335 }
1327 1336
1328 // Let the stack unwind before deletion to make it less risky as this 1337 // Let the stack unwind before deletion to make it less risky as this
1329 // method is called from multiple places in this file. 1338 // method is called from multiple places in this file.
1330 if (internal_state_ == COMPLETED) 1339 if (internal_state_ == COMPLETED)
1331 DeleteSoon(); 1340 DeleteSoon();
1332 } 1341 }
1333 1342
1334 void AppCacheUpdateJob::ScheduleUpdateRetry(int delay_ms) { 1343 void AppCacheUpdateJob::ScheduleUpdateRetry(int delay_ms) {
1335 // TODO(jennb): post a delayed task with the "same parameters" as this job 1344 // TODO(jennb): post a delayed task with the "same parameters" as this job
1336 // to retry the update at a later time. Need group, URLs of pending master 1345 // to retry the update at a later time. Need group, URLs of pending master
1337 // entries and their hosts. 1346 // entries and their hosts.
1338 } 1347 }
1339 1348
1340 void AppCacheUpdateJob::Cancel() { 1349 void AppCacheUpdateJob::Cancel() {
1341 internal_state_ = CANCELLED; 1350 internal_state_ = CANCELLED;
1342 1351
1352 LogHistogramStats(CANCELLED_ERROR, GURL());
1353
1343 if (manifest_fetcher_) { 1354 if (manifest_fetcher_) {
1344 delete manifest_fetcher_; 1355 delete manifest_fetcher_;
1345 manifest_fetcher_ = NULL; 1356 manifest_fetcher_ = NULL;
1346 } 1357 }
1347 1358
1348 for (PendingUrlFetches::iterator it = pending_url_fetches_.begin(); 1359 for (PendingUrlFetches::iterator it = pending_url_fetches_.begin();
1349 it != pending_url_fetches_.end(); ++it) { 1360 it != pending_url_fetches_.end(); ++it) {
1350 delete it->second; 1361 delete it->second;
1351 } 1362 }
1352 pending_url_fetches_.clear(); 1363 pending_url_fetches_.clear();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 (*hosts.begin())->AssociateNoCache(GURL()); 1420 (*hosts.begin())->AssociateNoCache(GURL());
1410 1421
1411 inprogress_cache_ = NULL; 1422 inprogress_cache_ = NULL;
1412 added_master_entries_.clear(); 1423 added_master_entries_.clear();
1413 } 1424 }
1414 1425
1415 void AppCacheUpdateJob::DiscardDuplicateResponses() { 1426 void AppCacheUpdateJob::DiscardDuplicateResponses() {
1416 storage_->DoomResponses(manifest_url_, duplicate_response_ids_); 1427 storage_->DoomResponses(manifest_url_, duplicate_response_ids_);
1417 } 1428 }
1418 1429
1430 void AppCacheUpdateJob::LogHistogramStats(
1431 ResultType result, const GURL& failed_resource_url) {
1432 AppCacheHistograms::CountUpdateJobResult(result, manifest_url_.GetOrigin());
1433 if (result == UPDATE_OK)
1434 return;
1435
1436 int percent_complete = 0;
1437 if (url_file_list_.size() > 0) {
1438 size_t actual_fetches_completed = url_fetches_completed_;
1439 if (!failed_resource_url.is_empty() && actual_fetches_completed)
1440 --actual_fetches_completed;
1441 percent_complete = (static_cast<double>(actual_fetches_completed) /
1442 static_cast<double>(url_file_list_.size())) * 100.0;
1443 percent_complete = std::min(percent_complete, 99);
1444 }
1445
1446 bool was_making_progress =
1447 base::Time::Now() - last_progress_time_ <
1448 base::TimeDelta::FromMinutes(5);
1449
1450 bool off_origin_resource_failure =
1451 !failed_resource_url.is_empty() &&
1452 (failed_resource_url.GetOrigin() != manifest_url_.GetOrigin());
1453
1454 AppCacheHistograms::LogUpdateFailureStats(
1455 manifest_url_.GetOrigin(),
1456 percent_complete,
1457 was_making_progress,
1458 off_origin_resource_failure);
1459 }
1460
1419 void AppCacheUpdateJob::DeleteSoon() { 1461 void AppCacheUpdateJob::DeleteSoon() {
1420 ClearPendingMasterEntries(); 1462 ClearPendingMasterEntries();
1421 manifest_response_writer_.reset(); 1463 manifest_response_writer_.reset();
1422 storage_->CancelDelegateCallbacks(this); 1464 storage_->CancelDelegateCallbacks(this);
1423 service_->RemoveObserver(this); 1465 service_->RemoveObserver(this);
1424 service_ = NULL; 1466 service_ = NULL;
1425 1467
1426 // Break the connection with the group so the group cannot call delete 1468 // Break the connection with the group so the group cannot call delete
1427 // on this object after we've posted a task to delete ourselves. 1469 // on this object after we've posted a task to delete ourselves.
1428 group_->SetUpdateStatus(AppCacheGroup::IDLE); 1470 group_->SetUpdateStatus(AppCacheGroup::IDLE);
1429 group_ = NULL; 1471 group_ = NULL;
1430 1472
1431 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 1473 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1432 } 1474 }
1433 1475
1434 } // namespace appcache 1476 } // namespace appcache
OLDNEW
« no previous file with comments | « webkit/browser/appcache/appcache_update_job.h ('k') | webkit/browser/appcache/appcache_url_request_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698