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

krew

v0.2.4

Published

Minimalistic and flexible framework to implement microservice-like workers

Downloads

27

Readme

krew

License NPM Package NPM Downloads Build Status Test Coverage Code Climate Dependency Status devDependency Status

Author: Kurt Pattyn.

Krew is a minimalistic and flexible framework to implement microservice-like workers. It frees the programmer from implementing messaging protocols and communication infrastructure and lets the developer concentrate on the business logic.

Motivation

Implementing a microservice worker requires setting up messaging middleware (in case a message queue is used) and defining a common protocol to exchange messages.
Although not difficult, this requires a lot of boilerplate code.
Krew helps with this by taking away all this boilerplate from the developer by leveraging the excellent Kimbu module.

Installation

$ npm install krew

or

$ npm install krew --production

for a production only installation (no tests, documentation, ...).

Supported Node Versions

Krew supports Node versions 0.12 and later.
To use Krew with Node versions < 4.0, you must start node with the --harmony flag.

Usage

  var Worker = require("krew").Worker;
  var Transport = require("kimbu").Transport;
  var RabbitMQTransport = Transport.providers.RabbitMQTransport;
  var rmq = new RabbitMQTransport();  //use default options

  function calculatorMultiply(parameters, next) {
    console.log("Received calculator.multiply with parameters", parameters);
    var result = parameters.reduce(function(previousValue, currentValue, index, array) {
      return previousValue * currentValue;
    });

    next(result);
  }

  function somethingHappened(parameters, next) {
    console.log("Received something.happened event with content:", parameters);
    next();
  }

  var worker = new Worker("myWorker", rmq, {
    "calculator.multiply": calculatorMultiply,
    "something.happened": somethingHappened
  });
  
  worker.start();

In this example, we first create a transport to use for the worker to send and receive messages (see also Kimbu).
Then a worker is created with a name (myWorker), a transport (rmq) and an options hash declaring the messages this worker processes (calculator.multiply will be processed by calculatorMultiply(), something.happened will be processed by somethingHappened()).
The callback methods receive the parameters that were sent together with a next() callback ( comparable with the next() method of the express middleware handlers; see http://expressjs.com/es/guide/using-middleware.html).
The next() callback must be called when the message has been processed.
In the case of a command, next should be called with the result (or with an error) as in the calculatorMultiply method above.
In case of an event, next should be called without any parameters.
Finally, the worker is started (worker.start()).

To quickly test if the above example works, the worker can send messages to itself like:

  ...
  worker.start(function(err) {
    if (!err) {
      worker.request("calculator.multiply", [1, 2, 3], function(err, reply) {
        console.log("The result is:", reply);
      });
      worker.publish("something.happened", "The sun went down.");
    }
  });

Examples

Examples can be found under the examples subdirectory.

Quick Start

To quickly generate a worker, you can use the Krew Yeoman Generator.
This generator sets up a new worker, generating all the boilerplate you need to get started.

API

new Worker(workerName, transport, messageHash)

Creates a new worker with the given workerName.
The worker will use the given transport for commmunication and will process the messages given in messageHash.

Parameters

  • workerName (String, required): name of the worker; this name must be unique within the messaging framework
  • transport (Transport, required): the transport to use for exchanging messages
  • messageHash (Object, required): a hash containing message to callback mappings
    Format: { "messageName": messageHandler }, where messageHandler will be called with two arguments: parameters and next. next must be called when the message has been processed.
    In the case of a command (request-reply style of messaging) next must be called with the result of the command or with an Error object to indicate a failure.
    In the case of an event (publish-subscribe style of messaging) next should be called without arguments.
    See example below for an example of both uses.

Example

  var myWorker = new Worker("myWorker", rmq, {
    "someCommand": processSomeCommand,
    "someEvent": processSomeEvent
  });
  
  function processSomeCommand(parameters, next) {
    console.log("Received some command with parameters", parameters);
    var result = "some result";
    next(result);  //call next() with the result when finished processing!
    
    //or: next(new Error("Can only multiply integers, not strings!");
  };
  
  function processSomeEvent(parameters, next) {
    console.log("Received some event with parameters", parameters);
    next();  //call next() when finished processing!
  };

worker.start(callback)

Starts the worker. When started the worker will begin processing incoming commands and events.
When the worker is successfully started a ready event is emitted (see event("ready")) and you can start issuing requests and publishing events yourself (see example). When the worker failed to start, an error event is emitted (see event("error")). If a callback is supplied, it is called when the worker either started successfully or failed to start.

Parameters

  • callback (Function, optional): called when the worker started successfully or failed. It takes an 'Error' argument (nodejs style).

Example

  var myWorker = new Worker(...);
  
  myWorker.start(function(err) {
    if (err) {
      console.error("Oops, something went wrong", err);
      process.exit(-1);
    } else {
      //now we can make requests ourselves
      //yes, parameters can be objects as well
      myWorker.request("say.something.funny", { name: "krew", version: { major: 1, minor: 0 } }, function(err, reply) {
        if (err) {
          console.error("Oops, someone had a problem saying something funny", err);
        } else {
          console.log("Someone said something funny:", reply);
        }
      });
      myWorker.publish("important.notification", "I am alive and kicking");
    }
  });

worker.stop(callback)

Stops the worker. When stopped the worker will stop processing incoming commands and events.
If a callback is supplied, it is called when the worker either stopped successfully or failed to stop.

worker.request(commandName, parameters, options, callback)

Executes the command with the given commandName and parameters and calls the callback when an error is encountered or an answer is received. This is actually an RPC-like call.

Parameters

  • commandName (String, required): name of the command to execute
  • parameters (any, required): a single argument that can be any Javascript entity that is JSON stringifyable (JSON.stringify). Multiple parameters to the command should either be passed as an Array or as an Object.
  • options (Object, required): Currently not used; set to an empty object, e.g. {}.
  • callback (Object, required): called when the request returns. It takes two arguments: err and reply. err is not null if an error occurred, else reply contains the result of the request.

Example

  //using an Object as parameters
  myWorker.request("say.something.funny", { name: "krew", version: { major: 1, minor: 0 } }, function(err, reply) {
    if (err) {
      console.error("Oops, someone had a problem saying something funny", err);
    } else {
      console.log("Someone said something funny:", reply);
    }
  });

  //using an Array as parameters
  myWorker.request("calculator.add", [1, 2, 3, 4], function(err, reply) {
    if (err) {
      console.error("Oops, the calculator went bezerk", err);
    } else {
      console.log("The sum is:", reply);
    }
  });

  //using an String as parameters
  myWorker.request("utils.uppercase", "lowercase", function(err, reply) {
    if (err) {
      console.error("Oops, utils.uppercase seems sick", err);
    } else {
      console.log("uppercased:", reply);
    }
  });

Parameters

  • callback (Function, optional): called when the worker stopped successfully or failed. It takes an 'Error' argument (nodejs style).

Tests

Unit Tests

$ npm test

Unit Tests with Code Coverage

$ npm run test-cov

This will generate a folder coverage containing coverage information and a folder coverage/lcov-report containing an HTML report with the coverage results.

$ npm run test-ci

will create a folder coverage containing lcov formatted coverage information to be consumed by a 3rd party coverage analysis tool. This script is typically used on a continuous integration server.

Benchmarks

$ npm run benchmark

Checkstyle

Executing

$ npm run check-style

will run the jscs stylechecker against the code.

Static Code Analysis

Executing

$ npm run code-analysis

will run jshint to analyse the code.

Code Documentation

Executing

$ npm run make-docs

will run jsdoc to create documentation.

License

MIT