Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: chrome/browser/sync_file_system/drive_file_sync_service.cc

Issue 12221088: Sync FileSystem: Drop is_fetching_changes_ flag and completion_callback (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: run StartBatchSync on REMOTE_SERVICE_TEMPORARY_UNAVAILABLE case Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/sync_file_system/drive_file_sync_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync_file_system/drive_file_sync_service.h" 5 #include "chrome/browser/sync_file_system/drive_file_sync_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 FILE_PATH_LITERAL("Sync FileSystem"); 45 FILE_PATH_LITERAL("Sync FileSystem");
46 46
47 // The sync invalidation object ID for Google Drive. 47 // The sync invalidation object ID for Google Drive.
48 const char kDriveInvalidationObjectId[] = "CHANGELOG"; 48 const char kDriveInvalidationObjectId[] = "CHANGELOG";
49 49
50 // Incremental sync polling interval. 50 // Incremental sync polling interval.
51 // TODO(calvinlo): Improve polling algorithm dependent on whether push 51 // TODO(calvinlo): Improve polling algorithm dependent on whether push
52 // notifications are on or off. 52 // notifications are on or off.
53 const int64 kMinimumPollingDelaySeconds = 5; 53 const int64 kMinimumPollingDelaySeconds = 5;
54 const int64 kMaximumPollingDelaySeconds = 10 * 60; // 10 min 54 const int64 kMaximumPollingDelaySeconds = 10 * 60; // 10 min
55 const int64 kPollingDelaySecondsWithNotification = 4 * 60 * 60; // 4 hr 55 const int64 kPollingDelaySecondsWithNotification = 10 * 60; // 10 min
56 const double kDelayMultiplier = 1.6; 56 const double kDelayMultiplier = 1.6;
57 57
58 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) { 58 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) {
59 return file_util::CreateDirectory(dir_path) && 59 return file_util::CreateDirectory(dir_path) &&
60 file_util::CreateTemporaryFileInDir(dir_path, temp_file); 60 file_util::CreateTemporaryFileInDir(dir_path, temp_file);
61 } 61 }
62 62
63 void DeleteTemporaryFile(const FilePath& file_path) { 63 void DeleteTemporaryFile(const FilePath& file_path) {
64 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) { 64 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) {
65 content::BrowserThread::PostTask( 65 content::BrowserThread::PostTask(
66 content::BrowserThread::FILE, FROM_HERE, 66 content::BrowserThread::FILE, FROM_HERE,
67 base::Bind(&DeleteTemporaryFile, file_path)); 67 base::Bind(&DeleteTemporaryFile, file_path));
68 return; 68 return;
69 } 69 }
70 70
71 if (!file_util::Delete(file_path, true)) 71 if (!file_util::Delete(file_path, true))
72 LOG(ERROR) << "Leaked temporary file for Sync FileSystem: " 72 LOG(ERROR) << "Leaked temporary file for Sync FileSystem: "
73 << file_path.value(); 73 << file_path.value();
74 } 74 }
75 75
76 void EmptyStatusCallback(fileapi::SyncStatusCode code) {} 76 void EmptyStatusCallback(fileapi::SyncStatusCode code) {}
77 77
78 void MarkFetchingChangesCompleted(bool* is_fetching_changes) {
79 *is_fetching_changes = false;
80 }
81
82 void DidRemoveOrigin(const GURL& origin, fileapi::SyncStatusCode status) { 78 void DidRemoveOrigin(const GURL& origin, fileapi::SyncStatusCode status) {
83 // TODO(calvinlo): Disable syncing if status not ok (http://crbug.com/171611). 79 // TODO(calvinlo): Disable syncing if status not ok (http://crbug.com/171611).
84 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); 80 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status);
85 LOG(WARNING) << "Remove origin failed for: " << origin.spec() 81 LOG(WARNING) << "Remove origin failed for: " << origin.spec()
86 << " status=" << status; 82 << " status=" << status;
87 } 83 }
88 84
89 fileapi::FileChange CreateFileChange(bool is_deleted) { 85 fileapi::FileChange CreateFileChange(bool is_deleted) {
90 if (is_deleted) { 86 if (is_deleted) {
91 return fileapi::FileChange(fileapi::FileChange::FILE_CHANGE_DELETE, 87 return fileapi::FileChange(fileapi::FileChange::FILE_CHANGE_DELETE,
(...skipping 11 matching lines...) Expand all
103 public: 99 public:
104 explicit TaskToken(const base::WeakPtr<DriveFileSyncService>& sync_service) 100 explicit TaskToken(const base::WeakPtr<DriveFileSyncService>& sync_service)
105 : sync_service_(sync_service), 101 : sync_service_(sync_service),
106 task_type_(TASK_TYPE_NONE) { 102 task_type_(TASK_TYPE_NONE) {
107 } 103 }
108 104
109 void ResetTask(const tracked_objects::Location& location) { 105 void ResetTask(const tracked_objects::Location& location) {
110 location_ = location; 106 location_ = location;
111 task_type_ = TASK_TYPE_NONE; 107 task_type_ = TASK_TYPE_NONE;
112 description_.clear(); 108 description_.clear();
113 if (!completion_callback_.is_null())
114 completion_callback_.Run();
115 completion_callback_.Reset();
116 } 109 }
117 110
118 void UpdateTask(const tracked_objects::Location& location, 111 void UpdateTask(const tracked_objects::Location& location,
119 TaskType task_type, 112 TaskType task_type,
120 const std::string& description) { 113 const std::string& description) {
121 location_ = location; 114 location_ = location;
122 task_type_ = task_type; 115 task_type_ = task_type;
123 description_ = description; 116 description_ = description;
124 117
125 DVLOG(2) << "Token updated: " << description_ 118 DVLOG(2) << "Token updated: " << description_
126 << " " << location_.ToString(); 119 << " " << location_.ToString();
127 } 120 }
128 121
129 const tracked_objects::Location& location() const { return location_; } 122 const tracked_objects::Location& location() const { return location_; }
130 TaskType task_type() const { return task_type_; } 123 TaskType task_type() const { return task_type_; }
131 const std::string& description() const { return description_; } 124 const std::string& description() const { return description_; }
132 std::string done_description() const { return description_ + " done"; } 125 std::string done_description() const { return description_ + " done"; }
133 126
134 void set_completion_callback(const base::Closure& callback) {
135 completion_callback_ = callback;
136 }
137
138 const base::Closure& completion_callback() {
139 return completion_callback_;
140 }
141
142 ~TaskToken() { 127 ~TaskToken() {
143 // All task on DriveFileSyncService must hold TaskToken instance to ensure 128 // All task on DriveFileSyncService must hold TaskToken instance to ensure
144 // no other tasks are running. Also, as soon as a task finishes to work, 129 // no other tasks are running. Also, as soon as a task finishes to work,
145 // it must return the token to DriveFileSyncService. 130 // it must return the token to DriveFileSyncService.
146 // Destroying a token with valid |sync_service_| indicates the token was 131 // Destroying a token with valid |sync_service_| indicates the token was
147 // dropped by a task without returning. 132 // dropped by a task without returning.
148 if (sync_service_) { 133 if (sync_service_) {
149 LOG(ERROR) << "Unexpected TaskToken deletion from: " 134 LOG(ERROR) << "Unexpected TaskToken deletion from: "
150 << location_.ToString() << " while: " << description_; 135 << location_.ToString() << " while: " << description_;
151 } 136 }
152 DCHECK(!sync_service_); 137 DCHECK(!sync_service_);
153 } 138 }
154 139
155 private: 140 private:
156 base::WeakPtr<DriveFileSyncService> sync_service_; 141 base::WeakPtr<DriveFileSyncService> sync_service_;
157 tracked_objects::Location location_; 142 tracked_objects::Location location_;
158 TaskType task_type_; 143 TaskType task_type_;
159 std::string description_; 144 std::string description_;
160 base::Closure completion_callback_;
161 145
162 DISALLOW_COPY_AND_ASSIGN(TaskToken); 146 DISALLOW_COPY_AND_ASSIGN(TaskToken);
163 }; 147 };
164 148
165 void DriveFileSyncService::OnInvalidatorStateChange( 149 void DriveFileSyncService::OnInvalidatorStateChange(
166 syncer::InvalidatorState state) { 150 syncer::InvalidatorState state) {
167 SetPushNotificationEnabled(state); 151 SetPushNotificationEnabled(state);
168 } 152 }
169 153
170 void DriveFileSyncService::SetPushNotificationEnabled( 154 void DriveFileSyncService::SetPushNotificationEnabled(
171 syncer::InvalidatorState state) { 155 syncer::InvalidatorState state) {
172 push_notification_enabled_ = (state == syncer::INVALIDATIONS_ENABLED); 156 push_notification_enabled_ = (state == syncer::INVALIDATIONS_ENABLED);
173 if (!push_notification_enabled_) 157 if (!push_notification_enabled_)
174 return; 158 return;
175 159
176 // Push notifications are enabled so reset polling timer. 160 // Push notifications are enabled so reset polling timer.
177 UpdatePollingDelay(kPollingDelaySecondsWithNotification); 161 UpdatePollingDelay(kPollingDelaySecondsWithNotification);
178 } 162 }
179 163
180 void DriveFileSyncService::OnIncomingInvalidation( 164 void DriveFileSyncService::OnIncomingInvalidation(
181 const syncer::ObjectIdInvalidationMap& invalidation_map) { 165 const syncer::ObjectIdInvalidationMap& invalidation_map) {
182 DCHECK(push_notification_enabled_); 166 DCHECK(push_notification_enabled_);
183 DCHECK_EQ(1U, invalidation_map.size()); 167 DCHECK_EQ(1U, invalidation_map.size());
184 const invalidation::ObjectId object_id( 168 const invalidation::ObjectId object_id(
185 ipc::invalidation::ObjectSource::COSMO_CHANGELOG, 169 ipc::invalidation::ObjectSource::COSMO_CHANGELOG,
186 kDriveInvalidationObjectId); 170 kDriveInvalidationObjectId);
187 DCHECK_EQ(1U, invalidation_map.count(object_id)); 171 DCHECK_EQ(1U, invalidation_map.count(object_id));
188 172
173 has_unfetched_remote_change_ = true;
189 FetchChangesForIncrementalSync(); 174 FetchChangesForIncrementalSync();
190 } 175 }
191 176
192 struct DriveFileSyncService::ProcessRemoteChangeParam { 177 struct DriveFileSyncService::ProcessRemoteChangeParam {
193 scoped_ptr<TaskToken> token; 178 scoped_ptr<TaskToken> token;
194 RemoteChangeProcessor* processor; 179 RemoteChangeProcessor* processor;
195 RemoteChange remote_change; 180 RemoteChange remote_change;
196 fileapi::SyncFileCallback callback; 181 fileapi::SyncFileCallback callback;
197 182
198 DriveMetadata drive_metadata; 183 DriveMetadata drive_metadata;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 265
281 DriveFileSyncService::DriveFileSyncService(Profile* profile) 266 DriveFileSyncService::DriveFileSyncService(Profile* profile)
282 : profile_(profile), 267 : profile_(profile),
283 last_operation_status_(fileapi::SYNC_STATUS_OK), 268 last_operation_status_(fileapi::SYNC_STATUS_OK),
284 state_(REMOTE_SERVICE_OK), 269 state_(REMOTE_SERVICE_OK),
285 sync_enabled_(true), 270 sync_enabled_(true),
286 largest_fetched_changestamp_(0), 271 largest_fetched_changestamp_(0),
287 push_notification_registered_(false), 272 push_notification_registered_(false),
288 push_notification_enabled_(false), 273 push_notification_enabled_(false),
289 polling_delay_seconds_(kMinimumPollingDelaySeconds), 274 polling_delay_seconds_(kMinimumPollingDelaySeconds),
290 is_fetching_changes_(false), 275 has_unfetched_remote_change_(true),
291 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 276 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
292 temporary_file_dir_ = 277 temporary_file_dir_ =
293 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); 278 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName);
294 token_.reset(new TaskToken(AsWeakPtr())); 279 token_.reset(new TaskToken(AsWeakPtr()));
295 280
296 sync_client_.reset(new DriveFileSyncClient(profile)); 281 sync_client_.reset(new DriveFileSyncClient(profile));
297 sync_client_->AddObserver(this); 282 sync_client_->AddObserver(this);
298 283
299 metadata_store_.reset(new DriveMetadataStore( 284 metadata_store_.reset(new DriveMetadataStore(
300 profile->GetPath().Append(kSyncFileSystemDir), 285 profile->GetPath().Append(kSyncFileSystemDir),
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 scoped_ptr<DriveFileSyncClient> sync_client, 685 scoped_ptr<DriveFileSyncClient> sync_client,
701 scoped_ptr<DriveMetadataStore> metadata_store) 686 scoped_ptr<DriveMetadataStore> metadata_store)
702 : profile_(profile), 687 : profile_(profile),
703 last_operation_status_(fileapi::SYNC_STATUS_OK), 688 last_operation_status_(fileapi::SYNC_STATUS_OK),
704 state_(REMOTE_SERVICE_OK), 689 state_(REMOTE_SERVICE_OK),
705 sync_enabled_(true), 690 sync_enabled_(true),
706 largest_fetched_changestamp_(0), 691 largest_fetched_changestamp_(0),
707 push_notification_registered_(false), 692 push_notification_registered_(false),
708 push_notification_enabled_(false), 693 push_notification_enabled_(false),
709 polling_delay_seconds_(-1), 694 polling_delay_seconds_(-1),
710 is_fetching_changes_(false), 695 has_unfetched_remote_change_(true),
711 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 696 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
712 DCHECK(profile); 697 DCHECK(profile);
713 temporary_file_dir_ = base_dir.Append(kTempDirName); 698 temporary_file_dir_ = base_dir.Append(kTempDirName);
714 699
715 token_.reset(new TaskToken(AsWeakPtr())); 700 token_.reset(new TaskToken(AsWeakPtr()));
716 sync_client_ = sync_client.Pass(); 701 sync_client_ = sync_client.Pass();
717 metadata_store_ = metadata_store.Pass(); 702 metadata_store_ = metadata_store.Pass();
718 703
719 base::MessageLoopProxy::current()->PostTask( 704 base::MessageLoopProxy::current()->PostTask(
720 FROM_HERE, 705 FROM_HERE,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 745
761 // Notify remote sync service state if the state has been changed. 746 // Notify remote sync service state if the state has been changed.
762 if (!token_->description().empty() || old_state != GetCurrentState()) { 747 if (!token_->description().empty() || old_state != GetCurrentState()) {
763 FOR_EACH_OBSERVER( 748 FOR_EACH_OBSERVER(
764 Observer, service_observers_, 749 Observer, service_observers_,
765 OnRemoteServiceStateUpdated(GetCurrentState(), 750 OnRemoteServiceStateUpdated(GetCurrentState(),
766 token_->done_description())); 751 token_->done_description()));
767 } 752 }
768 } 753 }
769 754
770 if (!token_->completion_callback().is_null())
771 token_->completion_callback().Run();
772
773 token_->ResetTask(FROM_HERE); 755 token_->ResetTask(FROM_HERE);
774 if (!pending_tasks_.empty()) { 756 if (!pending_tasks_.empty()) {
775 base::Closure closure = pending_tasks_.front(); 757 base::Closure closure = pending_tasks_.front();
776 pending_tasks_.pop_front(); 758 pending_tasks_.pop_front();
777 closure.Run(); 759 closure.Run();
778 return; 760 return;
779 } 761 }
780 762
763 if (has_unfetched_remote_change_ && push_notification_enabled_) {
764 FetchChangesForIncrementalSync();
765 return;
766 }
767
781 SchedulePolling(); 768 SchedulePolling();
782 769
783 if (GetCurrentState() != REMOTE_SERVICE_OK && 770 if (GetCurrentState() != REMOTE_SERVICE_OK)
784 GetCurrentState() != REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)
785 return; 771 return;
786 772
787 // If the state has become OK or TEMPORARY_UNAVAILABLE and we have any 773 // If the state has become OK or TEMPORARY_UNAVAILABLE and we have any
788 // pending batch sync origins, restart batch sync for them. 774 // pending batch sync origins, restart batch sync for them.
789 if (!pending_batch_sync_origins_.empty()) { 775 if (!pending_batch_sync_origins_.empty()) {
790 GURL origin = *pending_batch_sync_origins_.begin(); 776 GURL origin = *pending_batch_sync_origins_.begin();
791 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); 777 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin());
792 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); 778 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin);
793 StartBatchSyncForOrigin(origin, resource_id); 779 StartBatchSyncForOrigin(origin, resource_id);
794 return; 780 return;
(...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 return false; 1816 return false;
1831 const PathToChangeMap& path_to_change = found_url->second; 1817 const PathToChangeMap& path_to_change = found_url->second;
1832 PathToChangeMap::const_iterator found_path = path_to_change.find(url.path()); 1818 PathToChangeMap::const_iterator found_path = path_to_change.find(url.path());
1833 if (found_path == path_to_change.end()) 1819 if (found_path == path_to_change.end())
1834 return false; 1820 return false;
1835 *change = found_path->second; 1821 *change = found_path->second;
1836 return true; 1822 return true;
1837 } 1823 }
1838 1824
1839 void DriveFileSyncService::FetchChangesForIncrementalSync() { 1825 void DriveFileSyncService::FetchChangesForIncrementalSync() {
1826 if (!sync_enabled_ ||
1827 !pending_batch_sync_origins_.empty() ||
1828 metadata_store_->incremental_sync_origins().empty() ||
1829 !pending_changes_.empty())
1830 return;
1831
1840 scoped_ptr<TaskToken> token(GetToken(FROM_HERE, TASK_TYPE_DRIVE, 1832 scoped_ptr<TaskToken> token(GetToken(FROM_HERE, TASK_TYPE_DRIVE,
1841 "Fetching remote change list")); 1833 "Fetching remote change list"));
1842 // If we got |token| successfully, |is_fetching_changes_| should be false. 1834 if (!token)
1843 // |is_fetching_changes_| is true only when the FetchChanges sequence is
1844 // running or is in |pending_queue_|. In both case, the token is owned by
1845 // the FetchChanges sequence.
1846 DCHECK(!token || !is_fetching_changes_);
1847
1848 if (!sync_enabled_ ||
1849 is_fetching_changes_ ||
1850 !pending_batch_sync_origins_.empty() ||
1851 metadata_store_->incremental_sync_origins().empty() ||
1852 !pending_changes_.empty()) {
1853 if (token) {
1854 token->ResetTask(FROM_HERE);
1855 NotifyTaskDone(last_operation_status_, token.Pass());
1856 }
1857 return; 1835 return;
1858 } 1836 has_unfetched_remote_change_ = false;
1859
1860 is_fetching_changes_ = true;
1861
1862 if (!token) {
1863 pending_tasks_.push_back(base::Bind(
1864 &DriveFileSyncService::FetchChangesForIncrementalSync, AsWeakPtr()));
1865 return;
1866 }
1867
1868 token->set_completion_callback(
1869 base::Bind(&MarkFetchingChangesCompleted, &is_fetching_changes_));
1870
1871 if (metadata_store_->incremental_sync_origins().empty()) {
1872 token->ResetTask(FROM_HERE);
1873 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass());
1874 return;
1875 }
1876 1837
1877 DVLOG(1) << "FetchChangesForIncrementalSync (start_changestamp:" 1838 DVLOG(1) << "FetchChangesForIncrementalSync (start_changestamp:"
1878 << (largest_fetched_changestamp_ + 1) << ")"; 1839 << (largest_fetched_changestamp_ + 1) << ")";
1879 1840
1880 sync_client_->ListChanges( 1841 sync_client_->ListChanges(
1881 largest_fetched_changestamp_ + 1, 1842 largest_fetched_changestamp_ + 1,
1882 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync, 1843 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync,
1883 AsWeakPtr(), base::Passed(&token), false)); 1844 AsWeakPtr(), base::Passed(&token), false));
1884 } 1845 }
1885 1846
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 fileapi::SyncStatusCode 1993 fileapi::SyncStatusCode
2033 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper( 1994 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper(
2034 google_apis::GDataErrorCode error) const { 1995 google_apis::GDataErrorCode error) const {
2035 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); 1996 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error);
2036 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated()) 1997 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated())
2037 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED; 1998 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED;
2038 return status; 1999 return status;
2039 } 2000 }
2040 2001
2041 } // namespace sync_file_system 2002 } // namespace sync_file_system
OLDNEW
« no previous file with comments | « chrome/browser/sync_file_system/drive_file_sync_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698