Comparing version
// My non blocking main task | ||
var myTask = function(args,next) { | ||
// My non blocking main job | ||
var myjob = function(args,next) { | ||
@@ -9,8 +9,8 @@ // do nothing now but in 1 sec | ||
// if i'm task id 10 or 20, let's add | ||
// another task dynamicaly in the queue. | ||
// if i'm job id 10 or 20, let's add | ||
// another job dynamicaly in the queue. | ||
// It can be usefull for network operation (retry on timeout) | ||
if (args._taskId==10||args._taskId==20) { | ||
myQueueJobs.add(myTask,[999,'bla '+args._taskId]); | ||
if (args._jobId==10||args._jobId==20) { | ||
myQueueJobs.add(myjob,[999,'bla '+args._jobId]); | ||
} | ||
@@ -25,5 +25,5 @@ next(); | ||
// Let's add 30 task and add them to the queue | ||
// Let's add 30 job and add them to the queue | ||
for (var i = 0; i<30; i++) { | ||
myQueueJobs.add(myTask,[i,'test1']); | ||
myQueueJobs.add(myjob,[i,'test1']); | ||
} | ||
@@ -34,2 +34,3 @@ | ||
console.log('starting ...'); | ||
console.log(JSON.stringify(myQueueJobs.stats())); | ||
}); | ||
@@ -41,17 +42,18 @@ | ||
console.log('end'); | ||
console.log(JSON.stringify(myQueueJobs.stats())); | ||
}); | ||
// I want to know when each job has started | ||
myQueueJobs.on('taskStart',function(args) { | ||
console.log('taskStart',args); | ||
myQueueJobs.on('jobStart',function(args) { | ||
console.log('jobStart',args); | ||
}); | ||
// I want to know when each job has ended | ||
myQueueJobs.on('taskEnd',function(args) { | ||
myQueueJobs.on('jobEnd',function(args) { | ||
console.log('taskEnd',args); | ||
console.log('jobEnd',args); | ||
// If i'm taskId 10, then make a pause of 5 sec | ||
// If i'm jobId 10, then make a pause of 5 sec | ||
if (args._taskId == 10) { | ||
if (args._jobId == 10) { | ||
myQueueJobs.pause(true); | ||
@@ -74,3 +76,3 @@ setTimeout(function() { | ||
var statId = setInterval(function() { | ||
console.log(myQueueJobs.stats()); | ||
console.log(JSON.stringify(myQueueJobs.stats())); | ||
},1000); |
{ | ||
"name": "qjobs", | ||
"version": "1.0.7", | ||
"version": "1.0.8", | ||
"description": "qjobs is a simple and stupid queue job manager for nodejs", | ||
@@ -10,4 +10,7 @@ "main": "qjobs.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "make test" | ||
}, | ||
"engines": { | ||
"node": "*" | ||
}, | ||
"repository": { | ||
@@ -25,5 +28,5 @@ "type": "git", | ||
"author": "Franck TABARY", | ||
"license": "BSD", | ||
"license": "BeerWare", | ||
"readmeFilename": "Readme.md", | ||
"gitHead": "6b6ea2dd626799e946ab700e4c4902ab792d3bb2" | ||
} |
103
qjobs.js
@@ -14,7 +14,7 @@ | ||
var lastPause = 0; | ||
var lastNow; | ||
var previousJobsDone; | ||
var previousCpt; | ||
var previousTimeRemaining; | ||
var interval = null; | ||
var stopAdding = false; | ||
var sleeping = false; | ||
/* | ||
@@ -27,2 +27,8 @@ * helper to set max concurrency | ||
/* | ||
* helper to set delay between rafales | ||
*/ | ||
var setInterval = function(delay) { | ||
interval = delay; | ||
} | ||
@@ -37,3 +43,40 @@ /* | ||
/* | ||
* | ||
*/ | ||
var sleepDueToInterval = function() { | ||
if (interval === null) return; | ||
if (sleeping) { | ||
return true; | ||
} | ||
if (stopAdding) { | ||
if (jobsRunning > 0) { | ||
//console.log('waiting for '+jobsRunning+' jobs to finish'); | ||
return true; | ||
} | ||
//console.log('waiting for '+rafaleDelay+' ms'); | ||
sleeping = true; | ||
module.exports.emit('sleep'); | ||
setTimeout(function() { | ||
stopAdding = false; | ||
sleeping = false; | ||
module.exports.emit('continu'); | ||
run(); | ||
},interval); | ||
return true; | ||
} | ||
if (jobsRunning + 1 == maxConcurrency) { | ||
//console.log('max concurrent jobs reached'); | ||
stopAdding = true; | ||
return true; | ||
} | ||
} | ||
/* | ||
@@ -48,11 +91,13 @@ * run the queue | ||
timeStart = Date.now(); | ||
lastNow = timeStart; | ||
} | ||
if (sleepDueToInterval()) return; | ||
// while queue is empty and number of job running | ||
// concurrently are less than max job running, | ||
// then launch the next job | ||
while (jobsList.length && jobsRunning<maxConcurrency) { | ||
// get the next job and remove it from the queue | ||
while (jobsList.length && jobsRunning < maxConcurrency) { | ||
// get the next job and | ||
// remove it from the queue | ||
var job = jobsList.shift(); | ||
@@ -66,14 +111,9 @@ | ||
// add an internal identifiant for | ||
// hypothetical external use | ||
// add jobId in args | ||
args._jobId = jobId++; | ||
//args.__jobsTotal = jobsTotal; | ||
//args.__timeStart = timeStart; | ||
//args.__progress= Math.ceil(((jobsDone+1)/jobsTotal)*100); | ||
// emit taskStart event before launch the job | ||
module.exports.emit('taskStart',args); | ||
// emit jobStart event | ||
module.exports.emit('jobStart',args); | ||
// run the job, passing args, next() function, | ||
// binded to 'this' | ||
// run the job | ||
job[0](job[1],next.bind(this,args)); | ||
@@ -83,5 +123,4 @@ | ||
// if we really finish all the jobs, let's end | ||
if (jobsList.length==0 && jobsRunning==0) { | ||
// emit 'end' event | ||
// all jobs done ? emit end event | ||
if (jobsList.length == 0 && jobsRunning == 0) { | ||
module.exports.emit('end'); | ||
@@ -101,4 +140,4 @@ } | ||
// emit 'taskEnd' event | ||
module.exports.emit('taskEnd',args); | ||
// emit 'jobEnd' event | ||
module.exports.emit('jobEnd',args); | ||
@@ -137,21 +176,6 @@ // if queue has been set to pause | ||
var now = Date.now(); | ||
var cpt = jobsTotal-jobsDone; | ||
//+jobsRunning; | ||
var o = {}; | ||
o._timeStart = timeStart||'N/A'; | ||
o._timeElapsed = now - timeStart||'N/A'; | ||
/* TODO: fix me | ||
if (paused) { | ||
o._timeRemaining = 'N/A'; | ||
} else { | ||
o._jobsPerSec = Math.ceil(((now-lastNow)/1000)*(jobsDone-previousJobsDone)); | ||
if (previousCpt!=cpt) { | ||
o._timeRemaining = Math.round((o._jobsPerSec * cpt)/1000)/60; | ||
} else { | ||
o._timeRemaining = previousTimeRemaining; | ||
} | ||
} | ||
*/ | ||
o._jobsTotal = jobsTotal; | ||
@@ -165,3 +189,3 @@ o._jobsRunning = jobsRunning; | ||
} else { | ||
if (!o._timeElapsed) { | ||
if (o._timeElapsed=='N/A') { | ||
o._status = 'Starting'; | ||
@@ -176,6 +200,2 @@ } else { | ||
} | ||
previousJobsDone = jobsDone; | ||
previousCpt = cpt; | ||
previousTimeRemaining = o._timeRemaining; | ||
lastNow = now; | ||
return o; | ||
@@ -189,2 +209,3 @@ } | ||
module.exports.setConcurrency = setConcurrency; | ||
module.exports.setInterval = setInterval; | ||
module.exports.stats = stats; |
@@ -1,36 +0,40 @@ | ||
**qjobs is a simple and stupid queue job manager for nodejs.** | ||
[](http://travis-ci.org/franck34/qjobs) | ||
* concurrency limiter | ||
* dynamic queue (a job can be add while the queue is treated) | ||
* event based, can be usefull to plug within pub/sub stuffs | ||
* non blocking (of course), but a job itself can run async code | ||
* really simple to use | ||
* really simple to understand | ||
**qjobs** | ||
================== | ||
***Efficient queue job manager module for nodejs.*** | ||
Features | ||
-------------- | ||
* Concurrency limiter | ||
* Dynamic queue, a job can be added while the queue is running | ||
* Optional delay before continuing after max concurrency has been reached | ||
* Support of pause/unpause | ||
* Events emitter based: start, end, sleep, continu, jobStart, jobEnd | ||
* Quick statistic function, so you can know where the queue is, at regular interval | ||
**Compatibility :** | ||
* not tested with nodejs < 0.10 | ||
For what it can be usefull ? | ||
--------------------- | ||
Jobs which needs to run in parallels, but in a controled maner, example: | ||
* Network scanners | ||
* Parallels monitoring jobs | ||
* Images/Videos related jobs | ||
**Help needed :** | ||
* i have no idea how to make unit tests | ||
Compatibility : | ||
------------------ | ||
* not tested with nodejs < 0.10 | ||
**Example :** | ||
``` | ||
Examples | ||
-------------------- | ||
// My non blocking main task | ||
var myTask = function(args,next) { | ||
(take a look at tests directory if you are looking for running samples) | ||
// do nothing now but in 1 sec | ||
``` | ||
// My non blocking main job | ||
var myjob = function(args,next) { | ||
setTimeout(function() { | ||
// if i'm task id 10 or 20, let's add | ||
// another task dynamicaly in the queue. | ||
// It can be usefull for network operation (retry on timeout) | ||
if (args._taskId==10||args._taskId==20) { | ||
myQueueJobs.add(myTask,[999,'bla '+args._taskId]); | ||
} | ||
console.log('Do something interesting here',args); | ||
next(); | ||
@@ -40,34 +44,31 @@ },1000); | ||
// Notice the "new" before require, to be able to use more | ||
// than one queue independently | ||
// qjobs stuff | ||
var myQueueJobs = new require('qjobs'); | ||
// Let's add 30 task and add them to the queue | ||
// Let's add 30 job to the queue | ||
for (var i = 0; i<30; i++) { | ||
myQueueJobs.add(myTask,[i,'test1']); | ||
myQueueJobs.add(myjob,[i,'test '+i]); | ||
} | ||
// I want to know when the first job has started | ||
// Initialize all events | ||
myQueueJobs.on('start',function() { | ||
console.log('starting ...'); | ||
console.log('Starting ...'); | ||
}); | ||
// I want to know when the last job has ended | ||
myQueueJobs.on('end',function() { | ||
console.log('end'); | ||
console.log('... All jobs done'); | ||
}); | ||
// I want to know when each job has started | ||
myQueueJobs.on('taskStart',function(args) { | ||
console.log('taskRun',args); | ||
myQueueJobs.on('jobStart',function(args) { | ||
console.log('jobStart',args); | ||
}); | ||
// I want to know when each job has ended | ||
myQueueJobs.on('taskEnd',function(args) { | ||
myQueueJobs.on('jobEnd',function(args) { | ||
console.log('taskend',args); | ||
console.log('jobend',args); | ||
// If i'm taskId 10, then make a pause of 5 sec | ||
// If i'm jobId 10, then make a pause of 5 sec | ||
if (args._taskId == 10) { | ||
if (args._jobId == 10) { | ||
myQueueJobs.pause(true); | ||
@@ -74,0 +75,0 @@ setTimeout(function() { |
Misc. License Issues
License(Experimental) A package's licensing information has fine-grained problems.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
12048
40.68%9
125%0
-100%334
63.73%1
-50%90
1.12%4
300%