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

bossman

v2.0.0

Published

Distributed job scheduling in node, based on redis.

Downloads

8

Readme

bossman

Stupid simple distributed job scheduling in node, backed by redis.

npm Version License Build Status Coverage Status

Bossman combines schedulers and workers into a single concept, which aligns better with most node applications. All of the jobs run with a redis lock, preventing more than once instance from performing a given job at a time.

Usage

Bossman is published on npm, and can be installed simply:

npm install bossman --save

Or if you use Yarn in your project:

yarn add bossman

You can then import the module and use it normally. For more details, see the API documentation.

import Bossman from 'bossman';

// Make sure you name your variables clever things:
const fred = new Bossman({
  connection: {
    host: '127.0.0.1',
    port: 1234,
  },
  // Set the redis key prefix:
  prefix: 'bossman:',
});

// Hire for a job.
fred.hire('engineers', {
  every: '10 minutes',
  work: () => {
    // Do something...
  },
});

// Hire something as soon as possible:
fred.demand('engineers');

// You can also "qa" work:
fred.qa((jobName, jobDefinition, next) => {
  return next();
});

// Fire a job, this will cancel any pending jobs:
fred.fire('engineers');

// Shut down our instance.
fred.quit();

API

new Bossman(options: Object)

Creates a new bossman instance. All arguments are optional.

  • options.connection: Used to configure the connection to your redis. This accepts the same arguments that ioredis does.
  • options.prefix: A string that all redis keys will be prefixed with. Defaults to bossman.
  • options.ttl: The number of milliseconds before a job times out. Setting it will change the maximum duration that jobs can hold a lock. By default, job locks will timeout if a job does not complete in 2000ms.

bossman.hire(jobName: String, jobDefinition: Object)

Schedules recurring work to be done.

  • jobName: A unique name for the job.
  • jobDefinition: The job definition can contain three properties: work, every, and cron.
    • jobDefinition.work: A function that is invoked to perform the job. If the work is async, this function should return a promise to properly reflect the completion of the job.
    • jobDefinition.every: A string which describes the interval the job will be run. This can either be a human-friendly string (which will be parsed by the timestring module), or a number reflecting the milliseconds to wait between each job run.
    • jobDefinition.cron: A string used to schedule work in more complex intervals. These are parsed with cron-parser.

It's possible to omit the every or cron properties if you don't wish to schedule recurring work, and just want to register a job.

bossman.demand(jobName: String)

Runs a job as soon as possible, outside of the scheduled jobs. Demanded jobs still run with the same locking mechanism that scheduled jobs run with, ensuring only one instance runs the job at a time. This does not prevent any scheduled jobs from running, unless the demand is running at the same time as a scheduled job and all instances fail to acquire a lock on the job.

bossman.qa(qaFunction: Function)

QA is used to registers functions that will invoked any time a job is run. This function can be called multiple times to register multiple QA functions. The passed qaFunction function will be called with jobName, and jobDefinition from the hire function, as well as a next function, which should be called when the QA function is complete. The next function returns a promise that can be used to get

For example, here is what a time logging QA function might look like.

bossman.qa((jobName, jobDefinition, next) => {
  const startTime = Date.now();
  return next().then(() => {
    const endTime = Date.now();
    logToServer(`${jobName} completed in ${endTime - startTime}ms`);
  })
});

bossman.fire(jobName: String)

Cancels any scheduled jobs with name jobName. This does not stop any demanded jobs from running.

bossman.quit()

Shuts down a bossman instance, closing all redis connections. This does not cancel any scheduled work, and does not stop it from running in any other bossman instances.

How it works

Constructing a new bossman instance sets up an expired key listener on your redis database. When you hire for a new job, Bossman sets a key in Redis that expire when the first run should occur. When the key expires, the expired key listener is called and Bossman does the following:

  1. Attempt to get a lock to perform the work. Only one instance of bossman will acquire the lock.
  2. If the lock is acquired, then perform the work and move on.
  3. If the lock is not acquired, then move on.
  4. Schedule the next run of the job by setting a key that expires when the next run should occur.

It's worth noting that every instance of Bossman attempts to schedule the next run of the job. This is okay because Redis will only schedule the first one that it receives, thanks to the NX option in SET. Calling demand performs the same operation as hire, except with a special key for demands.