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

fanout-strategy

v1.2.4

Published

Strategy pattern for publish/subscribe pattern of event-driven SOA

Downloads

6

Readme

Fanout Strategy

This is a package for implementing the fanout-pattern for event driven architechtures.

There are two strategies currently implemented, with a common interface for interacting with them. This allows you to seamlessly interchange your fanout strategies on the fly.

Example

var Fanout = require('fanout-strategy');

var fanout = new Fanout();
// there are two strategies: Redis, AWS
var redisStrategy = new fanout.Redis(redisConfig);
var awsStrategy = new fanout.AWS(awsConfig);

fanout.setStrategy(redisStrategy);

Then, in your middleware you can do:

function(req, res, next) {
  // do stuff
  fanout.publish("example-event", {
    key1: "value1"
  }, function(err, info) {

  })
};

You can listen on events invoked by the publish method:

fanout.listen({
  'example-event': function(data, done) {
    // data = { key1: "value1" }
    // done is a callback used to acknowledge the job
  }
})

Strategies

AWS

In strategies like AWS, you will want to use the "fanout pattern". Instead of publishing to an event and listening on that same event, as you would using a redis strategy, you instead want to publish to an SNS queue and have it fanout automatically to any SQS queues that are subscribed to that topic.

This is advantageous for a microservices standpoint because in SQS the data is only deleted when it is acknowledged by the service. If a service happens to go down, it can get back to processing the backlog of messages that may have appeared during that time period.

This strategy deals with the entire lifecycle of a message. The publish method publishes to the specified SNS topic, and the listen method listens on the specified SQS queues. Additionally, the listeners are equipped to automatically delete messages that you "acknowledge" with a callback.

var awsStrategy = new fanout.AWS({
  accessKeyId: {String},
  secretAccessKey: {String},
  options: {
    sns: {
      region: {String},
      topicOwnerAWSAccountId: {String}
    },
    sqs: {
      region: {String},
      queueOwnerAWSAccountId: {String},
      waitTimeSeconds: {String} [Default=5s]
    }
  }
})
fanout.setStrategy(awsStrategy);

Redis

This will produce a redis strategy that defaults to your local redis. Two clients are created - a publish client and a subscription client. Redis pubsub are then used to publish and listen on events.

var redisStrategy = new fanout.Redis({
  host: {String} [Default="localhost"],
  port: {String | Integer} [Default=6379],
  auth: {String} [Default=""]
})
fanout.setStrategy(redisStrategy);

RabbitMQ

(Coming Soon!)

Methods

publish

Publish data to an event.

Example:

fanout.publish('example-event', { mydata: "hello" }, function(err, info) {})

Parameters:

  • @param {String} eventName [required] The event name to publish to.
  • @param {Object} data [required] The data to publish to the event.
  • `@return {Function} callback

listen

  • @param {Object (listenerFunc, eventName)} data The data that was passed into the publish function
  • {String} eventName The event name to listen on
  • {Function} listenerFunc The function to invoke when the event is triggered.
  • @return {Function} callback

setPrefix

This method is ignored for the Redis strategy!!

To see what setPrefix is really for, imagine using the AWS strategy. If you are using AWS, you will want each service to have its own set of queues (see beginning of documentation for explanation). If I have an event called new-registration, and I want to have listeners on the email and chat services pick it up, then I will want to have separate queues for each. The setPrefix method is for forcing you to choose a naming scheme for your SQS and SNS queues that is consistent.

For example. Consider the following without prefixes:

fanout.publish("auth__new-registration", user, function(err) {})`

And, in the listeners for the search and chat apis:

// search api
fanout.listen({
  "search__new-registration": function(user, done) {
    // index in search
  }
})

// chat api
fanout.listen({
  "chat__new-registration": function(user, done) {
    // index in search
  }
})

If you use setPrefix, you can do this:

// auth api
fanout.setPrefix("auth__");
fanout.publish("new-registration, user, function(err) {});

// search api
fanout.setPrefix("search__");
fanout.listen({
  "new-registration": function(user, done) {}
});

// chat api
fanout.setPrefix("chat__");
fanout.listen({
  "new-registration": function(user, done) {}
});