metrics_upload_scheduler.cc 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/metrics/metrics_upload_scheduler.h"
  5. #include <stdint.h>
  6. #include "base/feature_list.h"
  7. #include "base/metrics/field_trial_params.h"
  8. #include "base/metrics/histogram_macros.h"
  9. #include "base/strings/string_number_conversions.h"
  10. #include "build/build_config.h"
  11. #include "components/metrics/metrics_scheduler.h"
  12. namespace metrics {
  13. namespace {
  14. // When uploading metrics to the server fails, we progressively wait longer and
  15. // longer before sending the next log. This backoff process helps reduce load
  16. // on a server that is having issues.
  17. // The following is the multiplier we use to expand that inter-log duration.
  18. const double kBackoffMultiplier = 2;
  19. // The maximum backoff interval in hours.
  20. const int kMaxBackoffIntervalHours = 24;
  21. // Minutes to wait if we are unable to upload due to data usage cap.
  22. const int kOverDataUsageIntervalMinutes = 5;
  23. // Increases the upload interval each time it's called, to handle the case
  24. // where the server is having issues.
  25. base::TimeDelta BackOffUploadInterval(base::TimeDelta interval) {
  26. DCHECK_GT(kBackoffMultiplier, 1.0);
  27. interval = base::Microseconds(
  28. static_cast<int64_t>(kBackoffMultiplier * interval.InMicroseconds()));
  29. base::TimeDelta max_interval = base::Hours(kMaxBackoffIntervalHours);
  30. if (interval > max_interval || interval.InSeconds() < 0) {
  31. interval = max_interval;
  32. }
  33. return interval;
  34. }
  35. // Time delay after a log is uploaded successfully before attempting another.
  36. // On mobile, keeping the radio on is very expensive, so prefer to keep this
  37. // short and send in bursts.
  38. base::TimeDelta GetUnsentLogsInterval() {
  39. return base::Seconds(3);
  40. }
  41. // Initial time delay after a log uploaded fails before retrying it.
  42. base::TimeDelta GetInitialBackoffInterval() {
  43. return base::Minutes(5);
  44. }
  45. } // namespace
  46. MetricsUploadScheduler::MetricsUploadScheduler(
  47. const base::RepeatingClosure& upload_callback,
  48. bool fast_startup_for_testing)
  49. : MetricsScheduler(upload_callback, fast_startup_for_testing),
  50. unsent_logs_interval_(GetUnsentLogsInterval()),
  51. initial_backoff_interval_(GetInitialBackoffInterval()),
  52. backoff_interval_(initial_backoff_interval_) {}
  53. MetricsUploadScheduler::~MetricsUploadScheduler() {}
  54. void MetricsUploadScheduler::UploadFinished(bool server_is_healthy) {
  55. // If the server is having issues, back off. Otherwise, reset to default
  56. // (unless there are more logs to send, in which case the next upload should
  57. // happen sooner).
  58. if (!server_is_healthy) {
  59. TaskDone(backoff_interval_);
  60. backoff_interval_ = BackOffUploadInterval(backoff_interval_);
  61. } else {
  62. backoff_interval_ = initial_backoff_interval_;
  63. TaskDone(unsent_logs_interval_);
  64. }
  65. }
  66. void MetricsUploadScheduler::StopAndUploadCancelled() {
  67. Stop();
  68. TaskDone(unsent_logs_interval_);
  69. }
  70. void MetricsUploadScheduler::UploadOverDataUsageCap() {
  71. TaskDone(base::Minutes(kOverDataUsageIntervalMinutes));
  72. }
  73. } // namespace metrics