Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / drive / job_scheduler.h
blob3739382f4620c7182c1dbbff1d66abad95ae5d28
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
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_DRIVE_JOB_SCHEDULER_H_
6 #define COMPONENTS_DRIVE_JOB_SCHEDULER_H_
8 #include <string>
9 #include <vector>
11 #include "base/id_map.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/observer_list.h"
14 #include "base/threading/thread_checker.h"
15 #include "components/drive/drive_uploader.h"
16 #include "components/drive/job_list.h"
17 #include "components/drive/job_queue.h"
18 #include "components/drive/service/drive_service_interface.h"
19 #include "net/base/network_change_notifier.h"
21 class PrefService;
23 namespace base {
24 class SeqencedTaskRunner;
27 namespace drive {
29 class EventLogger;
31 // Priority of a job. Higher values are lower priority.
32 enum ContextType {
33 USER_INITIATED,
34 BACKGROUND,
35 // Indicates the number of values of this enum.
36 NUM_CONTEXT_TYPES,
39 struct ClientContext {
40 explicit ClientContext(ContextType in_type) : type(in_type) {}
41 ContextType type;
44 // The JobScheduler is responsible for queuing and scheduling drive jobs.
45 // Because jobs are executed concurrently by priority and retried for network
46 // failures, there is no guarantee of orderings.
48 // Jobs are grouped into two priority levels:
49 // - USER_INITIATED jobs are those occur as a result of direct user actions.
50 // - BACKGROUND jobs runs in response to state changes, server actions, etc.
51 // USER_INITIATED jobs must be handled immediately, thus have higher priority.
52 // BACKGROUND jobs run only after all USER_INITIATED jobs have run.
54 // Orthogonally, jobs are grouped into two types:
55 // - "File jobs" transfer the contents of files.
56 // - "Metadata jobs" operates on file metadata or the directory structure.
57 // On WiFi or Ethernet connections, all types of jobs just run.
58 // On mobile connections (2G/3G/4G), we don't want large background traffic.
59 // USER_INITIATED jobs or metadata jobs will run. BACKGROUND file jobs wait
60 // in the queue until the network type changes.
61 // On offline case, no jobs run. USER_INITIATED jobs fail immediately.
62 // BACKGROUND jobs stay in the queue and wait for network connection.
63 class JobScheduler
64 : public net::NetworkChangeNotifier::ConnectionTypeObserver,
65 public JobListInterface {
66 public:
67 JobScheduler(PrefService* pref_service,
68 EventLogger* logger,
69 DriveServiceInterface* drive_service,
70 base::SequencedTaskRunner* blocking_task_runner);
71 ~JobScheduler() override;
73 // JobListInterface overrides.
74 std::vector<JobInfo> GetJobInfoList() override;
75 void AddObserver(JobListObserver* observer) override;
76 void RemoveObserver(JobListObserver* observer) override;
77 void CancelJob(JobID job_id) override;
78 void CancelAllJobs() override;
80 // Adds a GetAppList operation to the queue.
81 // |callback| must not be null.
82 void GetAppList(const google_apis::AppListCallback& callback);
84 // Adds a GetAboutResource operation to the queue.
85 // |callback| must not be null.
86 void GetAboutResource(const google_apis::AboutResourceCallback& callback);
88 // Adds a GetAllFileList operation to the queue.
89 // |callback| must not be null.
90 void GetAllFileList(const google_apis::FileListCallback& callback);
92 // Adds a GetFileListInDirectory operation to the queue.
93 // |callback| must not be null.
94 void GetFileListInDirectory(const std::string& directory_resource_id,
95 const google_apis::FileListCallback& callback);
97 // Adds a Search operation to the queue.
98 // |callback| must not be null.
99 void Search(const std::string& search_query,
100 const google_apis::FileListCallback& callback);
102 // Adds a GetChangeList operation to the queue.
103 // |callback| must not be null.
104 void GetChangeList(int64 start_changestamp,
105 const google_apis::ChangeListCallback& callback);
107 // Adds GetRemainingChangeList operation to the queue.
108 // |callback| must not be null.
109 void GetRemainingChangeList(const GURL& next_link,
110 const google_apis::ChangeListCallback& callback);
112 // Adds GetRemainingFileList operation to the queue.
113 // |callback| must not be null.
114 void GetRemainingFileList(const GURL& next_link,
115 const google_apis::FileListCallback& callback);
117 // Adds a GetFileResource operation to the queue.
118 void GetFileResource(const std::string& resource_id,
119 const ClientContext& context,
120 const google_apis::FileResourceCallback& callback);
122 // Adds a GetShareUrl operation to the queue.
123 void GetShareUrl(const std::string& resource_id,
124 const GURL& embed_origin,
125 const ClientContext& context,
126 const google_apis::GetShareUrlCallback& callback);
128 // Adds a TrashResource operation to the queue.
129 void TrashResource(const std::string& resource_id,
130 const ClientContext& context,
131 const google_apis::EntryActionCallback& callback);
133 // Adds a CopyResource operation to the queue.
134 void CopyResource(const std::string& resource_id,
135 const std::string& parent_resource_id,
136 const std::string& new_title,
137 const base::Time& last_modified,
138 const google_apis::FileResourceCallback& callback);
140 // Adds a UpdateResource operation to the queue.
141 void UpdateResource(const std::string& resource_id,
142 const std::string& parent_resource_id,
143 const std::string& new_title,
144 const base::Time& last_modified,
145 const base::Time& last_viewed_by_me,
146 const google_apis::drive::Properties& properties,
147 const ClientContext& context,
148 const google_apis::FileResourceCallback& callback);
150 // Adds a AddResourceToDirectory operation to the queue.
151 void AddResourceToDirectory(const std::string& parent_resource_id,
152 const std::string& resource_id,
153 const google_apis::EntryActionCallback& callback);
155 // Adds a RemoveResourceFromDirectory operation to the queue.
156 void RemoveResourceFromDirectory(
157 const std::string& parent_resource_id,
158 const std::string& resource_id,
159 const ClientContext& context,
160 const google_apis::EntryActionCallback& callback);
162 // Adds a AddNewDirectory operation to the queue.
163 void AddNewDirectory(const std::string& parent_resource_id,
164 const std::string& directory_title,
165 const AddNewDirectoryOptions& options,
166 const ClientContext& context,
167 const google_apis::FileResourceCallback& callback);
169 // Adds a DownloadFile operation to the queue.
170 // The first two arguments |virtual_path| and |expected_file_size| are used
171 // only for filling JobInfo for the operation so that observers can get the
172 // detail. The actual operation never refers these values.
173 JobID DownloadFile(
174 const base::FilePath& virtual_path,
175 int64 expected_file_size,
176 const base::FilePath& local_cache_path,
177 const std::string& resource_id,
178 const ClientContext& context,
179 const google_apis::DownloadActionCallback& download_action_callback,
180 const google_apis::GetContentCallback& get_content_callback);
182 // Adds an UploadNewFile operation to the queue.
183 void UploadNewFile(const std::string& parent_resource_id,
184 int64 expected_file_size,
185 const base::FilePath& drive_file_path,
186 const base::FilePath& local_file_path,
187 const std::string& title,
188 const std::string& content_type,
189 const UploadNewFileOptions& options,
190 const ClientContext& context,
191 const google_apis::FileResourceCallback& callback);
193 // Adds an UploadExistingFile operation to the queue.
194 void UploadExistingFile(const std::string& resource_id,
195 int64 expected_file_size,
196 const base::FilePath& drive_file_path,
197 const base::FilePath& local_file_path,
198 const std::string& content_type,
199 const UploadExistingFileOptions& options,
200 const ClientContext& context,
201 const google_apis::FileResourceCallback& callback);
203 // Adds AddPermission operation to the queue. |callback| must not be null.
204 void AddPermission(const std::string& resource_id,
205 const std::string& email,
206 google_apis::drive::PermissionRole role,
207 const google_apis::EntryActionCallback& callback);
209 private:
210 friend class JobSchedulerTest;
212 enum QueueType {
213 METADATA_QUEUE,
214 FILE_QUEUE,
215 NUM_QUEUES
218 static const int kMaxJobCount[NUM_QUEUES];
220 // Represents a single entry in the job map.
221 struct JobEntry {
222 explicit JobEntry(JobType type);
223 ~JobEntry();
225 // General user-visible information on the job.
226 JobInfo job_info;
228 // Context of the job.
229 ClientContext context;
231 // The number of times the jobs is retried due to server errors.
232 int retry_count;
234 // The callback to start the job. Called each time it is retry.
235 base::Callback<google_apis::CancelCallback()> task;
237 // The callback to cancel the running job. It is returned from task.Run().
238 google_apis::CancelCallback cancel_callback;
240 // The callback to notify an error to the client of JobScheduler.
241 // This is used to notify cancel of a job that is not running yet.
242 base::Callback<void(google_apis::DriveApiErrorCode)> abort_callback;
244 base::ThreadChecker thread_checker_;
247 // Parameters for DriveUploader::ResumeUploadFile.
248 struct ResumeUploadParams;
250 // Creates a new job and add it to the job map.
251 JobEntry* CreateNewJob(JobType type);
253 // Adds the specified job to the queue and starts the job loop for the queue
254 // if needed.
255 void StartJob(JobEntry* job);
257 // Adds the specified job to the queue.
258 void QueueJob(JobID job_id);
260 // Determines the next job that should run, and starts it.
261 void DoJobLoop(QueueType queue_type);
263 // Returns the lowest acceptable priority level of the operations that is
264 // currently allowed to start for the |queue_type|.
265 int GetCurrentAcceptedPriority(QueueType queue_type);
267 // Updates |wait_until_| to throttle requests.
268 void UpdateWait();
270 // Retries the job if needed and returns false. Otherwise returns true.
271 bool OnJobDone(JobID job_id, google_apis::DriveApiErrorCode error);
273 // Callback for job finishing with a FileListCallback.
274 void OnGetFileListJobDone(
275 JobID job_id,
276 const google_apis::FileListCallback& callback,
277 google_apis::DriveApiErrorCode error,
278 scoped_ptr<google_apis::FileList> file_list);
280 // Callback for job finishing with a ChangeListCallback.
281 void OnGetChangeListJobDone(
282 JobID job_id,
283 const google_apis::ChangeListCallback& callback,
284 google_apis::DriveApiErrorCode error,
285 scoped_ptr<google_apis::ChangeList> change_list);
287 // Callback for job finishing with a FileResourceCallback.
288 void OnGetFileResourceJobDone(
289 JobID job_id,
290 const google_apis::FileResourceCallback& callback,
291 google_apis::DriveApiErrorCode error,
292 scoped_ptr<google_apis::FileResource> entry);
294 // Callback for job finishing with a AboutResourceCallback.
295 void OnGetAboutResourceJobDone(
296 JobID job_id,
297 const google_apis::AboutResourceCallback& callback,
298 google_apis::DriveApiErrorCode error,
299 scoped_ptr<google_apis::AboutResource> about_resource);
301 // Callback for job finishing with a GetShareUrlCallback.
302 void OnGetShareUrlJobDone(
303 JobID job_id,
304 const google_apis::GetShareUrlCallback& callback,
305 google_apis::DriveApiErrorCode error,
306 const GURL& share_url);
308 // Callback for job finishing with a AppListCallback.
309 void OnGetAppListJobDone(
310 JobID job_id,
311 const google_apis::AppListCallback& callback,
312 google_apis::DriveApiErrorCode error,
313 scoped_ptr<google_apis::AppList> app_list);
315 // Callback for job finishing with a EntryActionCallback.
316 void OnEntryActionJobDone(JobID job_id,
317 const google_apis::EntryActionCallback& callback,
318 google_apis::DriveApiErrorCode error);
320 // Callback for job finishing with a DownloadActionCallback.
321 void OnDownloadActionJobDone(
322 JobID job_id,
323 const google_apis::DownloadActionCallback& callback,
324 google_apis::DriveApiErrorCode error,
325 const base::FilePath& temp_file);
327 // Callback for job finishing with a UploadCompletionCallback.
328 void OnUploadCompletionJobDone(
329 JobID job_id,
330 const ResumeUploadParams& resume_params,
331 const google_apis::FileResourceCallback& callback,
332 google_apis::DriveApiErrorCode error,
333 const GURL& upload_location,
334 scoped_ptr<google_apis::FileResource> entry);
336 // Callback for DriveUploader::ResumeUploadFile().
337 void OnResumeUploadFileDone(
338 JobID job_id,
339 const base::Callback<google_apis::CancelCallback()>& original_task,
340 const google_apis::FileResourceCallback& callback,
341 google_apis::DriveApiErrorCode error,
342 const GURL& upload_location,
343 scoped_ptr<google_apis::FileResource> entry);
345 // Updates the progress status of the specified job.
346 void UpdateProgress(JobID job_id, int64 progress, int64 total);
348 // net::NetworkChangeNotifier::ConnectionTypeObserver override.
349 void OnConnectionTypeChanged(
350 net::NetworkChangeNotifier::ConnectionType type) override;
352 // Get the type of queue the specified job should be put in.
353 QueueType GetJobQueueType(JobType type);
355 // For testing only. Disables throttling so that testing is faster.
356 void SetDisableThrottling(bool disable) { disable_throttling_ = disable; }
358 // Aborts a job which is not in STATE_RUNNING.
359 void AbortNotRunningJob(JobEntry* job, google_apis::DriveApiErrorCode error);
361 // Notifies updates to observers.
362 void NotifyJobAdded(const JobInfo& job_info);
363 void NotifyJobDone(const JobInfo& job_info,
364 google_apis::DriveApiErrorCode error);
365 void NotifyJobUpdated(const JobInfo& job_info);
367 // Gets information of the queue of the given type as string.
368 std::string GetQueueInfo(QueueType type) const;
370 // Returns a string representation of QueueType.
371 static std::string QueueTypeToString(QueueType type);
373 // The number of times operations have failed in a row, capped at
374 // kMaxThrottleCount. This is used to calculate the delay before running the
375 // next task.
376 int throttle_count_;
378 // Jobs should not start running until this time. Used for throttling.
379 base::Time wait_until_;
381 // Disables throttling for testing.
382 bool disable_throttling_;
384 // The queues of jobs.
385 scoped_ptr<JobQueue> queue_[NUM_QUEUES];
387 // The list of queued job info indexed by job IDs.
388 typedef IDMap<JobEntry, IDMapOwnPointer> JobIDMap;
389 JobIDMap job_map_;
391 // The list of observers for the scheduler.
392 base::ObserverList<JobListObserver> observer_list_;
394 EventLogger* logger_;
395 DriveServiceInterface* drive_service_;
396 base::SequencedTaskRunner* blocking_task_runner_;
397 scoped_ptr<DriveUploaderInterface> uploader_;
399 PrefService* pref_service_;
401 base::ThreadChecker thread_checker_;
403 // Note: This should remain the last member so it'll be destroyed and
404 // invalidate its weak pointers before any other members are destroyed.
405 base::WeakPtrFactory<JobScheduler> weak_ptr_factory_;
406 DISALLOW_COPY_AND_ASSIGN(JobScheduler);
409 } // namespace drive
411 #endif // COMPONENTS_DRIVE_JOB_SCHEDULER_H_