0.1.5 • Public • Published


    NPM version Build Status

    Co-Executioner wraps around generator functions managing execution to regulate heavy tasks by providing multi-level, configurable pooling and retry strategies, while allowing for inline non-blocking code.


    $ npm install co-executioner


    $ mocha


    Create an executioner

    const Executioner = require('co-executioner');
    executioner = new Executioner('executioner 0');

    Create a task

    const Task = Executioner.Task;
    task = new Task('simple task', function*() {
      // Do async operations
      return data; // data to resolve

    Execute the task

    const process =;  // Returns Process
    // Process implements then/catch as a native Promise
    process.then((data) => {
      // data returned by the generator
    process.catch((errors) => {
      // Array of errors, from every try/retry

    Basic yieldables

    You can yield a variety of object types and they will be handled accordingly.

    Generator and Generator functions

    When yielding a generator function, it is added to the process queue of the task and run until it is resolved. NOTE: If you want to actually return generator functions, you may wrap them in another object.

    data = yield function*() { return true };         // data = true
    data = yield function*() { return true }();       // data = true
    data = yield function*() { yield {               // data = function*
        data: function*(){ return true; }

    The generator function will be executed in the same way as the base generator function, under the same task, using the same configuration.


    Yielding promises will return the resolved value, or throw an error when rejected.


    Task objects that are yield, will run as sub-tasks, unless another executioner is set in its configuration.

    // data = data returned from anotherGenerator
    let data = yield new Task('sub', function*() { yield anotherGenerator(); });


    Arrays are tested to see if all elements are of one of the following types:

    • Generator
    • Generator Function
    • Task In each of the cases, the values will be resolved using threading. Note: An executioner may have a different count of threads and cores, arrays are parallelized using the number of threads, even tasks, unless tasks have a specified executioner
    let power = function*(data) { return data * data; }
    data = yield [0..10].map(power) // data = [0, 1, 4, 9, ...]


    Executioner considers values any non-aforementioned types and will return them as they are.


    The number of retries and the interval between them can be specified both on an executioner and task level. Once an Error object is yield or an exception is thrown, the executioner starts over the Process after waiting for an interval set in milliseconds and adds the error to a list. When the maximum number of retries is reached, the process will reject passing the array of errors. Note that nested Tasks will implement their retries individually, meaning that a yielded Task will not add to the number of retries of the parent Task.

    Configuration parameters:

    • retries: Number of retries before rejecting.
    • retryInterval: Time to wait between failure and retry in ms.


    Executioners and Tasks are configurable. For the shared parameters: Default Executioner configuration < Executioner < Task

    Executioner configuration [default values]:

    name: String                 // Name of the executioner ['default']
    retries: Number              // Number of retries before failure [1]
    retryInterval: Number        // Interval between failure and start of retry in ms [200]
    cores: Number                // Task pool size [1]
    threads: Number              // Maximum threads per Process [1]
    silent: Boolean              // Mute logging [false]
    pooling: Boolean             // Keep pool of active tasks, throttle execution to those [true]
    log: Function                // Custom log function, use with silent set to false
    timeout: Number              // Exceeding execution time (in ms) results in task failure. [0 - disabled]

    Task configuration

    name: String                 // Name of the task ['<anon>']
    retries: Number              // Number of retries before failure
    retryInterval: Number        // Interval between failure and start of retry in ms
    threads: Number              // Maximum threads
    heavy: Boolean               // If set to true, no other tasks will cycle while this Process is running
    timeout: Number              // Exceeding execution time (in ms) results in task failure. [0 - disabled]


    Co-Executioner comes with a set of templates to serve common usage patterns. You can easily access them as such:

    {Templates} = require('co-executioner');


    waiter can be yielded and it will wait for a set amount of ms before returning.


    functor takes in an array of functions that may return yieldables. The result of the functions is returned in an ordered array. The functor allows for threading, so the functions will be pooled and executed in order and on demand. For example, if you have 2 threads and pass 10 functions to the functor, it will first execute 2 of them, and if they return a yieldable it will wait for it to resolve before executing the next function in the array.

    callback(function(cb){}) [alias:promisify]

    callback (or promisify) takes in a node-style callback function and returns a yieldable. It will throw an error in case of non-null err.

    spawn(config, function*)

    spawn is a shortcut of new Task(...).


    sync will yield each element of the array in sequence, one-by-one, and return an ordered array of the results.




    npm i co-executioner

    DownloadsWeekly Downloads






    Unpacked Size

    86.1 kB

    Total Files


    Last publish


    • izotos
    • mbor