npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

co-executioner

v0.1.5

Published

Wrap, manage, throttle & pool deferred tasks

Downloads

10

Readme

Co-Executioner

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.

Install

$ npm install co-executioner

Tests

$ mocha

Usage

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 = executioner.run(task);  // 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.

Promises

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

Tasks

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

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, ...]

Values

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

Retry

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.

Configuration

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]

Templates

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(ms)

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

functor([fns])

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([yieldable])

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

License

MIT