Permalink
Browse files

init

  • Loading branch information...
0 parents commit a503266025f13ee7109a40213425469b9bc6ff0b @kilianc committed Oct 9, 2011
Showing with 212 additions and 0 deletions.
  1. +22 −0 LICENSE
  2. +93 −0 README.md
  3. +93 −0 lib/fnqueue.js
  4. +4 −0 package.json
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2011 Kilian Ciuffolo, me@nailik.org
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,93 @@
+# node-fnqueue ![project status](http://dl.dropbox.com/u/2208502/maintained.png)
+
+A powerful utility for function chaining (inspired by [async](https://github.com/caolan/async)).
+
+## Dependencies
+
+- nodejs v0.4.12+
+
+## Installation and first run
+
+ $ git clone git://github.com/kilian/node-fnqueue.git
+
+## Usage
+
+Parameters:
+
+- Object of functions
+- Global callback
+- Concurrency level (default is max possible)
+
+Each field of first parameter (Functions object) must be an Array / Function.
+
+If you pass an Array you are declaring a needed dependency with another function, otherwise you are passing a Function, then you are declaring a dependency less step.
+
+Each function with a dependency is called with the result of the depended function as parameter.
+
+The global callback is called on the first error, or at the end of all functions. The first parameter is the err (if provided) and the second one is a data object with the result of the chain.
+
+FnQueue magically resolves all dependencies and executes functions in the right order with the provided concurrency level.
+
+ var FnQueue = require('node-fnqueue');
+or for a verbose mode:
+
+ var FnQueue = require('node-fnqueue').verbose();
+
+Example:
+
+ new FnQueue({
+ funnyStuff: ['processSomething', 'searchSomething', function(time, searchResults, callback){
+ // do something silly
+ callback(null, 'ciao!');
+ }],
+ searchSomething: function(callback){
+ // do something with database
+ callback(err, results);
+ },
+ update: ['searchSomething', function(searchResults, callback){
+ // change values inside results and save to db
+ callback(err); // no needs to return values
+ }],
+ processSomething: ['searchSomething', function(searchResults, callback){
+ var start = new Date().getTime();
+ // write a file log
+ var elapsedTime = new Date().getTime() - start;
+ callback(err, elapsedTime); // logs write time;
+ }]
+ },function(err, data){
+
+ if(err)
+ throw err;
+
+ console.log(data.searchSomething); // results
+ console.log(data.update); // undefined
+ console.log(data.processSomething); // elapsedTime
+ console.log(data.funnyStuff); // 'ciao!'
+ }, 1);
+
+## License
+
+_This software is released under the MIT license cited below_.
+
+ Copyright (c) 2010 Kilian Ciuffolo, me@nailik.org. All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the 'Software'), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,93 @@
+function FnQueue(tasks, callback, concurrecyLevel){
+ this.tasks = tasks;
+ this.callback = callback;
+ this.results = {};
+ this.concurrecyLevel = concurrecyLevel || 'auto';
+ this.runningNb = 0;
+ this.callNextFunction();
+};
+
+FnQueue.verbose = function(){
+ FnQueue.prototype.isVerbose = false;
+ return FnQueue;
+};
+
+FnQueue.prototype.isVerbose = true;
+
+FnQueue.prototype.onTaskComplete = function(taskName, err, result){
+
+ this.runningNb--;
+
+ if(err){
+ this.callback && this.callback(err, this.results);
+ return;
+ }
+
+ this.results[taskName] = result || null;
+ this.callNextFunction();
+};
+
+FnQueue.prototype.callNextFunction = function(){
+
+ var dependencies, finish = true, args;
+
+ for(var taskName in this.tasks){
+
+ if(this.concurrecyLevel != 'auto' && this.runningNb >= this.concurrecyLevel)
+ return;
+
+ dependencies = this.tasks[taskName];
+ finish = false;
+
+ // no dependecies declared
+ if(dependencies instanceof Function){
+
+ this.isVerbose && console.log('FnQueue executing: ' + taskName);
+
+ this.runningNb++;
+ delete this.tasks[taskName];
+ dependencies(this.onTaskComplete.bind(this, taskName));
+
+ break;
+ }
+
+ args = this.getDependencies(dependencies);
+
+ if(args){
+
+ args.push(this.onTaskComplete.bind(this, taskName));
+
+ this.isVerbose && console.log('FnQueue executing: ' + taskName);
+
+ this.runningNb++;
+ delete this.tasks[taskName];
+ dependencies.pop().apply(null, args);
+
+ if(this.concurrecyLevel != 'auto' && this.runningNb >= this.concurrecyLevel)
+ return;
+ }
+ }
+
+ finish && !this.runningNb && this.callback && this.callback(null, this.results);
+};
+
+FnQueue.prototype.getDependencies = function(dependencies){
+
+ var args = [];
+
+ for(var i = 0; i < dependencies.length-1; i++){
+
+ if(this.results[dependencies[i]] === undefined){
+ return false;
+ }
+
+ var arg = this.results[dependencies[i]];
+
+ if(arg !== undefined)
+ args.push(arg);
+ }
+
+ return args;
+};
+
+module.exports = FnQueue;
@@ -0,0 +1,4 @@
+{
+ "name" : "fnqueue",
+ "main" : "./lib/fnqueue.js"
+}

0 comments on commit a503266

Please sign in to comment.