Index: chrome/browser/sync/engine/syncer_thread.h |
diff --git a/chrome/browser/sync/engine/syncer_thread.h b/chrome/browser/sync/engine/syncer_thread.h |
index d270f14000d127431ceff0ce7b804ec8a8acce0a..11fee167958b5f88dd7db4d1ce0c3f900d5aff5e 100644 |
--- a/chrome/browser/sync/engine/syncer_thread.h |
+++ b/chrome/browser/sync/engine/syncer_thread.h |
@@ -3,74 +3,175 @@ |
// found in the LICENSE file. |
// |
// A class to run the syncer on a thread. |
-// This is the default implementation of SyncerThread whose Stop implementation |
-// does not support a timeout, but is greatly simplified. |
#ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ |
#define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ |
#pragma once |
-#include <list> |
-#include <string> |
-#include <vector> |
- |
-#include "base/basictypes.h" |
-#include "base/gtest_prod_util.h" |
-#include "base/memory/ref_counted.h" |
+#include "base/callback.h" |
+#include "base/memory/linked_ptr.h" |
tim (not reviewing)
2011/04/18 16:11:47
I'm assuming there were no changes to syncer_threa
lipalani1
2011/04/18 20:36:41
Yes it was a straight port.
On 2011/04/18 16:11:47
|
#include "base/memory/scoped_ptr.h" |
-#include "base/synchronization/condition_variable.h" |
+#include "base/observer_list.h" |
+#include "base/task.h" |
#include "base/threading/thread.h" |
#include "base/time.h" |
-#include "base/synchronization/waitable_event.h" |
-#include "chrome/browser/sync/engine/syncer_types.h" |
-#include "chrome/browser/sync/sessions/sync_session.h" |
-#include "chrome/browser/sync/syncable/model_type.h" |
+#include "base/timer.h" |
+#include "chrome/browser/sync/engine/nudge_source.h" |
+#include "chrome/browser/sync/engine/polling_constants.h" |
+#include "chrome/browser/sync/engine/syncer.h" |
#include "chrome/browser/sync/syncable/model_type_payload_map.h" |
-#include "chrome/common/deprecated/event_sys-inl.h" |
- |
-#if defined(OS_LINUX) |
-#include "chrome/browser/sync/engine/idle_query_linux.h" |
-#endif |
- |
-class EventListenerHookup; |
+#include "chrome/browser/sync/engine/net/server_connection_manager.h" |
+#include "chrome/browser/sync/sessions/sync_session.h" |
+#include "chrome/browser/sync/sessions/sync_session_context.h" |
namespace browser_sync { |
-class ModelSafeWorker; |
-class ServerConnectionManager; |
-class Syncer; |
-class URLFactory; |
struct ServerConnectionEvent; |
-class SyncerThread : public base::RefCountedThreadSafe<SyncerThread>, |
- public sessions::SyncSession::Delegate { |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadTest, CalculateSyncWaitTime); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadTest, CalculatePollingWaitTime); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Polling); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Nudge); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, NudgeWithDataTypes); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, |
- NudgeWithDataTypesCoalesced); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, NudgeWithPayloads); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, |
- NudgeWithPayloadsCoalesced); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Throttling); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, AuthInvalid); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Pause); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, StartWhenNotConnected); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, PauseWhenNotConnected); |
- FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, StopSyncPermanently); |
- friend class SyncerThreadWithSyncerTest; |
- friend class SyncerThreadFactory; |
+class SyncerThread : public sessions::SyncSession::Delegate, |
+ public ServerConnectionEventListener { |
public: |
- // Encapsulates the parameters that make up an interval on which the |
- // syncer thread is sleeping. |
+ enum Mode { |
+ // In this mode, the thread only performs configuration tasks. This is |
+ // designed to make the case where we want to download updates for a |
+ // specific type only, and not continue syncing until we are moved into |
+ // normal mode. |
+ CONFIGURATION_MODE, |
+ // Resumes polling and allows nudges, drops configuration tasks. Runs |
+ // through entire sync cycle. |
+ NORMAL_MODE, |
+ }; |
+ |
+ // Takes ownership of both |context| and |syncer|. |
+ SyncerThread(sessions::SyncSessionContext* context, Syncer* syncer); |
+ virtual ~SyncerThread(); |
+ |
+ typedef Callback0::Type ModeChangeCallback; |
+ |
+ // Change the mode of operation. |
+ // We don't use a lock when changing modes, so we won't cause currently |
+ // scheduled jobs to adhere to the new mode. We could protect it, but it |
+ // doesn't buy very much as a) a session could already be in progress and it |
+ // will continue no matter what, b) the scheduled sessions already contain |
+ // all their required state and won't be affected by potential change at |
+ // higher levels (i.e. the registrar), and c) we service tasks FIFO, so once |
+ // the mode changes all future jobs will be run against the updated mode. |
+ // If supplied, |callback| will be invoked when the mode has been |
+ // changed to |mode| *from the SyncerThread*, and not from the caller |
+ // thread. |
+ void Start(Mode mode, ModeChangeCallback* callback); |
+ |
+ // Joins on the thread as soon as possible (currently running session |
+ // completes). |
+ void Stop(); |
+ |
+ // The meat and potatoes. |
+ void ScheduleNudge(const base::TimeDelta& delay, NudgeSource source, |
+ const syncable::ModelTypeBitSet& types, |
+ const tracked_objects::Location& nudge_location); |
+ void ScheduleNudgeWithPayloads( |
+ const base::TimeDelta& delay, NudgeSource source, |
+ const syncable::ModelTypePayloadMap& types_with_payloads, |
+ const tracked_objects::Location& nudge_location); |
+ void ScheduleConfig(const syncable::ModelTypeBitSet& types); |
+ void ScheduleClearUserData(); |
+ |
+ // Change status of notifications in the SyncSessionContext. |
+ void set_notifications_enabled(bool notifications_enabled); |
+ |
+ // DDOS avoidance function. Calculates how long we should wait before trying |
+ // again after a failed sync attempt, where the last delay was |base_delay|. |
+ // TODO(tim): Look at URLRequestThrottlerEntryInterface. |
+ static base::TimeDelta GetRecommendedDelay(const base::TimeDelta& base_delay); |
+ |
+ // SyncSession::Delegate implementation. |
+ virtual void OnSilencedUntil(const base::TimeTicks& silenced_until); |
+ virtual bool IsSyncingCurrentlySilenced(); |
+ virtual void OnReceivedShortPollIntervalUpdate( |
+ const base::TimeDelta& new_interval); |
+ virtual void OnReceivedLongPollIntervalUpdate( |
+ const base::TimeDelta& new_interval); |
+ virtual void OnShouldStopSyncingPermanently(); |
+ |
+ // ServerConnectionEventListener implementation. |
+ // TODO(tim): schedule a nudge when valid connection detected? in 1 minute? |
+ virtual void OnServerConnectionEvent(const ServerConnectionEvent2& event); |
+ |
+ private: |
+ enum JobProcessDecision { |
+ // Indicates we should continue with the current job. |
+ CONTINUE, |
+ // Indicates that we should save it to be processed later. |
+ SAVE, |
+ // Indicates we should drop this job. |
+ DROP, |
+ }; |
+ |
+ struct SyncSessionJob { |
+ // An enum used to describe jobs for scheduling purposes. |
+ enum SyncSessionJobPurpose { |
+ // Our poll timer schedules POLL jobs periodically based on a server |
+ // assigned poll interval. |
+ POLL, |
+ // A nudge task can come from a variety of components needing to force |
+ // a sync. The source is inferable from |session.source()|. |
+ NUDGE, |
+ // The user invoked a function in the UI to clear their entire account |
+ // and stop syncing (globally). |
+ CLEAR_USER_DATA, |
+ // Typically used for fetching updates for a subset of the enabled types |
+ // during initial sync or reconfiguration. We don't run all steps of |
+ // the sync cycle for these (e.g. CleanupDisabledTypes is skipped). |
+ CONFIGURATION, |
+ }; |
+ SyncSessionJob(); |
+ SyncSessionJob(SyncSessionJobPurpose purpose, base::TimeTicks start, |
+ linked_ptr<sessions::SyncSession> session, bool is_canary_job, |
+ const tracked_objects::Location& nudge_location); |
+ ~SyncSessionJob(); |
+ SyncSessionJobPurpose purpose; |
+ base::TimeTicks scheduled_start; |
+ linked_ptr<sessions::SyncSession> session; |
+ bool is_canary_job; |
+ |
+ // This is the location the nudge came from. used for debugging purpose. |
+ // In case of multiple nudges getting coalesced this stores the first nudge |
+ // that came in. |
+ tracked_objects::Location nudge_location; |
+ }; |
+ friend class SyncerThread2Test; |
+ friend class SyncerThread2WhiteboxTest; |
+ |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, |
+ DropNudgeWhileExponentialBackOff); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, SaveNudge); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinueNudge); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, DropPoll); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinuePoll); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinueConfiguration); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, |
+ SaveConfigurationWhileThrottled); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, |
+ SaveNudgeWhileThrottled); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, |
+ ContinueClearUserDataUnderAllCircumstances); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, |
+ ContinueCanaryJobConfig); |
+ FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, |
+ ContinueNudgeWhileExponentialBackOff); |
+ |
+ // A component used to get time delays associated with exponential backoff. |
+ // Encapsulated into a class to facilitate testing. |
+ class DelayProvider { |
+ public: |
+ DelayProvider(); |
+ virtual base::TimeDelta GetDelay(const base::TimeDelta& last_delay); |
+ virtual ~DelayProvider(); |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(DelayProvider); |
+ }; |
+ |
struct WaitInterval { |
enum Mode { |
- // A wait interval whose duration has not been affected by exponential |
- // backoff. The base case for exponential backoff falls in to this case |
- // (e.g when the exponent is 1). So far, we don't need a separate case. |
- // NORMAL intervals are not nudge-rate limited. |
- NORMAL, |
// A wait interval whose duration has been affected by exponential |
// backoff. |
// EXPONENTIAL_BACKOFF intervals are nudge-rate limited to 1 per interval. |
@@ -79,286 +180,162 @@ class SyncerThread : public base::RefCountedThreadSafe<SyncerThread>, |
// during such an interval. |
THROTTLED, |
}; |
+ WaitInterval(); |
+ ~WaitInterval(); |
Mode mode; |
- // This bool is set to true if we have observed a nudge during during this |
- // interval and mode == EXPONENTIAL_BACKOFF. |
- bool had_nudge_during_backoff; |
- base::TimeDelta poll_delta; // The wait duration until the next poll. |
- WaitInterval() : mode(NORMAL), had_nudge_during_backoff(false) { } |
+ // This bool is set to true if we have observed a nudge during this |
+ // interval and mode == EXPONENTIAL_BACKOFF. |
+ bool had_nudge; |
+ base::TimeDelta length; |
+ base::OneShotTimer<SyncerThread> timer; |
+ |
+ // Configure jobs are saved only when backing off or throttling. So we |
+ // expose the pointer here. |
+ scoped_ptr<SyncSessionJob> pending_configure_job; |
+ WaitInterval(Mode mode, base::TimeDelta length); |
}; |
- enum NudgeSource { |
- kUnknown = 0, |
- kNotification, |
- kLocal, |
- kContinuation, |
- kClearPrivateData |
- }; |
- // Server can overwrite these values via client commands. |
- // Standard short poll. This is used when XMPP is off. |
- static const int kDefaultShortPollIntervalSeconds; |
- // Long poll is used when XMPP is on. |
- static const int kDefaultLongPollIntervalSeconds; |
- // 30 minutes by default. If exponential backoff kicks in, this is the |
- // longest possible poll interval. |
- static const int kDefaultMaxPollIntervalMs; |
- // Maximum interval for exponential backoff. |
- static const int kMaxBackoffSeconds; |
- |
- explicit SyncerThread(sessions::SyncSessionContext* context); |
- virtual ~SyncerThread(); |
+ // Helper to assemble a job and post a delayed task to sync. |
+ void ScheduleSyncSessionJob( |
+ const base::TimeDelta& delay, |
+ SyncSessionJob::SyncSessionJobPurpose purpose, |
+ sessions::SyncSession* session, |
+ const tracked_objects::Location& nudge_location); |
- virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr); |
- |
- // Starts a syncer thread. |
- // Returns true if it creates a thread or if there's currently a thread |
- // running and false otherwise. |
- virtual bool Start(); |
- |
- // Stop processing. |max_wait| doesn't do anything in this version. |
- virtual bool Stop(int max_wait); |
- |
- // Request that the thread pauses. Returns false if the request can |
- // not be completed (e.g. the thread is not running). When the |
- // thread actually pauses, a SyncEngineEvent::PAUSED event notification |
- // will be sent to the relay channel. |
- virtual bool RequestPause(); |
- |
- // Request that the thread resumes from pause. Returns false if the |
- // request can not be completed (e.g. the thread is not running or |
- // is not currently paused). When the thread actually resumes, a |
- // SyncEngineEvent::RESUMED event notification will be sent to the relay |
- // channel. |
- virtual bool RequestResume(); |
- |
- // Nudges the syncer to sync with a delay specified. This API is for access |
- // from the SyncerThread's controller and will cause a mutex lock. |
- virtual void NudgeSyncer(int milliseconds_from_now, NudgeSource source); |
- |
- // Same as |NudgeSyncer|, but supports tracking the datatypes that caused |
- // the nudge to occur. |
- virtual void NudgeSyncerWithDataTypes( |
- int milliseconds_from_now, |
- NudgeSource source, |
- const syncable::ModelTypeBitSet& model_types); |
- |
- // Same as |NudgeSyncer|, but supports including a payload for passing on to |
- // the download updates command. Datatypes with payloads are also considered |
- // to have caused a nudged to occur and treated accordingly. |
- virtual void NudgeSyncerWithPayloads( |
- int milliseconds_from_now, |
- NudgeSource source, |
- const syncable::ModelTypePayloadMap& model_types_with_payloads); |
- |
- void SetNotificationsEnabled(bool notifications_enabled); |
- |
- // Call this when a directory is opened |
- void CreateSyncer(const std::string& dirname); |
- |
- // DDOS avoidance function. The argument and return value is in seconds |
- static int GetRecommendedDelaySeconds(int base_delay_seconds); |
- |
- protected: |
- virtual void ThreadMain(); |
- void ThreadMainLoop(); |
- |
- virtual void SetConnected(bool connected); |
- |
- virtual void SetSyncerPollingInterval(base::TimeDelta interval); |
- virtual void SetSyncerShortPollInterval(base::TimeDelta interval); |
- |
- // Needed to emulate the behavior of pthread_create, which synchronously |
- // started the thread and set the value of thread_running_ to true. |
- // We can't quite match that because we asynchronously post the task, |
- // which opens a window for Stop to get called before the task actually |
- // makes it. To prevent this, we block Start() until we're sure it's ok. |
- base::WaitableEvent thread_main_started_; |
- |
- // Handle of the running thread. |
- base::Thread thread_; |
+ // Invoke the Syncer to perform a sync. |
+ void DoSyncSessionJob(const SyncSessionJob& job); |
- // Fields that are modified / accessed by multiple threads go in this struct |
- // for clarity and explicitness. |
- struct ProtectedFields { |
- ProtectedFields(); |
- ~ProtectedFields(); |
+ // Called after the Syncer has performed the sync represented by |job|, to |
+ // reset our state. |
+ void FinishSyncSessionJob(const SyncSessionJob& job); |
- // False when we want to stop the thread. |
- bool stop_syncer_thread_; |
+ // Record important state that might be needed in future syncs, such as which |
+ // data types may require cleanup. |
+ void UpdateCarryoverSessionState(const SyncSessionJob& old_job); |
- // True when a pause was requested. |
- bool pause_requested_; |
+ // Helper to FinishSyncSessionJob to schedule the next sync operation. |
+ void ScheduleNextSync(const SyncSessionJob& old_job); |
- // True when the thread is paused. |
- bool paused_; |
+ // Helper to configure polling intervals. Used by Start and ScheduleNextSync. |
+ void AdjustPolling(const SyncSessionJob* old_job); |
- Syncer* syncer_; |
+ // Helper to ScheduleNextSync in case of consecutive sync errors. |
+ void HandleConsecutiveContinuationError(const SyncSessionJob& old_job); |
- // State of the server connection. |
- bool connected_; |
+ // Determines if it is legal to run |job| by checking current |
+ // operational mode, backoff or throttling, freshness |
+ // (so we don't make redundant syncs), and connection. |
+ bool ShouldRunJob(const SyncSessionJob& job); |
- // kUnknown if there is no pending nudge. (Theoretically, there |
- // could be a pending nudge of type kUnknown, so it's better to |
- // check pending_nudge_time_.) |
- NudgeSource pending_nudge_source_; |
+ // Decide whether we should CONTINUE, SAVE or DROP the job. |
+ JobProcessDecision DecideOnJob(const SyncSessionJob& job); |
- // Map of all datatypes that are requesting a nudge. Can be union |
- // from multiple nudges that are coalesced. In addition, we |
- // optionally track a payload associated with each datatype (most recent |
- // payload overwrites old ones). These payloads are used by the download |
- // updates command and can contain datatype specific information the server |
- // might use. |
- syncable::ModelTypePayloadMap pending_nudge_types_; |
+ // Decide on whether to CONTINUE, SAVE or DROP the job when we are in |
+ // backoff mode. |
+ JobProcessDecision DecideWhileInWaitInterval(const SyncSessionJob& job); |
- // null iff there is no pending nudge. |
- base::TimeTicks pending_nudge_time_; |
+ // Saves the job for future execution. Note: It drops all the poll jobs. |
+ void SaveJob(const SyncSessionJob& job); |
- // The wait interval for to the current iteration of our main loop. This is |
- // only written to by the syncer thread, and since the only reader from a |
- // different thread (NudgeSync) is called at totally random times, we don't |
- // really need to access mutually exclusively as the data races that exist |
- // are intrinsic, but do so anyway and avoid using 'volatile'. |
- WaitInterval current_wait_interval_; |
- } vault_; |
+ // Coalesces the current job with the pending nudge. |
+ void InitOrCoalescePendingJob(const SyncSessionJob& job); |
- // Gets signaled whenever a thread outside of the syncer thread changes a |
- // protected field in the vault_. |
- base::ConditionVariable vault_field_changed_; |
+ // 'Impl' here refers to real implementation of public functions, running on |
+ // |thread_|. |
+ void StartImpl(Mode mode, linked_ptr<ModeChangeCallback> callback); |
+ void ScheduleNudgeImpl( |
+ const base::TimeDelta& delay, |
+ sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, |
+ const syncable::ModelTypePayloadMap& types_with_payloads, |
+ bool is_canary_job, const tracked_objects::Location& nudge_location); |
+ void ScheduleConfigImpl(const ModelSafeRoutingInfo& routing_info, |
+ const std::vector<ModelSafeWorker*>& workers, |
+ const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source); |
+ void ScheduleClearUserDataImpl(); |
- // Used to lock everything in |vault_|. |
- base::Lock lock_; |
+ // Returns true if the client is currently in exponential backoff. |
+ bool IsBackingOff() const; |
- private: |
- // Threshold multipler for how long before user should be considered idle. |
- static const int kPollBackoffThresholdMultiplier = 10; |
+ // Helper to signal all listeners registered with |session_context_|. |
+ void Notify(SyncEngineEvent::EventCause cause); |
- // SyncSession::Delegate implementation. |
- virtual void OnSilencedUntil(const base::TimeTicks& silenced_until); |
- virtual bool IsSyncingCurrentlySilenced(); |
- virtual void OnReceivedShortPollIntervalUpdate( |
- const base::TimeDelta& new_interval); |
- virtual void OnReceivedLongPollIntervalUpdate( |
- const base::TimeDelta& new_interval); |
- virtual void OnShouldStopSyncingPermanently(); |
+ // Callback to change backoff state. |
+ void DoCanaryJob(); |
+ void Unthrottle(); |
- void HandleServerConnectionEvent(const ServerConnectionEvent& event); |
- |
- // Collect all local state required for a sync and build a SyncSession out of |
- // it, reset state for the next time, and performs the sync cycle. |
- // See |GetAndResetNudgeSource| for details on what 'reset' means. |
- // |was_nudged| is set to true if the session returned is fulfilling a nudge. |
- // Returns once the session is finished (HasMoreToSync returns false). The |
- // caller owns the returned SyncSession. |
- sessions::SyncSession* SyncMain(Syncer* syncer, |
- bool was_throttled, |
- bool continue_sync_cycle, |
- bool* initial_sync_for_thread, |
- bool* was_nudged); |
- |
- // Calculates the next sync wait time and exponential backoff state. |
- // last_poll_wait is the time duration of the previous polling timeout which |
- // was used. user_idle_milliseconds is updated by this method, and is a report |
- // of the full amount of time since the last period of activity for the user. |
- // The continue_sync_cycle parameter is used to determine whether or not we |
- // are calculating a polling wait time that is a continuation of an sync cycle |
- // which terminated while the syncer still had work to do. was_nudged is used |
- // in case of exponential backoff so we only allow one nudge per backoff |
- // interval. |
- WaitInterval CalculatePollingWaitTime( |
- int last_poll_wait, // in s |
- int* user_idle_milliseconds, |
- bool* continue_sync_cycle, |
- bool was_nudged); |
- |
- // Helper to above function, considers effect of user idle time. |
- virtual int CalculateSyncWaitTime(int last_wait, int user_idle_ms); |
- |
- // Resets the source tracking state to a clean slate and returns the current |
- // state in a SyncSourceInfo. |
- // The initial sync boolean is updated if read as a sentinel. The following |
- // two methods work in concert to achieve this goal. |
- // If |was_throttled| was true, this still discards elapsed nudges, but we |
- // treat the request as a periodic poll rather than a nudge from a source. |
- // Builds a SyncSourceInfo and returns whether a nudge occurred in the |
- // |was_nudged| parameter. |
- sessions::SyncSourceInfo GetAndResetNudgeSource(bool was_throttled, |
- bool continue_sync_cycle, |
- bool* initial_sync, |
- bool* was_nudged); |
- |
- sessions::SyncSourceInfo MakeSyncSourceInfo( |
- bool nudged, |
- NudgeSource nudge_source, |
- const syncable::ModelTypePayloadMap& model_types_with_payloads, |
- bool* initial_sync); |
- |
- int UserIdleTime(); |
- |
- void WaitUntilConnectedOrQuit(); |
- |
- // The thread will remain in this method until a resume is requested |
- // or shutdown is started. |
- void PauseUntilResumedOrQuit(); |
- |
- void EnterPausedState(); |
- |
- void ExitPausedState(); |
- |
- // For unit tests only. |
- virtual void DisableIdleDetection(); |
- |
- // This sets all conditions for syncer thread termination but does not |
- // actually join threads. It is expected that Stop will be called at some |
- // time after to fully stop and clean up. |
- void RequestSyncerExitAndSetThreadStopConditions(); |
+ // Executes the pending job. Called whenever an event occurs that may |
+ // change conditions permitting a job to run. Like when network connection is |
+ // re-established, mode changes etc. |
+ void DoPendingJobIfPossible(bool is_canary_job); |
- void Notify(SyncEngineEvent::EventCause cause); |
+ // The pointer is owned by the caller. |
+ browser_sync::sessions::SyncSession* CreateSyncSession( |
+ const browser_sync::sessions::SyncSourceInfo& info); |
+ |
+ // Creates a session for a poll and performs the sync. |
+ void PollTimerCallback(); |
+ |
+ // Assign |start| and |end| to appropriate SyncerStep values for the |
+ // specified |purpose|. |
+ void SetSyncerStepsForPurpose(SyncSessionJob::SyncSessionJobPurpose purpose, |
+ SyncerStep* start, |
+ SyncerStep* end); |
- scoped_ptr<EventListenerHookup> conn_mgr_hookup_; |
+ // Initializes the hookup between the ServerConnectionManager and us. |
+ void WatchConnectionManager(); |
+ |
+ // Used to update |server_connection_ok_|, see below. |
+ void CheckServerConnectionManagerStatus( |
+ HttpResponse::ServerConnectionCode code); |
+ |
+ // Called once the first time thread_ is started to broadcast an initial |
+ // session snapshot containing data like initial_sync_ended. Important when |
+ // the client starts up and does not need to perform an initial sync. |
+ void SendInitialSnapshot(); |
+ |
+ base::Thread thread_; |
// Modifiable versions of kDefaultLongPollIntervalSeconds which can be |
// updated by the server. |
- int syncer_short_poll_interval_seconds_; |
- int syncer_long_poll_interval_seconds_; |
- |
- // The time we wait between polls in seconds. This is used as lower bound on |
- // our wait time. Updated once per loop from the command line flag. |
- int syncer_polling_interval_; |
- |
- // The upper bound on the nominal wait between polls in seconds. Note that |
- // this bounds the "nominal" poll interval, while the the actual interval |
- // also takes previous failures into account. |
- int syncer_max_interval_; |
- |
- // This causes syncer to start syncing ASAP. If the rate of requests is too |
- // high the request will be silently dropped. mutex_ should be held when |
- // this is called. |
- void NudgeSyncImpl( |
- int milliseconds_from_now, |
- NudgeSource source, |
- const syncable::ModelTypePayloadMap& model_types_with_payloads); |
- |
-#if defined(OS_LINUX) |
- // On Linux, we need this information in order to query idle time. |
- scoped_ptr<IdleQueryLinux> idle_query_; |
-#endif |
+ base::TimeDelta syncer_short_poll_interval_seconds_; |
+ base::TimeDelta syncer_long_poll_interval_seconds_; |
- scoped_ptr<sessions::SyncSessionContext> session_context_; |
+ // Periodic timer for polling. See AdjustPolling. |
+ base::RepeatingTimer<SyncerThread> poll_timer_; |
+ |
+ // The mode of operation. We don't use a lock, see Start(...) comment. |
+ Mode mode_; |
+ |
+ // TODO(tim): Bug 26339. This needs to track more than just time I think, |
+ // since the nudges could be for different types. Current impl doesn't care. |
+ base::TimeTicks last_sync_session_end_time_; |
- // Set whenever the server instructs us to stop sending it requests until |
- // a specified time, and reset for each call to SyncShare. (Note that the |
- // WaitInterval::THROTTLED contract is such that we don't call SyncShare at |
- // all until the "silenced until" embargo expires.) |
- base::TimeTicks silenced_until_; |
+ // Have we observed a valid server connection? |
+ bool server_connection_ok_; |
- // Useful for unit tests |
- bool disable_idle_detection_; |
+ // Tracks in-flight nudges so we can coalesce. |
+ scoped_ptr<SyncSessionJob> pending_nudge_; |
+ |
+ // Current wait state. Null if we're not in backoff and not throttled. |
+ scoped_ptr<WaitInterval> wait_interval_; |
+ |
+ scoped_ptr<DelayProvider> delay_provider_; |
+ |
+ // Invoked to run through the sync cycle. |
+ scoped_ptr<Syncer> syncer_; |
+ |
+ scoped_ptr<sessions::SyncSessionContext> session_context_; |
DISALLOW_COPY_AND_ASSIGN(SyncerThread); |
}; |
+ |
} // namespace browser_sync |
+// The SyncerThread manages its own internal thread and thus outlives it. We |
+// don't need refcounting for posting tasks to this internal thread. |
+DISABLE_RUNNABLE_METHOD_REFCOUNT(browser_sync::SyncerThread); |
+ |
#endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ |