4.13.1 • Published 7 years ago

promise-command v4.13.1

Weekly downloads
2
License
Apache-2.0
Repository
github
Last release
7 years ago

promise-command

Parallel execution of ES6 promises without Promise.all

Controlling parallel execution of promises

It allows control of parallelism like async.parallelLimit combined with better debug-capabilities and more flexibility.

Usage of ES6 features

it works only with node 6 and 7 with full es6-support

Simple-Example:

const Controller = require("promise-command");

const crawler =  //function for parallel execution with promises
  (obj) => Promise.resolve(obj)
  .then((obj) => {
    obj.message = null;

    return obj;
  })
  .then((obj) => controller.tester(obj));  //use test function

const controller = new Controller({
  parallel: 200,  // maximal parallism
  fun: crawler  //function to use
});

Promise.resolve()
  .then(() => {  // prepare array of data
    controller.daten = [];
    let count = 1000;
     for (let i = 0; i < count; i++) {
      controller.daten.push({
        id: i
      });
    }
    return controller.daten;
  })
  .then((res) => controller.runner(res))   //execute function over array
  .then((x) => {  // await results after completion
    console.log("finished",x);
  })
  .catch((err) => {
    console.error("exit with error",err);
  });

Overwriting the Controller-Class

class Controller1 extends require("promise-command") {
  constructor(param) {
    super(param);
      this.collector = [];  //collect the results
    }
    
    // overwrting of error handler
  errHandler(pos, err) {
    debug("error",err,pos);
    // delete the data  with errors in the source for repeating
    delete this.daten[pos.pos];  
    if ( this.errcollector.size > 30 ){  //stop only after 30 errors
      return true;
    } else {
      return false;
    }
  }
  
  
  //user handling of every completed object
  objHandler(pos, obj,input) { 
    //debug("hier da",pos,obj);
    
    this.collector[pos.id] = Object.assign(obj, {
      diff: process.hrtime(pos.start) //add timing
    }); //store endresult in order of start like Promise.all

  }
  
  //overwrite handling of end results
  endHandler(){
    if (this.errcollector.size > 30) { //throw with error
      debug("finished with error %d", this.errcollector.size);
      this.emit("ende", [...this.errcollector.entries()]);
        } else { // return the array of results
      debug("finished with gen");
          this.emit("ende", null,this.collector);
    }

  }

//overwrite data generation
  *
  dataGenerator(res) {

    try {
      const iter1 = this.makeIteratorFun(res, null, this.fun);  //prepare iterator fun,iterate over input data

//only 1 iteration over data,collector and iterator are seperate
//let first = yield* this.startAll([], () => iter1.next());

//repeat endless with iterator over data, until limit is reached, iterator works on collector
      let first = yield* this.startAll(res, () => iter1.next(), 30000); //start generator with iterator, limit 30000 iterations
// in first are now the executions which are finished, the still running executions are missing

      debug("wait now until finished");  
      const l = yield* this.waiterFinished(3000, true);  // wait unitl finished or 3secs passed
      debug("now end %d", l.length);

      return first.concat(l);  //all results
    } catch (err) {
      debug("error generator", err);
    }
  }

}

It implements and uses following features:

es6-class with extenstion of EventEmitter

the controller with all its variables is inside an es6-class. Every invocation produces a new controller-object which can be independently used.

generator functions

the user provides a generator function with generates calls of a user-defined function with an user supplied argument. The controller iterates the generator and produces parallel execution of a limited number of promises. There is a helper generator for iteration over an used-supplied iterator which generates the different arguments for every function execution. Inside the main generator different functions can be used.The user is in full controll. The only condition is that the function is promised based and .then and .catch can be appended. There is also a helper-generator for pausing execution until a specified point in time. During waiting the execution continues until the pipeline is empty.

maps

during execution every argument of the running functions together with an incrementing id is collected into a map. After finishing of execution it is deleted from the map. The execution which takes the longest time is always at the beginning of the map present. Controlling and debugging of execution is very easy.

collection-arrays

after execution the results are collected in an array like with Promise.all in the correct order of start. All errors are also collected into an array. There can be as many errors as executed functions.

EventEmitter

Every function call is supplemented with an event emitter at the end of the promise-chain.The event emitter transfers the result or the error into the control function.

promised based controll-function

after execution of every function call it is brought into the promise-chain of the controller and the results are collected. Errors are handled with a maximal number of allowed errors before termination. The controller only terminates when every executed function call is finished. There will be no dangling promises after termination.

end condition

If the generator stops generation of promises the controller waits until all running promises are finished and the terminates with success error depending on the number of errors. If there are too many errors or the limit of executions in the configuration is reached the controller terminates independently from the generator.

test-function

the controller contains a simple test-function which can be used for tests together with the user-supplied generator function.

limitations

the generation of promises can be endless or limited to a finite number. Every promise must terminate otherwise the controller can never end and the program must be terminated with process.exit.

4.13.1

7 years ago

4.13.0

7 years ago

4.12.1

7 years ago

4.12.0

7 years ago

4.11.0

7 years ago

4.10.1

7 years ago

4.10.0

7 years ago

4.9.0

7 years ago

4.8.1

7 years ago

4.8.0

7 years ago

4.7.2

7 years ago

4.7.1

7 years ago

4.7.0

7 years ago

4.6.4

7 years ago

4.6.3

7 years ago

4.6.2

7 years ago

4.6.1

7 years ago

4.6.0

7 years ago

4.5.4

7 years ago

4.5.3

7 years ago

4.5.2

7 years ago

4.5.1

7 years ago

4.4.1

7 years ago

4.5.0

7 years ago

4.4.0

7 years ago

4.3.0

7 years ago

4.2.8

7 years ago

4.2.7

7 years ago

4.2.6

7 years ago

4.2.5

7 years ago

4.2.4

7 years ago

4.2.3

7 years ago

4.2.2

7 years ago

4.2.1

7 years ago

4.2.0

7 years ago

4.1.0

7 years ago

4.0.8

7 years ago

4.0.7

7 years ago

4.0.6

7 years ago

4.0.5

7 years ago

4.0.4

7 years ago

4.0.3

7 years ago

4.0.2

7 years ago

4.0.1

7 years ago

4.0.0

7 years ago

3.9.0

7 years ago

3.8.0

7 years ago

3.7.0

7 years ago

3.6.0

7 years ago

3.5.0

7 years ago

3.3.1

7 years ago

3.4.0

7 years ago

3.3.0

7 years ago

3.2.3

8 years ago

3.2.2

8 years ago

3.2.1

8 years ago

3.2.0

8 years ago

3.1.0

8 years ago

3.0.1

8 years ago

3.0.0

8 years ago

2.0.0

8 years ago

1.2.0

8 years ago

1.1.6

8 years ago

1.1.5

8 years ago

1.1.4

8 years ago

1.1.3

8 years ago

1.1.2

8 years ago

1.1.1

8 years ago

1.1.0

8 years ago

1.0.0

8 years ago