Index: chrome/browser/policy/cloud/external_policy_data_updater.cc |
diff --git a/chrome/browser/policy/cloud/external_policy_data_updater.cc b/chrome/browser/policy/cloud/external_policy_data_updater.cc |
deleted file mode 100644 |
index da2e8f18eb84c67331a7efe5250077c2eface19b..0000000000000000000000000000000000000000 |
--- a/chrome/browser/policy/cloud/external_policy_data_updater.cc |
+++ /dev/null |
@@ -1,400 +0,0 @@ |
-// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/policy/cloud/external_policy_data_updater.h" |
- |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/callback.h" |
-#include "base/location.h" |
-#include "base/logging.h" |
-#include "base/sequenced_task_runner.h" |
-#include "base/sha1.h" |
-#include "base/stl_util.h" |
-#include "chrome/browser/policy/cloud/external_policy_data_fetcher.h" |
-#include "net/base/backoff_entry.h" |
-#include "url/gurl.h" |
- |
-namespace policy { |
- |
-namespace { |
- |
-// Policies for exponential backoff of failed requests. There are 3 policies for |
-// different classes of errors. |
- |
-// For temporary errors (HTTP 500, RST, etc). |
-const net::BackoffEntry::Policy kRetrySoonPolicy = { |
- // Number of initial errors to ignore before starting to back off. |
- 0, |
- |
- // Initial delay in ms: 60 seconds. |
- 1000 * 60, |
- |
- // Factor by which the waiting time is multiplied. |
- 2, |
- |
- // Fuzzing percentage; this spreads delays randomly between 80% and 100% |
- // of the calculated time. |
- 0.20, |
- |
- // Maximum delay in ms: 12 hours. |
- 1000 * 60 * 60 * 12, |
- |
- // When to discard an entry: never. |
- -1, |
- |
- // |always_use_initial_delay|; false means that the initial delay is |
- // applied after the first error, and starts backing off from there. |
- false, |
-}; |
- |
-// For other errors (request failed, server errors). |
-const net::BackoffEntry::Policy kRetryLaterPolicy = { |
- // Number of initial errors to ignore before starting to back off. |
- 0, |
- |
- // Initial delay in ms: 1 hour. |
- 1000 * 60 * 60, |
- |
- // Factor by which the waiting time is multiplied. |
- 2, |
- |
- // Fuzzing percentage; this spreads delays randomly between 80% and 100% |
- // of the calculated time. |
- 0.20, |
- |
- // Maximum delay in ms: 12 hours. |
- 1000 * 60 * 60 * 12, |
- |
- // When to discard an entry: never. |
- -1, |
- |
- // |always_use_initial_delay|; false means that the initial delay is |
- // applied after the first error, and starts backing off from there. |
- false, |
-}; |
- |
-// When the data fails validation (maybe because the policy URL and the data |
-// served at that URL are out of sync). This essentially retries every 12 hours, |
-// with some random jitter. |
-const net::BackoffEntry::Policy kRetryMuchLaterPolicy = { |
- // Number of initial errors to ignore before starting to back off. |
- 0, |
- |
- // Initial delay in ms: 12 hours. |
- 1000 * 60 * 60 * 12, |
- |
- // Factor by which the waiting time is multiplied. |
- 2, |
- |
- // Fuzzing percentage; this spreads delays randomly between 80% and 100% |
- // of the calculated time. |
- 0.20, |
- |
- // Maximum delay in ms: 12 hours. |
- 1000 * 60 * 60 * 12, |
- |
- // When to discard an entry: never. |
- -1, |
- |
- // |always_use_initial_delay|; false means that the initial delay is |
- // applied after the first error, and starts backing off from there. |
- false, |
-}; |
- |
-// Maximum number of retries for requests that aren't likely to get a |
-// different response (e.g. HTTP 4xx replies). |
-const int kMaxLimitedRetries = 3; |
- |
-} // namespace |
- |
-class ExternalPolicyDataUpdater::FetchJob |
- : public base::SupportsWeakPtr<FetchJob> { |
- public: |
- FetchJob(ExternalPolicyDataUpdater* updater, |
- const std::string& key, |
- const ExternalPolicyDataUpdater::Request& request, |
- const ExternalPolicyDataUpdater::FetchSuccessCallback& callback); |
- virtual ~FetchJob(); |
- |
- const std::string& key() const; |
- const ExternalPolicyDataUpdater::Request& request() const; |
- |
- void Start(); |
- |
- void OnFetchFinished(ExternalPolicyDataFetcher::Result result, |
- scoped_ptr<std::string> data); |
- |
- private: |
- void OnFailed(net::BackoffEntry* backoff_entry); |
- void Reschedule(); |
- |
- // Always valid as long as |this| is alive. |
- ExternalPolicyDataUpdater* updater_; |
- |
- const std::string key_; |
- const ExternalPolicyDataUpdater::Request request_; |
- ExternalPolicyDataUpdater::FetchSuccessCallback callback_; |
- |
- // If the job is currently running, a corresponding |fetch_job_| exists in the |
- // |external_policy_data_fetcher_|. The job must eventually call back to the |
- // |updater_|'s OnJobSucceeded() or OnJobFailed() method in this case. |
- // If the job is currently not running, |fetch_job_| is NULL and no callbacks |
- // should be invoked. |
- ExternalPolicyDataFetcher::Job* fetch_job_; // Not owned. |
- |
- // Some errors should trigger a limited number of retries, even with backoff. |
- // This counts down the number of such retries to stop retrying once the limit |
- // is reached. |
- int limited_retries_remaining_; |
- |
- // Various delays to retry a failed download, depending on the failure reason. |
- net::BackoffEntry retry_soon_entry_; |
- net::BackoffEntry retry_later_entry_; |
- net::BackoffEntry retry_much_later_entry_; |
- |
- DISALLOW_COPY_AND_ASSIGN(FetchJob); |
-}; |
- |
-ExternalPolicyDataUpdater::Request::Request() { |
-} |
- |
-ExternalPolicyDataUpdater::Request::Request(const std::string& url, |
- const std::string& hash, |
- int64 max_size) |
- : url(url), hash(hash), max_size(max_size) { |
-} |
- |
-bool ExternalPolicyDataUpdater::Request::operator==( |
- const Request& other) const { |
- return url == other.url && hash == other.hash && max_size == other.max_size; |
-} |
- |
-ExternalPolicyDataUpdater::FetchJob::FetchJob( |
- ExternalPolicyDataUpdater* updater, |
- const std::string& key, |
- const ExternalPolicyDataUpdater::Request& request, |
- const ExternalPolicyDataUpdater::FetchSuccessCallback& callback) |
- : updater_(updater), |
- key_(key), |
- request_(request), |
- callback_(callback), |
- fetch_job_(NULL), |
- limited_retries_remaining_(kMaxLimitedRetries), |
- retry_soon_entry_(&kRetrySoonPolicy), |
- retry_later_entry_(&kRetryLaterPolicy), |
- retry_much_later_entry_(&kRetryMuchLaterPolicy) { |
-} |
- |
-ExternalPolicyDataUpdater::FetchJob::~FetchJob() { |
- if (fetch_job_) { |
- // Cancel the fetch job in the |external_policy_data_fetcher_|. |
- updater_->external_policy_data_fetcher_->CancelJob(fetch_job_); |
- // Inform the |updater_| that the job was canceled. |
- updater_->OnJobFailed(this); |
- } |
-} |
- |
-const std::string& ExternalPolicyDataUpdater::FetchJob::key() const { |
- return key_; |
-} |
- |
-const ExternalPolicyDataUpdater::Request& |
- ExternalPolicyDataUpdater::FetchJob::request() const { |
- return request_; |
-} |
- |
-void ExternalPolicyDataUpdater::FetchJob::Start() { |
- DCHECK(!fetch_job_); |
- // Start a fetch job in the |external_policy_data_fetcher_|. This will |
- // eventually call back to OnFetchFinished() with the result. |
- fetch_job_ = updater_->external_policy_data_fetcher_->StartJob( |
- GURL(request_.url), request_.max_size, |
- base::Bind(&ExternalPolicyDataUpdater::FetchJob::OnFetchFinished, |
- base::Unretained(this))); |
-} |
- |
-void ExternalPolicyDataUpdater::FetchJob::OnFetchFinished( |
- ExternalPolicyDataFetcher::Result result, |
- scoped_ptr<std::string> data) { |
- // The fetch job in the |external_policy_data_fetcher_| is finished. |
- fetch_job_ = NULL; |
- |
- switch (result) { |
- case ExternalPolicyDataFetcher::CONNECTION_INTERRUPTED: |
- // The connection was interrupted. Try again soon. |
- OnFailed(&retry_soon_entry_); |
- return; |
- case ExternalPolicyDataFetcher::NETWORK_ERROR: |
- // Another network error occurred. Try again later. |
- OnFailed(&retry_later_entry_); |
- return; |
- case ExternalPolicyDataFetcher::SERVER_ERROR: |
- // Problem at the server. Try again soon. |
- OnFailed(&retry_soon_entry_); |
- return; |
- case ExternalPolicyDataFetcher::CLIENT_ERROR: |
- // Client error. This is unlikely to go away. Try again later, and give up |
- // retrying after 3 attempts. |
- OnFailed(limited_retries_remaining_ ? &retry_later_entry_ : NULL); |
- if (limited_retries_remaining_) |
- --limited_retries_remaining_; |
- return; |
- case ExternalPolicyDataFetcher::HTTP_ERROR: |
- // Any other type of HTTP failure. Try again later. |
- OnFailed(&retry_later_entry_); |
- return; |
- case ExternalPolicyDataFetcher::MAX_SIZE_EXCEEDED: |
- // Received |data| exceeds maximum allowed size. This may be because the |
- // data being served is stale. Try again much later. |
- OnFailed(&retry_much_later_entry_); |
- return; |
- case ExternalPolicyDataFetcher::SUCCESS: |
- break; |
- } |
- |
- if (base::SHA1HashString(*data) != request_.hash) { |
- // Received |data| does not match expected hash. This may be because the |
- // data being served is stale. Try again much later. |
- OnFailed(&retry_much_later_entry_); |
- return; |
- } |
- |
- // If the callback rejects the data, try again much later. |
- if (!callback_.Run(*data)) { |
- OnFailed(&retry_much_later_entry_); |
- return; |
- } |
- |
- // Signal success. |
- updater_->OnJobSucceeded(this); |
-} |
- |
-void ExternalPolicyDataUpdater::FetchJob::OnFailed(net::BackoffEntry* entry) { |
- if (entry) { |
- entry->InformOfRequest(false); |
- |
- // This function may have been invoked because the job was obsoleted and is |
- // in the process of being deleted. If this is the case, the WeakPtr will |
- // become invalid and the delayed task will never run. |
- updater_->task_runner_->PostDelayedTask( |
- FROM_HERE, |
- base::Bind(&FetchJob::Reschedule, AsWeakPtr()), |
- entry->GetTimeUntilRelease()); |
- } |
- |
- updater_->OnJobFailed(this); |
-} |
- |
-void ExternalPolicyDataUpdater::FetchJob::Reschedule() { |
- updater_->ScheduleJob(this); |
-} |
- |
-ExternalPolicyDataUpdater::ExternalPolicyDataUpdater( |
- scoped_refptr<base::SequencedTaskRunner> task_runner, |
- scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher, |
- size_t max_parallel_fetches) |
- : task_runner_(task_runner), |
- external_policy_data_fetcher_(external_policy_data_fetcher.release()), |
- max_parallel_jobs_(max_parallel_fetches), |
- running_jobs_(0), |
- shutting_down_(false) { |
- DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
-} |
- |
-ExternalPolicyDataUpdater::~ExternalPolicyDataUpdater() { |
- DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
- shutting_down_ = true; |
- STLDeleteValues(&job_map_); |
-} |
- |
-void ExternalPolicyDataUpdater::FetchExternalData( |
- const std::string key, |
- const Request& request, |
- const FetchSuccessCallback& callback) { |
- DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
- |
- // Check whether a job exists for this |key| already. |
- FetchJob* job = job_map_[key]; |
- if (job) { |
- // If the current |job| is handling the given |request| already, nothing |
- // needs to be done. |
- if (job->request() == request) |
- return; |
- |
- // Otherwise, the current |job| is obsolete. If the |job| is on the queue, |
- // its WeakPtr will be invalidated and skipped by StartNextJobs(). If |job| |
- // is currently running, it will call OnJobFailed() immediately. |
- delete job; |
- job_map_.erase(key); |
- } |
- |
- // Start a new job to handle |request|. |
- job = new FetchJob(this, key, request, callback); |
- job_map_[key] = job; |
- ScheduleJob(job); |
-} |
- |
-void ExternalPolicyDataUpdater::CancelExternalDataFetch( |
- const std::string& key) { |
- DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
- |
- // If a |job| exists for this |key|, delete it. If the |job| is on the queue, |
- // its WeakPtr will be invalidated and skipped by StartNextJobs(). If |job| is |
- // currently running, it will call OnJobFailed() immediately. |
- std::map<std::string, FetchJob*>::iterator job = job_map_.find(key); |
- if (job != job_map_.end()) { |
- delete job->second; |
- job_map_.erase(job); |
- } |
-} |
- |
-void ExternalPolicyDataUpdater::StartNextJobs() { |
- if (shutting_down_) |
- return; |
- |
- while (running_jobs_ < max_parallel_jobs_ && !job_queue_.empty()) { |
- FetchJob* job = job_queue_.front().get(); |
- job_queue_.pop(); |
- |
- // Some of the jobs may have been invalidated, and have to be skipped. |
- if (job) { |
- ++running_jobs_; |
- // A started job will always call OnJobSucceeded() or OnJobFailed(). |
- job->Start(); |
- } |
- } |
-} |
- |
-void ExternalPolicyDataUpdater::ScheduleJob(FetchJob* job) { |
- DCHECK_EQ(job_map_[job->key()], job); |
- |
- job_queue_.push(job->AsWeakPtr()); |
- |
- StartNextJobs(); |
-} |
- |
-void ExternalPolicyDataUpdater::OnJobSucceeded(FetchJob* job) { |
- DCHECK(running_jobs_); |
- DCHECK_EQ(job_map_[job->key()], job); |
- |
- --running_jobs_; |
- job_map_.erase(job->key()); |
- delete job; |
- |
- StartNextJobs(); |
-} |
- |
-void ExternalPolicyDataUpdater::OnJobFailed(FetchJob* job) { |
- DCHECK(running_jobs_); |
- DCHECK_EQ(job_map_[job->key()], job); |
- |
- --running_jobs_; |
- |
- // The job is not deleted when it fails because a retry attempt may have been |
- // scheduled. |
- StartNextJobs(); |
-} |
- |
-} // namespace policy |