• Stars
    star
    116
  • Rank 303,894 (Top 6 %)
  • Language
    JavaScript
  • Created about 10 years ago
  • Updated almost 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A micro-service bus with built-in messaging patterns, for NodeJS and RabbitMQ

A highly opinionated, yet minimal, set of message bus abstractions for NodeJS. It is built on top of RabbitMQ, with rabbot as the primary library for working with RabbitMQ.

About Rabbus

The service bus implementation is basic, but includes several of the most common patterns:

  • Send / Receive
  • Publish / Subscribe
  • Request / Response

The items on the left are "producers" as they produce a message for RabbitMQ to route and handle. Items on the right are "consumers" as they consume a message from a queue in RabbitMQ.

Producers and Consumers inherit from a base class of that name, providing common functionality and a means by which all producers / consumers can be extended (see "middleware" below).

Installing Rabbus

It's all NPM. You're going to want the 'rabbot' package with this, so you will need to do two things:

npm install --save rabbot rabbus

Please note that rabbot is explicitly NOT mentioned as a dependency in the Rabbus package.json file for runtime dependencies. This is done with intent, to help prevent library version conflicts.

Upgrading Rabbus

If you are upgrading Rabbus from a previous version, be sure to read the Upgrade Guide.

Rabbus Demos

There are several demos available to show the basic use of Rabbus. These demos can be found in the /demos folder, including:

  • Send / Receive
  • Publish / Subscribe
  • Request / Response

Be sure to read the demo documentation for information on how to run these demos.

Rabbus Documentation

Detailed Rabbus documentation can be found in the docs folder, with a file for each of the major aspects of Rabbus.

Core Documents

Messaging Patterns:

Other Documentation:

Configuring RabbitMQ Connections

Please see the rabbot documentation for information on configuring RabbitMQ connections.

Messaging Patterns

There are three pairs of pattern-based objects that come with Rabbus. Each of them is meant to be used in combination with it's pair. You are encouraged, however, not to use them directly. While this is certainly possible, I find it is more convenient to inherit from these objects at the point where they need to be used. The configuration of each object can then be encapsulated for the intended use, allowing easier testing and maintenance.

There are a few commonalities between all of these object pairs. Most notably, the object that sends a message to RabbitMQ only needs to know about the exchange to which it sends. Conversely, the object that consumes a message from within RabbitMQ needs to know about both the exchange and the queue to which it subscribes.

Basic API and Middleware

Rabbus uses a base message producer and consumer object to provide the functionality of all message producers and consumers. This gives a consistent API to all objects, and makes it easy to create your own patterns and extend the Rabbus feature set.

All message consumers receive a common set of parameters when consuming the message:

<obj>.<consumerMethod>(function(message, properties, actions, next){
});

Each of these parameters gives you specific information or callable function to continue processing or completing the process.

For definitions of these parameters, please see the middleware documentation

Topology

In addition to the pattern objects, Rabbus also includes a topology object and use of middleware within it's objects. These object types allow much greater freedom and flexibility with Rabbus, when needed.

The Topology object allows you to pre-define and build the needed topology for your RabbitMQ scenario. You can also use existing topology constructs (exchanges, queues and bindings) with a Topology, preventing Rabbus from attempting to re-create them.

See the topology documentation for more information.

Sending Custom Message Properties

RabbitMQ allows you to specify any number of custom headers and other properties, and rabbot allows you to manipulate them as needed.

With Rabbus, you can also pass any arbitrary properties or headers that you wish, when sending a message. This is done in a few ways.

  1. Middleware - see the documentation below
  2. A key/value list when sending a message

To use a key/value list, provide an object with keys / values in either the send or publish method of the Sender / Publisher objects (below).

For example:

sender.send(someMessage, {
  expiresAfter: 1000,
  headers: {
    foo: "bar"
  }
});

This will send a message with a TTL of 1 second (1000ms), and a header of foo: bar.

Callback After Sending message

If you want to specify both a properties object and provide a callback method to fire after the message is sent, the callback can be specified as an onComplete attribute of the properties:

sender.send(someMessage, {
  expiresAfter: 1000,
  onComplete: function(){
    console.log("the message has been sent!");
  }
});

If you don't specify an object literal, you can provide a callback function directly as the second parameter.

sender.send(someMessage, function(){
  console.log("the message has been sent!");
});

Limit Message Processing

If you need to limit the number of messages being processed by any given messgae handler, you can specify a limit in the configuration.

function SomeSubscriber(){
  Rabbus.Subscriber.call(this, rabbot, {
    // ...
    queue: {
      // ...
      limit: 1
    }
  });
}

This will limit your SomeSubscriber to only working on one message at a time. When your processing code calls done, the next message will be picked up and processed.

NoBatch: Ack / Nack Individual Messages

rabbot's default behavior is to batch process ack and nack calls on messages. This can lead to an improvement of up to 400% throughput in processing small things. In scenarios where there are very long running processes that leave a message unacknowledged for extended periods, though, this can be troublesome.

To prevent issues with batching ack / nack calls, rabbot and Rabbus provide a noBatch option for Queue definitions.

var Subscriber = new Rabbus.Subscriber({
  // ...
  queue: {
    //... 
    noBatch: true
  }
});

The following Rabbus objects provide the noBatch feature:

  • Rabbus.Receiver
  • Rabbus.Subscriber
  • Rabbus.Responder

The messageType Attribute

Rabbus is built on top of the rabbot library, which uses a messageType attribute for messages. The behavior of the messageType attribute makes rabbot and Rabbus behave somewhat differently than RabbitMQ / AMQP on their own.

Internally, rabbot uses an in-memory messaging library called Postal.js to facilitate message delivery to consumer functions. The messageType attribute is used by postal as it's own form of a routing key.

Because of this, you can have two consumers receive a copy of a single message from a single queue... or, have messages from different queues show up in a single subscriber.

c1 = new Rabbus.Subscriber({
  // ...
  exchange: "foo",
  routingKey: "foo",
  queue: "foo",
  messageType: "foo" // <= note the message type
});

c2 = new Rabbus.Subscriber({
  // ...
  exchange: "bar",
  routingKey: "bar",
  queue: "bar",
  messageType: "foo" // <= same message type
});

c1.subscribe(function(msg, props, actions){
  console.log("c1 got it!");
  actions.ack();
});

c2.subscribe(function(msg, props, actions){
  console.log("c2 got it!");
  actions.ack();
});

In this example, it is highly likely that you will receive both a "c1 got it!" message and a "c2 got it!" message in the console, when publishing a message for c1 to consumer. This happens because of the messageType being the same. rabbot has internally used the messageType to say that both the c1 and c2 handler methods should receive the message.

Leaving the messageType blank will cause rabbot to use the routing key for the message, as the means by which it delivers messages to handlers. As long as you are using unique routing keys, you should probably leave the messageType blank.

That's not to say there isn't value in what rabbot does. This is just different than standard RabbitMQ/AMQP.

Legalese

Rabbus is Copyright ©2016 Muted Solutions, LLC. All Rights Reserved.

Rabbus is distributed under the MIT license.

More Repositories

1

backbone.modelbinding

awesome model binding for Backbone.js
JavaScript
700
star
2

backbone.memento

store and restore your model's state
JavaScript
367
star
3

mustbe

Authorization plumbing for NodeJS/ExpressJS/ConnectJS apps
JavaScript
320
star
4

Albacore

Dolphin-Safe Rake Tasks For .NET Systems
Ruby
240
star
5

jasmine.async

Make Jasmine's asynchronous testing suck less.
JavaScript
136
star
6

backbone.picky

selectable entities as mixins for Backbone.Model and Backbone.Collection
JavaScript
129
star
7

express-sub-app-demo

Demonstrates the ability to mount multiple Express apps into a single Express host app
JavaScript
111
star
8

solid-javascript

SOLID JavaScript In A Wobbly World (Wide Web)
JavaScript
70
star
9

nanit

Node Application Initializers
JavaScript
56
star
10

migroose

MongoDB database / data-structure migrations, for MongooseJS models and schemas
JavaScript
55
star
11

appcontroller

An example Application Controller implementation for C# WinForms applications
C#
35
star
12

emberclonemail

A sample application written with EmberJS
Ruby
32
star
13

backbone.compute

Computed fields for Backbone.Model
JavaScript
31
star
14

presentations-and-training

Material used for presentations and training classes
C#
26
star
15

backbone.fwd

forward events from one backbone object, through another
JavaScript
20
star
16

bowie

An experiment in beautiful models with ES6 elegance
JavaScript
19
star
17

hands-on-backbone

The sample code to go along with the "Hands-on Backbone.js" screencast series from PragProg.com
JavaScript
18
star
18

iam

Simple authentication plumbing and middleware for Node/Express apps
JavaScript
15
star
19

bada55-node-dev

How to build your own #BADA55 NodeJS development environment
JavaScript
14
star
20

UnitOfWork

A C# UnitOfWork Implementation For NHibernate. Supports WinForms and ASP.NET.
C#
12
star
21

epa

simple environment configuration for nodejs apps, using json files
JavaScript
11
star
22

speccy

simple javascript specification pattern implementation for nodejs / browserify
JavaScript
9
star
23

appcontroller.cf

Application Controller example code for the .NET Compact Framework
C#
8
star
24

jquery-to-backbone-marionette

code demo for my "jQuery To Backbone + Marionette" talk
JavaScript
8
star
25

boebotjs

Make Your Bot GO! With JavaScript!
JavaScript
8
star
26

Security

A small, role based security module for .NET apps
C#
7
star
27

vimbacore

a playground to try out c# coding in vim and figure out what albacore's csc task needs
Ruby
7
star
28

docker4js

Docker for JavaScript Developers - 2 day, hands-on training course from Derick Bailey
JavaScript
5
star
29

migroose-cli

command line tooling for mongrate, the mongodb/mongoosejs migration framework
JavaScript
5
star
30

5-tips-to-improve-js-with-es6

presentation given at Crater Remote Conf, Feb 10th, 2016
JavaScript
5
star
31

backbone-sinatra-boilerplate

My boilerplate cruft for working with Backbone.js in a Sinatra-backed app
JavaScript
5
star
32

MyFirstMVCSeleniumTest

How To Get Started With Selenium Core And ASP.NET MVC
JavaScript
4
star
33

classyobjects

A class-y inheritance example for JavaScript
JavaScript
3
star
34

backboneplugins

website for backboneplugins.com
CSS
3
star
35

ninject.rhinomocks.cf

Automocking container for RhinoMocks, running on Compact Framework
C#
3
star
36

5-stages-of-developer-grief

Presented at SpaceCityJS 2015
3
star
37

vimfiles.osx

my osx .vim folder and .vimrc
Vim Script
3
star
38

5-stages-of-entrepreneurial-grief

presentation for PrarieDevCon 2015
3
star
39

ninject.rhinomocks

Automocking container for RhinoMocks
C#
3
star
40

growing-express-architecture

Growing Express.js Architecture - a talk given at JSRemoteConf on Jan 15, 2016.
3
star
41

node-oracledb-cpu-leak

app to demonstrate node-oracledb cpu leak / spike
JavaScript
2
star
42

gitup

Automate the git update dance
Shell
2
star
43

execubot.js

A sample WebTask.io project: Read and execute code from a gist, post it in slack channel.
JavaScript
2
star
44

backbone.presentation

My slide deck for a Backbone.js presentation
JavaScript
2
star
45

cheesewiz

Correctly package localized resource files in .NET Comptact Framework .cab deployment projects
C#
2
star
46

jsfuncalc

An exercise in creating a functional javascript calculator
Ruby
2
star
47

ocarina

Simplified API for Oracle, built on top of official orabledb library
JavaScript
2
star
48

apologypro

apology.pro: because you're an amateur
JavaScript
2
star
49

boxing

terrible dropbox api and express middleware
JavaScript
2
star
50

mutedsolutions

website for my company
CSS
2
star
51

alt-tekpub

An open rewrite of Tekpub using Node, MongoDB and other buzzwords
JavaScript
1
star
52

objects

1
star
53

vimfiles.windows

my vim files and _vimrc for windows
Vim Script
1
star
54

derickbailey.github.com

My Github Homepage!
1
star
55

rabbus-sequence

process messages in sequential order with Rabbus and RabbitMQ
JavaScript
1
star
56

puzzleblocks

a command line game inspired by the Nintaii game that I play on my Droid
Ruby
1
star
57

traffic-limiter

Limit the number of tasks being run, based on task key/type
JavaScript
1
star
58

express-depot

mount Express sub-apps and middleware from a directory listing
JavaScript
1
star
59

react-todo-example

a basic example of organizing code in a basic react/redux app
JavaScript
1
star
60

wacotechlunch

Waco Tech Lunch
1
star
61

dotfiles

my dotfiles
Vim Script
1
star
62

node-jasmine-async

Making Jasmine's async suck less (for Jasmine v1.3)
JavaScript
1
star