1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file.
4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#ifndef COMPONENTS_DOMAIN_RELIABILITY_SCHEDULER_H_
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#define COMPONENTS_DOMAIN_RELIABILITY_SCHEDULER_H_
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <vector>
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/callback.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/time/time.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/domain_reliability/domain_reliability_export.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace base {
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass Value;
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace base
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace domain_reliability {
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass DomainReliabilityConfig;
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass MockableTime;
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Determines when an upload should be scheduled. A domain's config will
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// specify minimum and maximum upload delays; the minimum upload delay ensures
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// that Chrome will not send too many upload requests to a site by waiting at
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// least that long after the first beacon, while the maximum upload delay makes
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// sure the server receives the reports while they are still fresh.
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch//
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// When everything is working fine, the scheduler will return precisely that
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// interval. If all uploaders have failed, then the beginning or ending points
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// of the interval may be pushed later to accomodate the retry with exponential
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// backoff.
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch//
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// See dispatcher.h for an explanation of what happens with the scheduled
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// interval.
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass DOMAIN_RELIABILITY_EXPORT DomainReliabilityScheduler {
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  typedef base::Callback<void(base::TimeDelta, base::TimeDelta)>
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ScheduleUploadCallback;
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  struct Params {
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   public:
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    base::TimeDelta minimum_upload_delay;
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    base::TimeDelta maximum_upload_delay;
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    base::TimeDelta upload_retry_interval;
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    static Params GetFromFieldTrialsOrDefaults();
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  };
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DomainReliabilityScheduler(MockableTime* time,
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                             size_t num_collectors,
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                             const Params& params,
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                             const ScheduleUploadCallback& callback);
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ~DomainReliabilityScheduler();
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
560de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // If there is no upload pending, schedules an upload based on the provided
570de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // parameters (some time between the minimum and maximum delay from now).
580de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // May call the ScheduleUploadCallback.
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void OnBeaconAdded();
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
610de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Returns which collector to use for an upload that is about to start. Must
620de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // be called exactly once during or after the ScheduleUploadCallback but
630de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // before OnUploadComplete is called. (Also records the upload start time for
640de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // future retries, if the upload ends up failing.)
650de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  size_t OnUploadStart();
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Updates the scheduler state based on the result of an upload. Must be
680de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // called exactly once after |OnUploadStart|. |success| should be true if the
690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // upload was successful, and false otherwise.
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void OnUploadComplete(bool success);
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::Value* GetWebUIData() const;
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private:
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  struct CollectorState {
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    CollectorState();
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // The number of consecutive failures to upload to this collector, or 0 if
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // the most recent upload succeeded.
800de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    unsigned failures;
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    base::TimeTicks next_upload;
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  };
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void MaybeScheduleUpload();
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void GetNextUploadTimeAndCollector(base::TimeTicks now,
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     base::TimeTicks* upload_time_out,
880de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)                                     size_t* collector_index_out);
890de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
900de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  base::TimeDelta GetUploadRetryInterval(unsigned failures);
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockableTime* time_;
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<CollectorState> collectors_;
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  Params params_;
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ScheduleUploadCallback callback_;
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Whether there are beacons that have not yet been uploaded. Set when a
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // beacon arrives or an upload fails, and cleared when an upload starts.
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool upload_pending_;
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Whether the scheduler has called the ScheduleUploadCallback to schedule
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // the next upload. Set when an upload is scheduled and cleared when the
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // upload starts.
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool upload_scheduled_;
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Whether the last scheduled upload is in progress. Set when the upload
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // starts and cleared when the upload completes (successfully or not).
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool upload_running_;
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Index of the collector selected for the next upload.  (Set in
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |OnUploadStart| and cleared in |OnUploadComplete|.)
1120de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  size_t collector_index_;
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Time of the first beacon that was not included in the last successful
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // upload.
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::TimeTicks first_beacon_time_;
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // first_beacon_time_ saved during uploads.  Restored if upload fails.
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::TimeTicks old_first_beacon_time_;
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Extra bits to return in GetWebUIData.
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeTicks scheduled_min_time_;
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeTicks scheduled_max_time_;
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Whether the other last_upload_* fields are populated.
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool last_upload_finished_;
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeTicks last_upload_start_time_;
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeTicks last_upload_end_time_;
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  size_t last_upload_collector_index_;
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool last_upload_success_;
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace domain_reliability
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif  // COMPONENTS_DOMAIN_RELIABILITY_SCHEDULER_H_
135