| Index: webkit/browser/appcache/appcache_update_job.cc
|
| diff --git a/webkit/browser/appcache/appcache_update_job.cc b/webkit/browser/appcache/appcache_update_job.cc
|
| index 253aee77e45caf465c9cbc3ed644a2466d004968..33a68b04a89f75b6506f6ebe61fce68d9dc89186 100644
|
| --- a/webkit/browser/appcache/appcache_update_job.cc
|
| +++ b/webkit/browser/appcache/appcache_update_job.cc
|
| @@ -131,6 +131,7 @@ void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect(
|
| net::URLRequest* request, const GURL& new_url, bool* defer_redirect) {
|
| DCHECK(request_ == request);
|
| // Redirect is not allowed by the update process.
|
| + job_->MadeProgress();
|
| request->Cancel();
|
| result_ = REDIRECT_ERROR;
|
| OnResponseCompleted();
|
| @@ -140,8 +141,10 @@ void AppCacheUpdateJob::URLFetcher::OnResponseStarted(
|
| net::URLRequest *request) {
|
| DCHECK(request == request_);
|
| int response_code = -1;
|
| - if (request->status().is_success())
|
| + if (request->status().is_success()) {
|
| response_code = request->GetResponseCode();
|
| + job_->MadeProgress();
|
| + }
|
| if ((response_code / 100) == 2) {
|
|
|
| // See http://code.google.com/p/chromium/issues/detail?id=69594
|
| @@ -189,6 +192,7 @@ void AppCacheUpdateJob::URLFetcher::OnReadCompleted(
|
| DCHECK(request_ == request);
|
| bool data_consumed = true;
|
| if (request->status().is_success() && bytes_read > 0) {
|
| + job_->MadeProgress();
|
| data_consumed = ConsumeResponseData(bytes_read);
|
| if (data_consumed) {
|
| bytes_read = 0;
|
| @@ -279,6 +283,9 @@ bool AppCacheUpdateJob::URLFetcher::ConsumeResponseData(int bytes_read) {
|
| }
|
|
|
| void AppCacheUpdateJob::URLFetcher::OnResponseCompleted() {
|
| + if (request_->status().is_success())
|
| + job_->MadeProgress();
|
| +
|
| // Retry for 503s where retry-after is 0.
|
| if (request_->status().is_success() &&
|
| request_->GetResponseCode() == 503 &&
|
| @@ -394,6 +401,7 @@ void AppCacheUpdateJob::StartUpdate(AppCacheHost* host,
|
| }
|
|
|
| // Begin update process for the group.
|
| + MadeProgress();
|
| group_->SetUpdateStatus(AppCacheGroup::CHECKING);
|
| if (group_->HasCache()) {
|
| update_type_ = UPGRADE_ATTEMPT;
|
| @@ -422,19 +430,19 @@ AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() {
|
|
|
| void AppCacheUpdateJob::HandleCacheFailure(
|
| const std::string& error_message,
|
| - ResultType result) {
|
| + ResultType result,
|
| + const GURL& failed_resource_url) {
|
| // 6.9.4 cache failure steps 2-8.
|
| DCHECK(internal_state_ != CACHE_FAILURE);
|
| DCHECK(!error_message.empty());
|
| DCHECK(result != UPDATE_OK);
|
| internal_state_ = CACHE_FAILURE;
|
| + LogHistogramStats(result, failed_resource_url);
|
| CancelAllUrlFetches();
|
| CancelAllMasterEntryFetches(error_message);
|
| NotifyAllError(error_message);
|
| DiscardInprogressCache();
|
| internal_state_ = COMPLETED;
|
| - AppCacheHistograms::CountUpdateJobResult(
|
| - result, manifest_url_.GetOrigin());
|
| DeleteSoon(); // To unwind the stack prior to deletion.
|
| }
|
|
|
| @@ -498,7 +506,7 @@ void AppCacheUpdateJob::HandleManifestFetchCompleted(
|
| const char* kFormatString = "Manifest fetch failed (%d) %s";
|
| std::string message = FormatUrlErrorMessage(
|
| kFormatString, manifest_url_, fetcher->result(), response_code);
|
| - HandleCacheFailure(message, fetcher->result());
|
| + HandleCacheFailure(message, fetcher->result(), GURL());
|
| }
|
| }
|
|
|
| @@ -514,7 +522,8 @@ void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group,
|
| MaybeCompleteUpdate();
|
| } else {
|
| // Treat failure to mark group obsolete as a cache failure.
|
| - HandleCacheFailure("Failed to mark the cache as obsolete", DB_ERROR);
|
| + HandleCacheFailure("Failed to mark the cache as obsolete",
|
| + DB_ERROR, GURL());
|
| }
|
| }
|
|
|
| @@ -537,7 +546,7 @@ void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) {
|
| const char* kFormatString = "Failed to parse manifest %s";
|
| const std::string message = base::StringPrintf(kFormatString,
|
| manifest_url_.spec().c_str());
|
| - HandleCacheFailure(message, MANIFEST_ERROR);
|
| + HandleCacheFailure(message, MANIFEST_ERROR, GURL());
|
| VLOG(1) << message;
|
| return;
|
| }
|
| @@ -611,7 +620,7 @@ void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) {
|
| const char* kFormatString = "Resource fetch failed (%d) %s";
|
| std::string message = FormatUrlErrorMessage(
|
| kFormatString, url, fetcher->result(), response_code);
|
| - HandleCacheFailure(message, fetcher->result());
|
| + HandleCacheFailure(message, fetcher->result(), url);
|
| return;
|
| }
|
| } else if (response_code == 404 || response_code == 410) {
|
| @@ -707,7 +716,7 @@ void AppCacheUpdateJob::HandleMasterEntryFetchCompleted(
|
|
|
| // Section 6.9.4, step 22.3.
|
| if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) {
|
| - HandleCacheFailure(message, fetcher->result());
|
| + HandleCacheFailure(message, fetcher->result(), GURL());
|
| return;
|
| }
|
| }
|
| @@ -749,12 +758,13 @@ void AppCacheUpdateJob::HandleManifestRefetchCompleted(
|
| << " response code: " << response_code;
|
| ScheduleUpdateRetry(kRerunDelayMs);
|
| if (response_code == 200) {
|
| - HandleCacheFailure("Manifest changed during update", MANIFEST_ERROR);
|
| + HandleCacheFailure(
|
| + "Manifest changed during update", MANIFEST_ERROR, GURL());
|
| } else {
|
| const char* kFormatString = "Manifest re-fetch failed (%d) %s";
|
| std::string message = FormatUrlErrorMessage(
|
| kFormatString, manifest_url_, fetcher->result(), response_code);
|
| - HandleCacheFailure(message, fetcher->result());
|
| + HandleCacheFailure(message, fetcher->result(), GURL());
|
| }
|
| }
|
| }
|
| @@ -770,7 +780,7 @@ void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) {
|
| base::Unretained(this)));
|
| } else {
|
| HandleCacheFailure("Failed to write the manifest headers to storage",
|
| - DISKCACHE_ERROR);
|
| + DISKCACHE_ERROR, GURL());
|
| }
|
| }
|
|
|
| @@ -784,7 +794,7 @@ void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) {
|
| StoreGroupAndCache();
|
| } else {
|
| HandleCacheFailure("Failed to write the manifest data to storage",
|
| - DISKCACHE_ERROR);
|
| + DISKCACHE_ERROR, GURL());
|
| }
|
| }
|
|
|
| @@ -825,7 +835,7 @@ void AppCacheUpdateJob::OnGroupAndNewestCacheStored(AppCacheGroup* group,
|
| message.append(", would exceed quota");
|
| result = QUOTA_ERROR;
|
| }
|
| - HandleCacheFailure(message, result);
|
| + HandleCacheFailure(message, result, GURL());
|
| }
|
| }
|
|
|
| @@ -911,7 +921,7 @@ void AppCacheUpdateJob::CheckIfManifestChanged() {
|
| // Use a local variable because service_ is reset in HandleCacheFailure.
|
| AppCacheService* service = service_;
|
| HandleCacheFailure("Manifest entry not found in existing cache",
|
| - DB_ERROR);
|
| + DB_ERROR, GURL());
|
| AppCacheHistograms::AddMissingManifestEntrySample();
|
| service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback());
|
| }
|
| @@ -1315,8 +1325,7 @@ void AppCacheUpdateJob::MaybeCompleteUpdate() {
|
| NotifyAllAssociatedHosts(UPDATE_READY_EVENT);
|
| DiscardDuplicateResponses();
|
| internal_state_ = COMPLETED;
|
| - AppCacheHistograms::CountUpdateJobResult(
|
| - UPDATE_OK, manifest_url_.GetOrigin());
|
| + LogHistogramStats(UPDATE_OK, GURL());
|
| break;
|
| case CACHE_FAILURE:
|
| NOTREACHED(); // See HandleCacheFailure
|
| @@ -1340,6 +1349,8 @@ void AppCacheUpdateJob::ScheduleUpdateRetry(int delay_ms) {
|
| void AppCacheUpdateJob::Cancel() {
|
| internal_state_ = CANCELLED;
|
|
|
| + LogHistogramStats(CANCELLED_ERROR, GURL());
|
| +
|
| if (manifest_fetcher_) {
|
| delete manifest_fetcher_;
|
| manifest_fetcher_ = NULL;
|
| @@ -1416,6 +1427,37 @@ void AppCacheUpdateJob::DiscardDuplicateResponses() {
|
| storage_->DoomResponses(manifest_url_, duplicate_response_ids_);
|
| }
|
|
|
| +void AppCacheUpdateJob::LogHistogramStats(
|
| + ResultType result, const GURL& failed_resource_url) {
|
| + AppCacheHistograms::CountUpdateJobResult(result, manifest_url_.GetOrigin());
|
| + if (result == UPDATE_OK)
|
| + return;
|
| +
|
| + int percent_complete = 0;
|
| + if (url_file_list_.size() > 0) {
|
| + size_t actual_fetches_completed = url_fetches_completed_;
|
| + if (!failed_resource_url.is_empty() && actual_fetches_completed)
|
| + --actual_fetches_completed;
|
| + percent_complete = (static_cast<double>(actual_fetches_completed) /
|
| + static_cast<double>(url_file_list_.size())) * 100.0;
|
| + percent_complete = std::min(percent_complete, 99);
|
| + }
|
| +
|
| + bool was_making_progress =
|
| + base::Time::Now() - last_progress_time_ <
|
| + base::TimeDelta::FromMinutes(5);
|
| +
|
| + bool off_origin_resource_failure =
|
| + !failed_resource_url.is_empty() &&
|
| + (failed_resource_url.GetOrigin() != manifest_url_.GetOrigin());
|
| +
|
| + AppCacheHistograms::LogUpdateFailureStats(
|
| + manifest_url_.GetOrigin(),
|
| + percent_complete,
|
| + was_making_progress,
|
| + off_origin_resource_failure);
|
| +}
|
| +
|
| void AppCacheUpdateJob::DeleteSoon() {
|
| ClearPendingMasterEntries();
|
| manifest_response_writer_.reset();
|
|
|