ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / ui / file_manager / image_loader / scheduler.js
blobb0f841bcdfca68dffdf823186407663906f4d8e8
1 // Copyright 2013 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 /**
6 * Scheduler for requests. Fetches requests from a queue and processes them
7 * synchronously, taking into account priorities. The highest priority is 0.
8 * @constructor
9 */
10 function Scheduler() {
11 /**
12 * List of requests waiting to be checked. If these items are available in
13 * cache, then they are processed immediately after starting the scheduler.
14 * However, if they have to be downloaded, then these requests are moved
15 * to pendingRequests_.
17 * @type {Array.<Request>}
18 * @private
20 this.newRequests_ = [];
22 /**
23 * List of pending requests for images to be downloaded.
24 * @type {Array.<Request>}
25 * @private
27 this.pendingRequests_ = [];
29 /**
30 * List of requests being processed.
31 * @type {Array.<Request>}
32 * @private
34 this.activeRequests_ = [];
36 /**
37 * Hash array of requests being added to the queue, but not finalized yet.
38 * @type {Object}
39 * @private
41 this.requests_ = {};
43 /**
44 * If the scheduler has been started.
45 * @type {boolean}
46 * @private
48 this.started_ = false;
51 /**
52 * Maximum download requests to be run in parallel.
53 * @type {number}
54 * @const
56 Scheduler.MAXIMUM_IN_PARALLEL = 5;
58 /**
59 * Adds a request to the internal priority queue and executes it when requests
60 * with higher priorities are finished. If the result is cached, then it is
61 * processed immediately once the scheduler is started.
63 * @param {Request} request Request object.
65 Scheduler.prototype.add = function(request) {
66 if (!this.started_) {
67 this.newRequests_.push(request);
68 this.requests_[request.getId()] = request;
69 return;
72 // Enqueue the request, since already started.
73 this.pendingRequests_.push(request);
74 this.sortPendingRequests_();
76 this.continue_();
79 /**
80 * Removes a request from the scheduler (if exists).
81 * @param {string} requestId Unique ID of the request.
83 Scheduler.prototype.remove = function(requestId) {
84 var request = this.requests_[requestId];
85 if (!request)
86 return;
88 // Remove from the internal queues with pending tasks.
89 var newIndex = this.pendingRequests_.indexOf(request);
90 if (newIndex != -1)
91 this.newRequests_.splice(newIndex, 1);
92 var pendingIndex = this.pendingRequests_.indexOf(request);
93 if (pendingIndex != -1)
94 this.pendingRequests_.splice(pendingIndex, 1);
96 // Cancel the request.
97 request.cancel();
98 delete this.requests_[requestId];
102 * Starts handling requests.
104 Scheduler.prototype.start = function() {
105 this.started_ = true;
107 // Process tasks added before scheduler has been started.
108 this.pendingRequests_ = this.newRequests_;
109 this.sortPendingRequests_();
110 this.newRequests_ = [];
112 // Start serving enqueued requests.
113 this.continue_();
117 * Sorts pending requests by priorities.
118 * @private
120 Scheduler.prototype.sortPendingRequests_ = function() {
121 this.pendingRequests_.sort(function(a, b) {
122 return a.getPriority() - b.getPriority();
127 * Processes pending requests from the queue. There is no guarantee that
128 * all of the tasks will be processed at once.
130 * @private
132 Scheduler.prototype.continue_ = function() {
133 // Run only up to MAXIMUM_IN_PARALLEL in the same time.
134 while (this.pendingRequests_.length &&
135 this.activeRequests_.length < Scheduler.MAXIMUM_IN_PARALLEL) {
136 var request = this.pendingRequests_.shift();
137 this.activeRequests_.push(request);
139 // Try to load from cache. If doesn't exist, then download.
140 request.loadFromCacheAndProcess(
141 this.finish_.bind(this, request),
142 function(currentRequest) {
143 currentRequest.downloadAndProcess(
144 this.finish_.bind(this, currentRequest));
145 }.bind(this, request));
150 * Handles finished requests.
152 * @param {Request} request Finished request.
153 * @private
155 Scheduler.prototype.finish_ = function(request) {
156 var index = this.activeRequests_.indexOf(request);
157 if (index < 0)
158 console.warn('Request not found.');
159 this.activeRequests_.splice(index, 1);
160 delete this.requests_[request.getId()];
162 // Continue handling the most important requests (if started).
163 if (this.started_)
164 this.continue_();