1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_SYNC_PROCESS_RUNNER_H_
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define CHROME_BROWSER_SYNC_FILE_SYSTEM_SYNC_PROCESS_RUNNER_H_
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <string>
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/basictypes.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/memory/weak_ptr.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/timer/timer.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/sync_callbacks.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/sync_service_state.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace sync_file_system {
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class SyncFileSystemService;
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// A base class to schedule a sync.
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Each subclass must implement StartSync().
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// An instance of this class is supposed to be owned by SyncFileSystemService.
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Note that multiple SyncProcessRunner doesn't coordinate its sync schedule
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// with each other.
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class SyncProcessRunner {
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Default delay when more changes are available.
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static const int64 kSyncDelayInMilliseconds;
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Default delay when the previous change has had an error (but remote service
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // is running).
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static const int64 kSyncDelayWithSyncError;
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Default delay when there're more than 10 pending changes.
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static const int64 kSyncDelayFastInMilliseconds;
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static const int kPendingChangeThresholdForFastSync;
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Default delay when remote service is temporarily unavailable.
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The delay backs off exponentially from initial value on repeated failure.
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static const int64 kSyncDelaySlowInMilliseconds;
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Default delay when there're no changes.
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static const int64 kSyncDelayMaxInMilliseconds;
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  class Client {
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   public:
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual ~Client() {}
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual void OnSyncIdle() {}
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual SyncServiceState GetSyncServiceState() = 0;
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual SyncFileSystemService* GetSyncService() = 0;
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  class TimerHelper {
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   public:
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual ~TimerHelper() {}
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual bool IsRunning() = 0;
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual void Start(const tracked_objects::Location& from_here,
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       const base::TimeDelta& delay,
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       const base::Closure& closure) = 0;
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    virtual base::TimeTicks Now() const = 0;
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   protected:
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TimerHelper() {}
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncProcessRunner(const std::string& name,
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    Client* client,
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    scoped_ptr<TimerHelper> timer_helper,
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    size_t max_parallel_task);
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~SyncProcessRunner();
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Subclass must implement this.
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void StartSync(const SyncStatusCallback& callback) = 0;
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Schedules a new sync.
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void Schedule();
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 pending_changes() const { return pending_changes_; }
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns the current service state.  Default implementation returns
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // sync_service()->GetSyncServiceState().
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual SyncServiceState GetServiceState();
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) protected:
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void OnChangesUpdated(int64 pending_changes);
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SyncFileSystemService* GetSyncService();
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Finished(const base::TimeTicks& start_time, SyncStatusCode status);
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void Run();
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void ScheduleInternal(int64 delay);
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Throttles new sync for |base_delay| milliseconds for an error case.
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If new sync is already throttled, back off the duration.
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void ThrottleSync(int64 base_delay);
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Clears old throttling setting that is already over.
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void ResetOldThrottling();
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void ResetThrottling();
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void CheckIfIdle();
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string name_;
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Client* client_;
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  size_t max_parallel_task_;
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  size_t running_tasks_;
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<TimerHelper> timer_helper_;
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeTicks last_run_;
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeTicks last_scheduled_;
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SyncServiceState service_state_;
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeTicks throttle_from_;
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeTicks throttle_until_;
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int64 pending_changes_;
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::WeakPtrFactory<SyncProcessRunner> factory_;
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SyncProcessRunner);
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace sync_file_system
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_SYNC_PROCESS_RUNNER_H_
125