12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class to schedule syncer tasks intelligently.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SYNC_ENGINE_SYNC_SCHEDULER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYNC_ENGINE_SYNC_SCHEDULER_H_
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/base/sync_export.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/nudge_source.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sync/internal_api/public/base/invalidation_interface.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/sessions/sync_session.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tracked_objects {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Location;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace tracked_objects
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ServerConnectionEvent;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct SYNC_EXPORT_PRIVATE ConfigurationParams {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams();
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams(
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ModelTypeSet types_to_download,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const ModelSafeRoutingInfo& routing_info,
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const base::Closure& ready_task,
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const base::Closure& retry_task);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ConfigurationParams();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Source for the configuration.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The types that should be downloaded.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet types_to_download;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The new routing info (superset of types to be downloaded).
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelSafeRoutingInfo routing_info;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback to invoke on configuration completion.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure ready_task;
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Callback to invoke on configuration failure.
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::Closure retry_task;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SYNC_EXPORT_PRIVATE SyncScheduler
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public sessions::SyncSession::Delegate {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Mode {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In this mode, the thread only performs configuration tasks.  This is
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // designed to make the case where we want to download updates for a
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // specific type only, and not continue syncing until we are moved into
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // normal mode.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CONFIGURATION_MODE,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resumes polling and allows nudges, drops configuration tasks.  Runs
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // through entire sync cycle.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NORMAL_MODE,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All methods of SyncScheduler must be called on the same thread
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (except for RequestEarlyExit()).
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncScheduler();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SyncScheduler();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the scheduler with the given mode.  If the scheduler is
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // already started, switch to the given mode, although some
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scheduled tasks from the old mode may still run.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start(Mode mode) = 0;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schedules the configuration task specified by |params|. Returns true if
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the configuration task executed immediately, false if it had to be
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scheduled for a later attempt. |params.ready_task| is invoked whenever the
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // configuration task executes. |params.retry_task| is invoked once if the
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // configuration task could not execute. |params.ready_task| will still be
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // called when configuration finishes.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: must already be in CONFIGURATION mode.
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void ScheduleConfiguration(const ConfigurationParams& params) = 0;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Request that the syncer avoid starting any new tasks and prepare for
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // shutdown.
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void Stop() = 0;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The meat and potatoes. All three of the following methods will post a
88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // delayed task to attempt the actual nudge (see ScheduleNudgeImpl).
89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  //
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: |desired_delay| is best-effort. If a nudge is already scheduled to
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // depart earlier than Now() + delay, the scheduler can and will prefer to
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // batch the two so that only one nudge is sent (at the earlier time). Also,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as always with delayed tasks and timers, it's possible the task gets run
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // any time after |desired_delay|.
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The LocalNudge indicates that we've made a local change, and that the
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // syncer should plan to commit this to the server some time soon.
98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void ScheduleLocalNudge(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ModelTypeSet types,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& nudge_location) = 0;
101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The LocalRefreshRequest occurs when we decide for some reason to manually
103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // request updates.  This should be used sparingly.  For example, one of its
104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // uses is to fetch the latest tab sync data when it's relevant to the UI on
105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // platforms where tab sync is not registered for invalidations.
106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void ScheduleLocalRefreshRequest(
107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      ModelTypeSet types,
108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      const tracked_objects::Location& nudge_location) = 0;
109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Invalidations are notifications the server sends to let us know when other
111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // clients have committed data.  We need to contact the sync server (being
112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // careful to pass along the "hints" delivered with those invalidations) in
113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // order to fetch the update.
114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void ScheduleInvalidationNudge(
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      syncer::ModelType type,
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_ptr<InvalidationInterface> invalidation,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& nudge_location) = 0;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Requests a non-blocking initial sync request for the specified type.
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  //
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Many types can only complete initial sync while the scheduler is in
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // configure mode, but a few of them are able to perform their initial sync
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // while the scheduler is in normal mode.  This non-blocking initial sync
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // can be requested through this function.
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void ScheduleInitialSyncNudge(syncer::ModelType model_type) = 0;
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change status of notifications in the SyncSessionContext.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetNotificationsEnabled(bool notifications_enabled) = 0;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when credentials are updated by the user.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnCredentialsUpdated() = 0;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the network layer detects a connection status change.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnConnectionStatusChange() = 0;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace syncer
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // SYNC_ENGINE_SYNC_SCHEDULER_H_
140