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

Side by Side Diff: chrome/browser/chromeos/drive/drive_scheduler.cc

Issue 12220073: Split queue into metadata and file data queues (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review fixes 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
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/chromeos/drive/drive_scheduler.h" 5 #include "chrome/browser/chromeos/drive/drive_scheduler.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 const DriveScheduler::QueueEntry* left, 48 const DriveScheduler::QueueEntry* left,
49 const DriveScheduler::QueueEntry* right) { 49 const DriveScheduler::QueueEntry* right) {
50 return (right->context.type == BACKGROUND && 50 return (right->context.type == BACKGROUND &&
51 left->context.type != BACKGROUND); 51 left->context.type != BACKGROUND);
52 } 52 }
53 53
54 DriveScheduler::DriveScheduler( 54 DriveScheduler::DriveScheduler(
55 Profile* profile, 55 Profile* profile,
56 google_apis::DriveServiceInterface* drive_service, 56 google_apis::DriveServiceInterface* drive_service,
57 google_apis::DriveUploaderInterface* uploader) 57 google_apis::DriveUploaderInterface* uploader)
58 : job_loop_is_running_(false), 58 : next_job_id_(0),
59 next_job_id_(0),
60 throttle_count_(0), 59 throttle_count_(0),
61 disable_throttling_(false), 60 disable_throttling_(false),
62 drive_service_(drive_service), 61 drive_service_(drive_service),
63 uploader_(uploader), 62 uploader_(uploader),
64 profile_(profile), 63 profile_(profile),
65 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 64 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
66 initialized_(false) { 65 initialized_(false) {
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
67 for (int i = 0; i < NUM_QUEUES; ++i) {
68 job_loop_is_running_[i] = false;
69 }
68 } 70 }
69 71
70 DriveScheduler::~DriveScheduler() { 72 DriveScheduler::~DriveScheduler() {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
72 DCHECK(initialized_); 74 DCHECK(initialized_);
73 STLDeleteElements(&queue_); 75 for (int i = 0; i < NUM_QUEUES; ++i) {
76 STLDeleteElements(&queue_[i]);
77 }
74 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 78 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
75 } 79 }
76 80
77 void DriveScheduler::Initialize() { 81 void DriveScheduler::Initialize() {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
79 83
80 // Initialize() may be called more than once for the lifetime when the 84 // Initialize() may be called more than once for the lifetime when the
81 // file system is remounted. 85 // file system is remounted.
82 if (initialized_) 86 if (initialized_)
83 return; 87 return;
84 88
85 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 89 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
86 initialized_ = true; 90 initialized_ = true;
87 } 91 }
88 92
89 void DriveScheduler::GetAccountMetadata( 93 void DriveScheduler::GetAccountMetadata(
90 const google_apis::GetAccountMetadataCallback& callback) { 94 const google_apis::GetAccountMetadataCallback& callback) {
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92 DCHECK(!callback.is_null()); 96 DCHECK(!callback.is_null());
93 97
94 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_GET_ACCOUNT_METADATA)); 98 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_GET_ACCOUNT_METADATA));
95 new_job->get_account_metadata_callback = callback; 99 new_job->get_account_metadata_callback = callback;
96 100
97 QueueJob(new_job.Pass()); 101 QueueJob(new_job.Pass());
98 102
99 StartJobLoop(); 103 StartJobLoop(GetJobQueueType(TYPE_GET_ACCOUNT_METADATA));
100 } 104 }
101 105
102 void DriveScheduler::GetAppList( 106 void DriveScheduler::GetAppList(
103 const google_apis::GetAppListCallback& callback) { 107 const google_apis::GetAppListCallback& callback) {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
105 DCHECK(!callback.is_null()); 109 DCHECK(!callback.is_null());
106 110
107 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_GET_APP_LIST)); 111 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_GET_APP_LIST));
108 new_job->get_app_list_callback = callback; 112 new_job->get_app_list_callback = callback;
109 113
110 QueueJob(new_job.Pass()); 114 QueueJob(new_job.Pass());
111 115
112 StartJobLoop(); 116 StartJobLoop(GetJobQueueType(TYPE_GET_APP_LIST));
113 } 117 }
114 118
115 void DriveScheduler::GetResourceList( 119 void DriveScheduler::GetResourceList(
116 const GURL& feed_url, 120 const GURL& feed_url,
117 int64 start_changestamp, 121 int64 start_changestamp,
118 const std::string& search_query, 122 const std::string& search_query,
119 bool shared_with_me, 123 bool shared_with_me,
120 const std::string& directory_resource_id, 124 const std::string& directory_resource_id,
121 const google_apis::GetResourceListCallback& callback) { 125 const google_apis::GetResourceListCallback& callback) {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
123 DCHECK(!callback.is_null()); 127 DCHECK(!callback.is_null());
124 128
125 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_GET_RESOURCE_LIST)); 129 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_GET_RESOURCE_LIST));
126 new_job->feed_url = feed_url; 130 new_job->feed_url = feed_url;
127 new_job->start_changestamp = start_changestamp; 131 new_job->start_changestamp = start_changestamp;
128 new_job->search_query = search_query; 132 new_job->search_query = search_query;
129 new_job->shared_with_me = shared_with_me; 133 new_job->shared_with_me = shared_with_me;
130 new_job->directory_resource_id = directory_resource_id; 134 new_job->directory_resource_id = directory_resource_id;
131 new_job->get_resource_list_callback = callback; 135 new_job->get_resource_list_callback = callback;
132 136
133 QueueJob(new_job.Pass()); 137 QueueJob(new_job.Pass());
134 138
135 StartJobLoop(); 139 StartJobLoop(GetJobQueueType(TYPE_GET_RESOURCE_LIST));
136 } 140 }
137 141
138 void DriveScheduler::GetResourceEntry( 142 void DriveScheduler::GetResourceEntry(
139 const std::string& resource_id, 143 const std::string& resource_id,
140 const DriveClientContext& context, 144 const DriveClientContext& context,
141 const google_apis::GetResourceEntryCallback& callback) { 145 const google_apis::GetResourceEntryCallback& callback) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
143 DCHECK(!callback.is_null()); 147 DCHECK(!callback.is_null());
144 148
145 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_GET_RESOURCE_ENTRY)); 149 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_GET_RESOURCE_ENTRY));
146 new_job->resource_id = resource_id; 150 new_job->resource_id = resource_id;
147 new_job->context = context; 151 new_job->context = context;
148 new_job->get_resource_entry_callback = callback; 152 new_job->get_resource_entry_callback = callback;
149 153
150 QueueJob(new_job.Pass()); 154 QueueJob(new_job.Pass());
151 155
152 StartJobLoop(); 156 StartJobLoop(GetJobQueueType(TYPE_GET_RESOURCE_ENTRY));
153 } 157 }
154 158
155 void DriveScheduler::DeleteResource( 159 void DriveScheduler::DeleteResource(
156 const std::string& resource_id, 160 const std::string& resource_id,
157 const google_apis::EntryActionCallback& callback) { 161 const google_apis::EntryActionCallback& callback) {
158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
159 DCHECK(!callback.is_null()); 163 DCHECK(!callback.is_null());
160 164
161 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_DELETE_RESOURCE)); 165 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_DELETE_RESOURCE));
162 new_job->resource_id = resource_id; 166 new_job->resource_id = resource_id;
163 new_job->entry_action_callback = callback; 167 new_job->entry_action_callback = callback;
164 168
165 QueueJob(new_job.Pass()); 169 QueueJob(new_job.Pass());
166 170
167 StartJobLoop(); 171 StartJobLoop(GetJobQueueType(TYPE_DELETE_RESOURCE));
168 } 172 }
169 173
170 174
171 void DriveScheduler::CopyHostedDocument( 175 void DriveScheduler::CopyHostedDocument(
172 const std::string& resource_id, 176 const std::string& resource_id,
173 const std::string& new_name, 177 const std::string& new_name,
174 const google_apis::GetResourceEntryCallback& callback) { 178 const google_apis::GetResourceEntryCallback& callback) {
175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
176 DCHECK(!callback.is_null()); 180 DCHECK(!callback.is_null());
177 181
178 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_COPY_HOSTED_DOCUMENT)); 182 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_COPY_HOSTED_DOCUMENT));
179 new_job->resource_id = resource_id; 183 new_job->resource_id = resource_id;
180 new_job->new_name = new_name; 184 new_job->new_name = new_name;
181 new_job->get_resource_entry_callback = callback; 185 new_job->get_resource_entry_callback = callback;
182 186
183 QueueJob(new_job.Pass()); 187 QueueJob(new_job.Pass());
184 188
185 StartJobLoop(); 189 StartJobLoop(GetJobQueueType(TYPE_COPY_HOSTED_DOCUMENT));
186 } 190 }
187 191
188 void DriveScheduler::RenameResource( 192 void DriveScheduler::RenameResource(
189 const std::string& resource_id, 193 const std::string& resource_id,
190 const std::string& new_name, 194 const std::string& new_name,
191 const google_apis::EntryActionCallback& callback) { 195 const google_apis::EntryActionCallback& callback) {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
193 DCHECK(!callback.is_null()); 197 DCHECK(!callback.is_null());
194 198
195 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_RENAME_RESOURCE)); 199 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_RENAME_RESOURCE));
196 new_job->resource_id = resource_id; 200 new_job->resource_id = resource_id;
197 new_job->new_name = new_name; 201 new_job->new_name = new_name;
198 new_job->entry_action_callback = callback; 202 new_job->entry_action_callback = callback;
199 203
200 QueueJob(new_job.Pass()); 204 QueueJob(new_job.Pass());
201 205
202 StartJobLoop(); 206 StartJobLoop(GetJobQueueType(TYPE_RENAME_RESOURCE));
203 } 207 }
204 208
205 void DriveScheduler::AddResourceToDirectory( 209 void DriveScheduler::AddResourceToDirectory(
206 const std::string& parent_resource_id, 210 const std::string& parent_resource_id,
207 const std::string& resource_id, 211 const std::string& resource_id,
208 const google_apis::EntryActionCallback& callback) { 212 const google_apis::EntryActionCallback& callback) {
209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
210 DCHECK(!callback.is_null()); 214 DCHECK(!callback.is_null());
211 215
212 scoped_ptr<QueueEntry> new_job( 216 scoped_ptr<QueueEntry> new_job(
213 new QueueEntry(TYPE_ADD_RESOURCE_TO_DIRECTORY)); 217 new QueueEntry(TYPE_ADD_RESOURCE_TO_DIRECTORY));
214 new_job->parent_resource_id = parent_resource_id; 218 new_job->parent_resource_id = parent_resource_id;
215 new_job->resource_id = resource_id; 219 new_job->resource_id = resource_id;
216 new_job->entry_action_callback = callback; 220 new_job->entry_action_callback = callback;
217 221
218 QueueJob(new_job.Pass()); 222 QueueJob(new_job.Pass());
219 223
220 StartJobLoop(); 224 StartJobLoop(GetJobQueueType(TYPE_ADD_RESOURCE_TO_DIRECTORY));
221 } 225 }
222 226
223 void DriveScheduler::RemoveResourceFromDirectory( 227 void DriveScheduler::RemoveResourceFromDirectory(
224 const std::string& parent_resource_id, 228 const std::string& parent_resource_id,
225 const std::string& resource_id, 229 const std::string& resource_id,
226 const google_apis::EntryActionCallback& callback) { 230 const google_apis::EntryActionCallback& callback) {
227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
228 232
229 scoped_ptr<QueueEntry> new_job( 233 scoped_ptr<QueueEntry> new_job(
230 new QueueEntry(TYPE_REMOVE_RESOURCE_FROM_DIRECTORY)); 234 new QueueEntry(TYPE_REMOVE_RESOURCE_FROM_DIRECTORY));
231 new_job->parent_resource_id = parent_resource_id; 235 new_job->parent_resource_id = parent_resource_id;
232 new_job->resource_id = resource_id; 236 new_job->resource_id = resource_id;
233 new_job->entry_action_callback = callback; 237 new_job->entry_action_callback = callback;
234 238
235 QueueJob(new_job.Pass()); 239 QueueJob(new_job.Pass());
236 240
237 StartJobLoop(); 241 StartJobLoop(GetJobQueueType(TYPE_REMOVE_RESOURCE_FROM_DIRECTORY));
238 } 242 }
239 243
240 void DriveScheduler::AddNewDirectory( 244 void DriveScheduler::AddNewDirectory(
241 const std::string& parent_resource_id, 245 const std::string& parent_resource_id,
242 const std::string& directory_name, 246 const std::string& directory_name,
243 const google_apis::GetResourceEntryCallback& callback) { 247 const google_apis::GetResourceEntryCallback& callback) {
244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
245 249
246 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_ADD_NEW_DIRECTORY)); 250 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_ADD_NEW_DIRECTORY));
247 new_job->parent_resource_id = parent_resource_id; 251 new_job->parent_resource_id = parent_resource_id;
248 new_job->directory_name = directory_name; 252 new_job->directory_name = directory_name;
249 new_job->get_resource_entry_callback = callback; 253 new_job->get_resource_entry_callback = callback;
250 254
251 QueueJob(new_job.Pass()); 255 QueueJob(new_job.Pass());
252 256
253 StartJobLoop(); 257 StartJobLoop(GetJobQueueType(TYPE_ADD_NEW_DIRECTORY));
254 } 258 }
255 259
256 void DriveScheduler::DownloadFile( 260 void DriveScheduler::DownloadFile(
257 const base::FilePath& virtual_path, 261 const base::FilePath& virtual_path,
258 const base::FilePath& local_cache_path, 262 const base::FilePath& local_cache_path,
259 const GURL& download_url, 263 const GURL& download_url,
260 const DriveClientContext& context, 264 const DriveClientContext& context,
261 const google_apis::DownloadActionCallback& download_action_callback, 265 const google_apis::DownloadActionCallback& download_action_callback,
262 const google_apis::GetContentCallback& get_content_callback) { 266 const google_apis::GetContentCallback& get_content_callback) {
263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
264 268
265 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_DOWNLOAD_FILE)); 269 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_DOWNLOAD_FILE));
266 new_job->virtual_path = virtual_path; 270 new_job->virtual_path = virtual_path;
267 new_job->local_cache_path = local_cache_path; 271 new_job->local_cache_path = local_cache_path;
268 new_job->download_url = download_url; 272 new_job->download_url = download_url;
269 new_job->context = context; 273 new_job->context = context;
270 new_job->download_action_callback = download_action_callback; 274 new_job->download_action_callback = download_action_callback;
271 new_job->get_content_callback = get_content_callback; 275 new_job->get_content_callback = get_content_callback;
272 276
273 QueueJob(new_job.Pass()); 277 QueueJob(new_job.Pass());
274 278
275 StartJobLoop(); 279 StartJobLoop(GetJobQueueType(TYPE_DOWNLOAD_FILE));
276 } 280 }
277 281
278 void DriveScheduler::UploadExistingFile( 282 void DriveScheduler::UploadExistingFile(
279 const GURL& upload_location, 283 const GURL& upload_location,
280 const base::FilePath& drive_file_path, 284 const base::FilePath& drive_file_path,
281 const base::FilePath& local_file_path, 285 const base::FilePath& local_file_path,
282 const std::string& content_type, 286 const std::string& content_type,
283 const std::string& etag, 287 const std::string& etag,
284 const DriveClientContext& context, 288 const DriveClientContext& context,
285 const google_apis::UploadCompletionCallback& upload_completion_callback) { 289 const google_apis::UploadCompletionCallback& upload_completion_callback) {
286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
287 291
288 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_UPLOAD_EXISTING_FILE)); 292 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_UPLOAD_EXISTING_FILE));
289 new_job->upload_location = upload_location; 293 new_job->upload_location = upload_location;
290 new_job->drive_file_path = drive_file_path; 294 new_job->drive_file_path = drive_file_path;
291 new_job->local_file_path = local_file_path; 295 new_job->local_file_path = local_file_path;
292 new_job->content_type = content_type; 296 new_job->content_type = content_type;
293 new_job->etag = etag; 297 new_job->etag = etag;
294 new_job->upload_completion_callback = upload_completion_callback; 298 new_job->upload_completion_callback = upload_completion_callback;
295 new_job->context = context; 299 new_job->context = context;
296 300
297 QueueJob(new_job.Pass()); 301 QueueJob(new_job.Pass());
298 302
299 StartJobLoop(); 303 StartJobLoop(GetJobQueueType(TYPE_UPLOAD_EXISTING_FILE));
300 } 304 }
301 305
302 void DriveScheduler::QueueJob(scoped_ptr<QueueEntry> job) { 306 void DriveScheduler::QueueJob(scoped_ptr<QueueEntry> job) {
303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
304 308
305 queue_.push_back(job.release()); 309 QueueType queue_type = GetJobQueueType(job->job_info.job_type);
306 queue_.sort(&QueueEntry::Compare); 310 std::list<QueueEntry*>& queue = queue_[queue_type];
311
312 queue.push_back(job.release());
313 queue.sort(&QueueEntry::Compare);
307 } 314 }
308 315
309 void DriveScheduler::StartJobLoop() { 316 void DriveScheduler::StartJobLoop(QueueType queue_type) {
310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
311 318
312 if (!job_loop_is_running_) 319 if (!job_loop_is_running_[queue_type])
313 DoJobLoop(); 320 DoJobLoop(queue_type);
314 } 321 }
315 322
316 void DriveScheduler::DoJobLoop() { 323 void DriveScheduler::DoJobLoop(QueueType queue_type) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
318 325
319 if (queue_.empty() || ShouldStopJobLoop()) { 326 if (queue_[queue_type].empty()) {
320 // Note that |queue_| is not cleared so the sync loop can resume. 327 // Note that |queue_| is not cleared so the sync loop can resume.
321 job_loop_is_running_ = false; 328 job_loop_is_running_[queue_type] = false;
322 return; 329 return;
323 } 330 }
324 job_loop_is_running_ = true; 331
332 // Check if we should defer based on the first item in the queue
333 if (ShouldStopJobLoop(queue_type, queue_[queue_type].front()->context)) {
334 job_loop_is_running_[queue_type] = false;
335 return;
336 }
337
338 job_loop_is_running_[queue_type] = true;
325 339
326 // Should copy before calling queue_.pop_front(). 340 // Should copy before calling queue_.pop_front().
327 scoped_ptr<QueueEntry> queue_entry(queue_.front()); 341 scoped_ptr<QueueEntry> queue_entry(queue_[queue_type].front());
328 queue_.pop_front(); 342 queue_[queue_type].pop_front();
329 343
330 JobInfo& job_info = queue_entry->job_info; 344 JobInfo& job_info = queue_entry->job_info;
331 job_info.state = STATE_RUNNING; 345 job_info.state = STATE_RUNNING;
332 346
333 // The some arguments are evaluated after bind, so we copy the pointer to the 347 // The some arguments are evaluated after bind, so we copy the pointer to the
334 // QueueEntry 348 // QueueEntry
335 QueueEntry* entry = queue_entry.get(); 349 QueueEntry* entry = queue_entry.get();
336 350
337 switch (job_info.job_type) { 351 switch (job_info.job_type) {
338 case TYPE_GET_ACCOUNT_METADATA: { 352 case TYPE_GET_ACCOUNT_METADATA: {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 weak_ptr_factory_.GetWeakPtr(), 471 weak_ptr_factory_.GetWeakPtr(),
458 base::Passed(&queue_entry))); 472 base::Passed(&queue_entry)));
459 } 473 }
460 break; 474 break;
461 475
462 // There is no default case so that there will be a compiler error if a type 476 // There is no default case so that there will be a compiler error if a type
463 // is added but unhandled. 477 // is added but unhandled.
464 } 478 }
465 } 479 }
466 480
467 bool DriveScheduler::ShouldStopJobLoop() { 481 bool DriveScheduler::ShouldStopJobLoop(QueueType queue_type,
482 const DriveClientContext& context) {
468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
469 484
470 // Should stop if the gdata feature was disabled while running the fetch 485 // Should stop if the gdata feature was disabled while running the fetch
471 // loop. 486 // loop.
472 if (profile_->GetPrefs()->GetBoolean(prefs::kDisableDrive)) 487 if (profile_->GetPrefs()->GetBoolean(prefs::kDisableDrive))
473 return true; 488 return true;
474 489
475 // Should stop if the network is not online. 490 // Should stop if the network is not online.
476 if (net::NetworkChangeNotifier::IsOffline()) 491 if (net::NetworkChangeNotifier::IsOffline())
477 return true; 492 return true;
478 493
479 // TODO(zork): This is a temporary fix for crbug.com/172270. It should be 494 if (queue_type == FILE_QUEUE && context.type == BACKGROUND) {
480 // re-enabled once it's merged. 495 // Should stop if the current connection is on cellular network, and
481 // 496 // fetching is disabled over cellular.
482 // Should stop if the current connection is on cellular network, and 497 if (profile_->GetPrefs()->GetBoolean(prefs::kDisableDriveOverCellular) &&
483 // fetching is disabled over cellular. 498 net::NetworkChangeNotifier::IsConnectionCellular(
484 // if (profile_->GetPrefs()->GetBoolean(prefs::kDisableDriveOverCellular) && 499 net::NetworkChangeNotifier::GetConnectionType()))
485 // net::NetworkChangeNotifier::IsConnectionCellular( 500 return true;
486 // net::NetworkChangeNotifier::GetConnectionType())) 501 }
487 // return true;
488 502
489 return false; 503 return false;
490 } 504 }
491 505
492 void DriveScheduler::ThrottleAndContinueJobLoop() { 506 void DriveScheduler::ThrottleAndContinueJobLoop(QueueType queue_type) {
493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
494 508
495 if (throttle_count_ < kMaxThrottleCount) 509 if (throttle_count_ < kMaxThrottleCount)
496 throttle_count_++; 510 throttle_count_++;
497 511
498 base::TimeDelta delay; 512 base::TimeDelta delay;
499 if (disable_throttling_) { 513 if (disable_throttling_) {
500 delay = base::TimeDelta::FromSeconds(0); 514 delay = base::TimeDelta::FromSeconds(0);
501 } else { 515 } else {
502 delay = 516 delay =
503 base::TimeDelta::FromSeconds(pow(2, throttle_count_ - 1)) + 517 base::TimeDelta::FromSeconds(pow(2, throttle_count_ - 1)) +
504 base::TimeDelta::FromMilliseconds(base::RandInt(0, 1000)); 518 base::TimeDelta::FromMilliseconds(base::RandInt(0, 1000));
505 } 519 }
506 VLOG(1) << "Throttling for " << delay.InMillisecondsF(); 520 VLOG(1) << "Throttling for " << delay.InMillisecondsF();
507 521
508 const bool posted = base::MessageLoopProxy::current()->PostDelayedTask( 522 const bool posted = base::MessageLoopProxy::current()->PostDelayedTask(
509 FROM_HERE, 523 FROM_HERE,
510 base::Bind(&DriveScheduler::DoJobLoop, 524 base::Bind(&DriveScheduler::DoJobLoop,
511 weak_ptr_factory_.GetWeakPtr()), 525 weak_ptr_factory_.GetWeakPtr(),
526 queue_type),
512 delay); 527 delay);
513 DCHECK(posted); 528 DCHECK(posted);
514 } 529 }
515 530
516 void DriveScheduler::ResetThrottleAndContinueJobLoop() { 531 void DriveScheduler::ResetThrottleAndContinueJobLoop(QueueType queue_type) {
517 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 532 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
518 533
519 // Post a task to continue the job loop. This allows us to finish handling 534 // Post a task to continue the job loop. This allows us to finish handling
520 // the current job before starting the next one. 535 // the current job before starting the next one.
521 throttle_count_ = 0; 536 throttle_count_ = 0;
522 base::MessageLoopProxy::current()->PostTask(FROM_HERE, 537 base::MessageLoopProxy::current()->PostTask(FROM_HERE,
523 base::Bind(&DriveScheduler::DoJobLoop, 538 base::Bind(&DriveScheduler::DoJobLoop,
524 weak_ptr_factory_.GetWeakPtr())); 539 weak_ptr_factory_.GetWeakPtr(),
540 queue_type));
525 } 541 }
526 542
527 scoped_ptr<DriveScheduler::QueueEntry> DriveScheduler::OnJobDone( 543 scoped_ptr<DriveScheduler::QueueEntry> DriveScheduler::OnJobDone(
528 scoped_ptr<DriveScheduler::QueueEntry> queue_entry, 544 scoped_ptr<DriveScheduler::QueueEntry> queue_entry,
529 DriveFileError error) { 545 DriveFileError error) {
530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 546 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
531 547
548 QueueType queue_type = GetJobQueueType(queue_entry->job_info.job_type);
549
532 // Retry, depending on the error. 550 // Retry, depending on the error.
533 if (error == DRIVE_FILE_ERROR_THROTTLED) { 551 if (error == DRIVE_FILE_ERROR_THROTTLED) {
534 queue_entry->job_info.state = STATE_RETRY; 552 queue_entry->job_info.state = STATE_RETRY;
535 553
536 // Requeue the job. 554 // Requeue the job.
537 QueueJob(queue_entry.Pass()); 555 QueueJob(queue_entry.Pass());
538 556
539 ThrottleAndContinueJobLoop(); 557 ThrottleAndContinueJobLoop(queue_type);
540 558
541 return scoped_ptr<DriveScheduler::QueueEntry>(); 559 return scoped_ptr<DriveScheduler::QueueEntry>();
542 } else { 560 } else {
543 ResetThrottleAndContinueJobLoop(); 561 ResetThrottleAndContinueJobLoop(queue_type);
544 562
545 // Send the entry back. 563 // Send the entry back.
546 return queue_entry.Pass(); 564 return queue_entry.Pass();
547 } 565 }
548 } 566 }
549 567
550 void DriveScheduler::OnGetResourceListJobDone( 568 void DriveScheduler::OnGetResourceListJobDone(
551 scoped_ptr<DriveScheduler::QueueEntry> queue_entry, 569 scoped_ptr<DriveScheduler::QueueEntry> queue_entry,
552 google_apis::GDataErrorCode error, 570 google_apis::GDataErrorCode error,
553 scoped_ptr<google_apis::ResourceList> resource_list) { 571 scoped_ptr<google_apis::ResourceList> resource_list) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 error, drive_path, file_path, resource_entry.Pass()); 691 error, drive_path, file_path, resource_entry.Pass());
674 } 692 }
675 693
676 void DriveScheduler::OnConnectionTypeChanged( 694 void DriveScheduler::OnConnectionTypeChanged(
677 net::NetworkChangeNotifier::ConnectionType type) { 695 net::NetworkChangeNotifier::ConnectionType type) {
678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 696 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
679 697
680 // Resume the job loop if the network is back online. Note that we don't 698 // Resume the job loop if the network is back online. Note that we don't
681 // need to check the type of the network as it will be checked in 699 // need to check the type of the network as it will be checked in
682 // ShouldStopJobLoop() as soon as the loop is resumed. 700 // ShouldStopJobLoop() as soon as the loop is resumed.
683 if (!net::NetworkChangeNotifier::IsOffline()) 701 if (!net::NetworkChangeNotifier::IsOffline()) {
684 StartJobLoop(); 702 for (int i = METADATA_QUEUE; i < NUM_QUEUES; ++i) {
703 StartJobLoop(static_cast<QueueType>(i));
704 }
705 }
706 }
707
708 DriveScheduler::QueueType DriveScheduler::GetJobQueueType(JobType type) {
709 switch (type) {
710 case TYPE_GET_ACCOUNT_METADATA:
711 case TYPE_GET_APP_LIST:
712 case TYPE_GET_RESOURCE_LIST:
713 case TYPE_GET_RESOURCE_ENTRY:
714 case TYPE_DELETE_RESOURCE:
715 case TYPE_COPY_HOSTED_DOCUMENT:
716 case TYPE_RENAME_RESOURCE:
717 case TYPE_ADD_RESOURCE_TO_DIRECTORY:
718 case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY:
719 case TYPE_ADD_NEW_DIRECTORY:
720 return METADATA_QUEUE;
721
722 case TYPE_DOWNLOAD_FILE:
723 case TYPE_UPLOAD_EXISTING_FILE:
724 return FILE_QUEUE;
725 }
726 NOTREACHED();
727 return FILE_QUEUE;
685 } 728 }
686 729
687 } // namespace drive 730 } // namespace drive
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/drive/drive_scheduler.h ('k') | chrome/browser/chromeos/drive/drive_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698