source: frontend/node_modules/fastq/queue.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 6.8 KB
Line 
1'use strict'
2
3/* eslint-disable no-var */
4
5var reusify = require('reusify')
6
7function fastqueue (context, worker, _concurrency) {
8 if (typeof context === 'function') {
9 _concurrency = worker
10 worker = context
11 context = null
12 }
13
14 if (!(_concurrency >= 1)) {
15 throw new Error('fastqueue concurrency must be equal to or greater than 1')
16 }
17
18 var cache = reusify(Task)
19 var queueHead = null
20 var queueTail = null
21 var _running = 0
22 var errorHandler = null
23
24 var self = {
25 push: push,
26 drain: noop,
27 saturated: noop,
28 pause: pause,
29 paused: false,
30
31 get concurrency () {
32 return _concurrency
33 },
34 set concurrency (value) {
35 if (!(value >= 1)) {
36 throw new Error('fastqueue concurrency must be equal to or greater than 1')
37 }
38 _concurrency = value
39
40 if (self.paused) return
41 for (; queueHead && _running < _concurrency;) {
42 _running++
43 release()
44 }
45 },
46
47 running: running,
48 resume: resume,
49 idle: idle,
50 length: length,
51 getQueue: getQueue,
52 unshift: unshift,
53 empty: noop,
54 kill: kill,
55 killAndDrain: killAndDrain,
56 error: error,
57 abort: abort
58 }
59
60 return self
61
62 function running () {
63 return _running
64 }
65
66 function pause () {
67 self.paused = true
68 }
69
70 function length () {
71 var current = queueHead
72 var counter = 0
73
74 while (current) {
75 current = current.next
76 counter++
77 }
78
79 return counter
80 }
81
82 function getQueue () {
83 var current = queueHead
84 var tasks = []
85
86 while (current) {
87 tasks.push(current.value)
88 current = current.next
89 }
90
91 return tasks
92 }
93
94 function resume () {
95 if (!self.paused) return
96 self.paused = false
97 if (queueHead === null) {
98 _running++
99 release()
100 return
101 }
102 for (; queueHead && _running < _concurrency;) {
103 _running++
104 release()
105 }
106 }
107
108 function idle () {
109 return _running === 0 && self.length() === 0
110 }
111
112 function push (value, done) {
113 var current = cache.get()
114
115 current.context = context
116 current.release = release
117 current.value = value
118 current.callback = done || noop
119 current.errorHandler = errorHandler
120
121 if (_running >= _concurrency || self.paused) {
122 if (queueTail) {
123 queueTail.next = current
124 queueTail = current
125 } else {
126 queueHead = current
127 queueTail = current
128 self.saturated()
129 }
130 } else {
131 _running++
132 worker.call(context, current.value, current.worked)
133 }
134 }
135
136 function unshift (value, done) {
137 var current = cache.get()
138
139 current.context = context
140 current.release = release
141 current.value = value
142 current.callback = done || noop
143 current.errorHandler = errorHandler
144
145 if (_running >= _concurrency || self.paused) {
146 if (queueHead) {
147 current.next = queueHead
148 queueHead = current
149 } else {
150 queueHead = current
151 queueTail = current
152 self.saturated()
153 }
154 } else {
155 _running++
156 worker.call(context, current.value, current.worked)
157 }
158 }
159
160 function release (holder) {
161 if (holder) {
162 cache.release(holder)
163 }
164 var next = queueHead
165 if (next && _running <= _concurrency) {
166 if (!self.paused) {
167 if (queueTail === queueHead) {
168 queueTail = null
169 }
170 queueHead = next.next
171 next.next = null
172 worker.call(context, next.value, next.worked)
173 if (queueTail === null) {
174 self.empty()
175 }
176 } else {
177 _running--
178 }
179 } else if (--_running === 0) {
180 self.drain()
181 }
182 }
183
184 function kill () {
185 queueHead = null
186 queueTail = null
187 self.drain = noop
188 }
189
190 function killAndDrain () {
191 queueHead = null
192 queueTail = null
193 self.drain()
194 self.drain = noop
195 }
196
197 function abort () {
198 var current = queueHead
199 queueHead = null
200 queueTail = null
201
202 while (current) {
203 var next = current.next
204 var callback = current.callback
205 var errorHandler = current.errorHandler
206 var val = current.value
207 var context = current.context
208
209 // Reset the task state
210 current.value = null
211 current.callback = noop
212 current.errorHandler = null
213
214 // Call error handler if present
215 if (errorHandler) {
216 errorHandler(new Error('abort'), val)
217 }
218
219 // Call callback with error
220 callback.call(context, new Error('abort'))
221
222 // Release the task back to the pool
223 current.release(current)
224
225 current = next
226 }
227
228 self.drain = noop
229 }
230
231 function error (handler) {
232 errorHandler = handler
233 }
234}
235
236function noop () {}
237
238function Task () {
239 this.value = null
240 this.callback = noop
241 this.next = null
242 this.release = noop
243 this.context = null
244 this.errorHandler = null
245
246 var self = this
247
248 this.worked = function worked (err, result) {
249 var callback = self.callback
250 var errorHandler = self.errorHandler
251 var val = self.value
252 self.value = null
253 self.callback = noop
254 if (self.errorHandler) {
255 errorHandler(err, val)
256 }
257 callback.call(self.context, err, result)
258 self.release(self)
259 }
260}
261
262function queueAsPromised (context, worker, _concurrency) {
263 if (typeof context === 'function') {
264 _concurrency = worker
265 worker = context
266 context = null
267 }
268
269 function asyncWrapper (arg, cb) {
270 worker.call(this, arg)
271 .then(function (res) {
272 cb(null, res)
273 }, cb)
274 }
275
276 var queue = fastqueue(context, asyncWrapper, _concurrency)
277
278 var pushCb = queue.push
279 var unshiftCb = queue.unshift
280
281 queue.push = push
282 queue.unshift = unshift
283 queue.drained = drained
284
285 return queue
286
287 function push (value) {
288 var p = new Promise(function (resolve, reject) {
289 pushCb(value, function (err, result) {
290 if (err) {
291 reject(err)
292 return
293 }
294 resolve(result)
295 })
296 })
297
298 // Let's fork the promise chain to
299 // make the error bubble up to the user but
300 // not lead to a unhandledRejection
301 p.catch(noop)
302
303 return p
304 }
305
306 function unshift (value) {
307 var p = new Promise(function (resolve, reject) {
308 unshiftCb(value, function (err, result) {
309 if (err) {
310 reject(err)
311 return
312 }
313 resolve(result)
314 })
315 })
316
317 // Let's fork the promise chain to
318 // make the error bubble up to the user but
319 // not lead to a unhandledRejection
320 p.catch(noop)
321
322 return p
323 }
324
325 function drained () {
326 var p = new Promise(function (resolve) {
327 process.nextTick(function () {
328 if (queue.idle()) {
329 resolve()
330 } else {
331 var previousDrain = queue.drain
332 queue.drain = function () {
333 if (typeof previousDrain === 'function') previousDrain()
334 resolve()
335 queue.drain = previousDrain
336 }
337 }
338 })
339 })
340
341 return p
342 }
343}
344
345module.exports = fastqueue
346module.exports.promise = queueAsPromised
Note: See TracBrowser for help on using the repository browser.