all files / core/lib/ queue.js

100% Statements 36/36
100% Branches 10/10
100% Functions 5/5
100% Lines 31/31
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60            213× 213× 213× 213× 213× 213× 213× 213× 213× 213×   213×           161× 161×       471× 471× 471×   471× 710× 239×         239× 239× 239×       234× 234× 234×   234× 234× 234×   234×        
 
'use strict'
 
let Promise = require('bluebird')
 
class Queue {
  constructor (options) {
    this.factory = options.factory
    this.concurrency = options.concurrency
    this.available = options.available || []
    this.pending = new Set()
    this.done = new Set()
    this.resolve = null
    this.reject = null
    this.promise = new Promise((resolve, reject) => {
      this.resolve = resolve
      this.reject = reject
    })
    if (this.available.length) this.run()
  }
 
  add () {
    // FIXME: use the code below if we ever need to support >1 args
    // var args = arguments.length === 1 ? [ arguments[0] ] : Array.apply(null, arguments)
    this.available.push([ arguments[0] ])
    this.run()
  }
 
  run () {
    let available = this.available
    let pending = this.pending
    let concurrency = this.concurrency
 
    while (pending.size < concurrency) {
      if (available.length === 0) break
      this.start(available.shift())
    }
  }
 
  start (args) {
    let p = this.factory.apply(null, args)
    this.pending.add(p)
    p.then(() => this.finish(p, args)).catch(err => this.reject(err))
  }
 
  finish (p, args) {
    let available = this.available
    let pending = this.pending
    let done = this.done
 
    pending.delete(p)
    done.add(p)
    this.run()
 
    if (available.length === 0 && pending.size === 0) this.resolve()
  }
}
 
module.exports = Queue