Pipsqueak

Greenkeeper badge NPM version NPM downloads Build Status Code Climate Test Coverage Code Style Dependency Status devDependencies Status

Pipsqueak is an in memory interval based task scheduler, with support for promises, callbacks and synchronous functions. Pipsqueak is also the name of a Hamster. Hamsters like running in circles. A bit like an interval based task scheduler, but more cute.

Pipsqueak

Advantages Over setInterval / setTimeout

Pipsqueak allows you to:

Promise API

const { promiseApi: pipsqueak } = require('pipsqueak');

const factory = (ctx) => new Promise((resolve, reject) => {
  resolve(new Date().toISOString());
})

const p = pipsqueak({ name: 'example', factory: factory, interval: '1s', delay: '1s' })
  .on('begin', ({ name, run, }) => console.log(`begin: ${name}/${run}`))
  .on('end', ({ name, run, result }) => console.log(`end:   ${name}/${run} ${result}`))
  .on('error', ({ name, run, error }) => console.error(`error: ${name}/${run} ${error.message}`))
  .start();

n.b. In order for the promise to be re-evaluated a factory must be used

Callback API

const { callbackApi: pipsqueak } = require('pipsqueak');

const task = (ctx, cb) => cb(null, new Date().toISOString());

const p = pipsqueak({ name: 'example', task: task, interval: '1s', delay: '1s' })
  .on('begin', ({ name, run, }) => console.log(`begin: ${name}/${run}`))
  .on('end', ({ name, run, result }) => console.log(`end:   ${name}/${run} ${result[0]}`))
  .on('error', ({ name, run, error }) => console.error(`error: ${name}/${run} ${error.message}`))
  .start();

n.b. the results are an array

Synchronous API

const { synchronousApi: pipsqueak } = require('pipsqueak');

const task = (ctx) => new Date().toISOString();

const p = pipsqueak({ name: 'example', task: task, interval: '1s', delay: '1s' })
  .on('begin', ({ name, run, }) => console.log(`begin: ${name}/${run}`))
  .on('end', ({ name, run, result }) => console.log(`end:   ${name}/${run} ${result}`))
  .on('error', ({ name, run, error }) => console.error(`error: ${name}/${run} ${error.message}`))
  .start();

Output

begin: example/39195fc7-7035-48a2-9f73-ef6476ff3fdd
end:   example/39195fc7-7035-48a2-9f73-ef6476ff3fdd 2018-02-10T22:41:51.025Z
begin: example/2c3fc5c6-c5dd-4233-8979-21b047b443b6
end:   example/2c3fc5c6-c5dd-4233-8979-21b047b443b6 2018-02-10T22:41:56.028Z
begin: example/aa6b7d7f-608b-4469-b874-18fda2457a45
end:   example/aa6b7d7f-608b-4469-b874-18fda2457a45 2018-02-10T22:42:01.029Z

Advanced Usage

Multiple tasks

You can specify multiple tasks by passing pipsqueak an array instead of a map

const { promiseApi: pipsqueak } = require('pipsqueak');

const factory = (ctx) => new Promise((resolve, reject) => {
  resolve(new Date().toISOString());
})

const tasks = [
  { name: 'example-1', factory: factory, interval: '1s', delay: '1s' },
  { name: 'example-2', factory: factory, interval: '5s' },
]
const p = pipsqueak(tasks)
  .on('begin', ({ name, run, }) => console.log(`begin: ${name}/${run}`))
  .on('end', ({ name, run, result }) => console.log(`end:   ${name}/${run} ${result}`))
  .on('error', ({ name, run, error }) => console.error(`error: ${name}/${run} ${error.message}`))
  .start();

Intervals / Delays

You must set an interval, but an initial delay is optional. Values may be integers, parsable strings or if you want a random duration, an object containing max and optional min properties.

const { promiseApi: pipsqueak } = require('pipsqueak');

const factory = (ctx) => new Promise((resolve, reject) => {
  resolve(new Date().toISOString());
})

const interval = { min: '1m', max: '5m' };
const delay = { max: '1m' };
const p = pipsqueak({ name: 'example', factory, interval, delay }).start();

Stopping

Calling stop will cancel any schedule runs and prevent new runs from being scheduled. You can specify a shutdown timeout at a task level

const tasks = [
  { name: 'example-1', factory: factory, interval: '1s', timeout: '2s' },
  { name: 'example-2', factory: factory, interval: '5s', timeout: '5s' },
]

Promise API

const { promiseApi: pipsqueak } = require('pipsqueak');

const p = pipsqueak(tasks).start()
p.stop().then(() => {
  ...
}).catch(err => {
  console.error(err.message);
});

Callback API

const { callbackApi: pipsqueak } = require('pipsqueak');

const p = pipsqueak(tasks).start();
p.stop(function(err) {
  if (err) console.error(err.message);
  ...
})

Synchronous API

Synchronous tasks are blocking, so there’s no need to wait for them

Poking Tasks

You can force a task or tasks to run by poking them.

const p = pipsqueak(tasks).start();
p.poke();
p.poke('task1');
p.poke(['task1', 'task2']);

If pipsqueak is stopped, or the task was running or disabled, poking it will have no effect. If pipsqueak was not started, the task will be run once, but not scheduled. If pipsqueak was started, the next schedule will be cancelled, the task will be run once and rescheduled.

Disabling Tasks

If you want to configure, but disable a specific tasks (maybe because it should only run under specific conditions, set disabled to true, e.g.

pipsqueak({ name: 'example', task: task, interval: '1s', disabled: true })

Events

begin

Emitted whenever the task begins.

Property Type Description
name String The supplied task runner name.
run UUID Uniquely identifies the run.
iteration Integer The number of times the task has been executed
timestamp Integer The current time in millis

end

Emitted whenever the task finishes.

Property Type Description
name String The supplied task runner name.
run UUID Uniquely identifies the run.
iteration Integer The number of times the task has been executed
timestamp Integer The current time in millis
result Mixed The result of the task, passed the the callback, resolved or returned

error

Emitted whenever the task errors.

Property Type Description
name String The supplied task runner name.
run UUID Uniquely identifies the run.
iteration Integer The number of times the task has been executed
timestamp Integer Uniquely identifies the run.
error Error The error object thrown, rejected or passed to the callback

Debug

To run with debug enabled set DEBUG=pipsqueak