Comparing version 0.0.2 to 0.1.0
@@ -1,26 +0,27 @@ | ||
var util = require('util'), | ||
EventEmitter = require('events').EventEmitter, | ||
Task = require('./task.js').Task; | ||
'use strict'; | ||
function Pool(options) { | ||
EventEmitter.call(this); | ||
const EventEmitter = require('events').EventEmitter; | ||
const Task = require('./task.js').Task; | ||
class Pool extends EventEmitter { | ||
constructor(options) { | ||
super(); | ||
options = options || {}; | ||
this.timeout = options.timeout || 10000; | ||
this.style = options.style || 'callback'; | ||
this.limit = options.limit || 10; | ||
this.running = 0; | ||
this.queue = []; | ||
} | ||
} | ||
util.inherits(Pool, EventEmitter); | ||
Pool.prototype.next = function() { | ||
next() { | ||
this.running--; | ||
if (!this.start() && !this.running) { | ||
this.emit('idle'); | ||
this.emit('idle'); | ||
} | ||
}; | ||
} | ||
Pool.prototype.start = function() { | ||
start() { | ||
if (this.running >= this.limit) return true; | ||
var task = this.queue.shift(); | ||
const task = this.queue.shift(); | ||
if (!task) return false; | ||
@@ -30,25 +31,36 @@ this.running++; | ||
return true; | ||
}; | ||
} | ||
Pool.prototype.add = function(task) { | ||
add(task) { | ||
task.pool = this; | ||
this.queue.push(task); | ||
this.start(); | ||
}; | ||
} | ||
Pool.prototype.wrap = function(fn, options) { | ||
var timeout = this.timeout || options.timeout; | ||
var self = this; | ||
return function() { | ||
var task = new Task({ | ||
fn: fn.bind(this), | ||
timeout: timeout, | ||
args: [].slice.call(arguments) | ||
}); | ||
self.add(task); | ||
return task; | ||
wrap(fn, options) { | ||
options = options || {}; | ||
const timeout = options.timeout || this.timeout; | ||
const style = options.style || this.style; | ||
return function wrapped() { | ||
const task = new Task({ | ||
fn, | ||
timeout, | ||
style, | ||
args: [].slice.call(arguments), | ||
}); | ||
this.add(task); | ||
return task; | ||
}.bind(this); | ||
} | ||
get promise() { | ||
this.wrap = (fn, options) => { | ||
delete this.wrap; | ||
return this.wrap(fn, Object.assign({ style: 'promise' }, options)); | ||
}; | ||
}; | ||
return this; | ||
} | ||
} | ||
exports.Task = Task; | ||
exports.Pool = Pool; |
@@ -1,8 +0,15 @@ | ||
var util = require('util'), | ||
EventEmitter = require('events').EventEmitter; | ||
'use strict'; | ||
function Task(options) { | ||
const EventEmitter = require('events').EventEmitter; | ||
class Task extends EventEmitter { | ||
constructor(options) { | ||
super(); | ||
this.timeout = options.timeout; | ||
this.args = options.args; | ||
this.fn = options.fn; | ||
this.style = options.style || 'callback'; | ||
this.promise = new Promise(resolve => this.on('run', resolve)); | ||
this.then = this.promise.then.bind(this.promise); | ||
this.catch = this.promise.catch.bind(this.promise); | ||
this.running = false; | ||
@@ -12,39 +19,43 @@ this.done = false; | ||
this.timedOut = false; | ||
EventEmitter.call(this); | ||
} | ||
} | ||
util.inherits(Task, EventEmitter); | ||
Task.prototype.run = function() { | ||
var callback, self = this; | ||
if (typeof this.args[this.args.length - 1] == 'function') { | ||
callback = this.args.pop(); | ||
run() { | ||
let callback; | ||
if (this.style !== 'promise' && typeof this.args[this.args.length - 1] === 'function') { | ||
callback = this.args.pop(); | ||
} | ||
this.args.push(function() { | ||
self.done = true; | ||
self.running = false; | ||
if (callback) { | ||
callback.apply(null, [].slice.call(arguments)); | ||
const resolve = function resolve() { | ||
this.done = true; | ||
this.running = false; | ||
if (callback) { | ||
callback.apply(null, [].slice.call(arguments)); | ||
} | ||
this.emit('end'); | ||
if (!this.timedOut) { | ||
clearTimeout(this.timer); | ||
if (this.pool) { | ||
this.pool.next(); | ||
} | ||
self.emit('end'); | ||
if (!self.timedOut) { | ||
clearTimeout(self.timer); | ||
if (self.pool) { | ||
self.pool.next(); | ||
} | ||
} | ||
}); | ||
} | ||
}.bind(this); | ||
if (this.style !== 'promise') { | ||
this.args.push(resolve); | ||
} | ||
this.started = this.running = true; | ||
this.result = this.fn.apply(null, this.args); | ||
if (this.style === 'promise') { | ||
this.result.then(resolve, resolve); | ||
} | ||
this.emit('run', this.result); | ||
this.timer = setTimeout(function() { | ||
self.timedOut = true; | ||
self.emit('timeout'); | ||
if (self.pool) { | ||
self.pool.emit('timeout', self); | ||
self.pool.next(); | ||
} | ||
this.timer = setTimeout(() => { | ||
this.timedOut = true; | ||
this.emit('timeout'); | ||
if (this.pool) { | ||
this.pool.emit('timeout', this); | ||
this.pool.next(); | ||
} | ||
}, this.timeout); | ||
}; | ||
} | ||
} | ||
exports.Task = Task; |
{ | ||
"name": "task-pool", | ||
"version": "0.0.2", | ||
"description": "A generic pool to limit number of running asynchronous tasks.", | ||
"keywords": ["task", "pool", "queue", "async"], | ||
"version": "0.1.0", | ||
"description": "A generic pool to limit number of running asynchronous tasks or promises.", | ||
"keywords": [ | ||
"task", | ||
"pool", | ||
"queue", | ||
"promise", | ||
"async" | ||
], | ||
"author": "Ali Farhadi <a.farhadi@gmail.com>", | ||
"engines": { | ||
"node": ">=0.8.0" | ||
"node": ">=4.0.0" | ||
}, | ||
"main": "./lib/pool", | ||
"scripts": { | ||
"cover": "istanbul cover _mocha", | ||
"test": "mocha" | ||
}, | ||
"repository": { | ||
@@ -15,8 +25,8 @@ "type": "git", | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "MIT", | ||
"url": "https://raw.github.com/farhadi/task-pool/master/LICENSE" | ||
} | ||
] | ||
"license": "MIT", | ||
"devDependencies": { | ||
"coveralls": "^2.11.9", | ||
"istanbul": "^0.4.4", | ||
"mocha": "^2.5.3" | ||
} | ||
} |
task-pool | ||
========= | ||
A generic pool to limit number of running asynchronous tasks. | ||
A generic pool to limit number of running asynchronous tasks or promises. | ||
[![Build Status](https://travis-ci.org/farhadi/task-pool.png)](https://travis-ci.org/farhadi/task-pool) | ||
[![Coverage Status](https://coveralls.io/repos/github/farhadi/task-pool/badge.svg?branch=master)](https://coveralls.io/github/farhadi/task-pool?branch=master) | ||
Installation | ||
@@ -23,3 +26,3 @@ ------------ | ||
//Create a new pool with a maximum number of 20 tasks at a time. | ||
//Tasks taking longer than 5 seconds countinue their journey out of the poolto leave space for new tasks. | ||
//Tasks taking longer than 5 seconds continue their journey out of the pool to leave space for new tasks. | ||
var pool = new Pool({limit: 20, timeout: 5000}); | ||
@@ -51,4 +54,21 @@ | ||
You can also wrap a function that returns a promise: | ||
``` javascript | ||
//Create a wrapper around exec | ||
var exec = pool.promise.wrap(require('child-process-promise').exec); | ||
//An array of commands to be executed using exec. | ||
var tasks = [ ... ]; | ||
for (i = 0; i < tasks.length; i++) { | ||
exec(tasks[i]).then(result) { | ||
//Do some process on the result | ||
}).catch(error, function(error) { | ||
//Do something when an error occurs | ||
}); | ||
} | ||
``` | ||
License | ||
------- | ||
task-pool is released under the MIT license. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9583
10
198
73
3
1