Permalink
Browse files

Moved from application. initial commit with readme

  • Loading branch information...
1 parent af4000a commit 83ee1f8ae971c55726c0093718bdb5246f37e813 @seanhess seanhess committed Aug 30, 2012
Showing with 450 additions and 1 deletion.
  1. +53 −1 README.md
  2. +99 −0 index.coffee
  3. +29 −0 package.json
  4. +269 −0 test.coffee
View
@@ -1,4 +1,56 @@
messagehub
==========
-Simple message, queue and pubsub system compatible with RabbitMQ
+Simple message, queue and pubsub system compatible with [RabbitMQ](http://www.rabbitmq.com/).
+
+Communicates events and jobs across processes and servers.
+
+
+
+Installation
+------------
+
+ npm install messagehub
+
+You also need to connect to a running [RabbitMQ](http://www.rabbitmq.com/) server at the host specified.
+
+Documentation
+-------------
+
+### Create
+
+ messagehub = require 'messagehub'
+ myhub = messagehub 'localhost', 'mychannel'
+
+### Events
+
+Emit an event
+
+ messagehub = require 'messagehub'
+ myhub = messagehub 'localhost', 'mychannel'
+ myhub.emit 'messages.one', {key: "value"}
+
+Observe an event (ALL handlers will trigger)
+
+ messagehub = require 'messagehub'
+ myhub = messagehub 'localhost', 'mychannel'
+ myhub.on 'messages.one', (data) ->
+ console.log "MESSAGES.ONE", data
+
+### Jobs
+
+Queue a job
+
+ messagehub = require 'messagehub'
+ myhub = messagehub 'localhost', 'mychannel'
+ myhub.job 'jobs.one', {key: "value"}
+
+Handle a job (jobs are balanced between workers)
+
+ messagehub = require 'messagehub'
+ myhub = messagehub 'localhost', 'mychannel'
+ myhub.worker 'jobs.one', (data, done) ->
+ console.log "MESSAGES.ONE", data
+ done()
+
+
View
@@ -0,0 +1,99 @@
+###
+
+http://stackoverflow.com/questions/8261654/messaging-confusion-pub-sub-vs-multicast-vs-fan-out
+
+
+SIMPLE EXPLANATION
+a message is routed by an exchange to any queues who are bound on that key.
+- multiple queues get the message at once if they are bound the same
+- multiple programs get messages balanced if they subscribe to the same queue
+
+EXCHANGES
+are the first step in the routing process. It decides which queues to put the message in
+
+EXCHANGE TYPE
+fanout: ignores binding ids and routing keys. Everyone bound to the exchange gets the message
+topic: can do everything, but a little slower
+ - unique queue name: everyone bound to it will receive it
+ - common queue name: load balances between it
+ - routing keys: will match based on a pattern
+direct: like topic, but doesn't do any * or #
+
+QUEUES
+exist outside the scope of the file. If you declare and bind a queue in your program, it will remain bound after it exits
+if you rebind a queue of the same name, it will receive messages for BOTH patterns
+
+QUEUE NAME
+if unique (empty string), it acts like a fanout, because the queue name is unique, and multiple unique queues are bound to the same exchange/id pattern.
+
+###
+
+
+amqp = require 'amqp'
+events = require 'events'
+
+
+# would you ever have an publisher and subscriber in the same one?
+# sure... why not?
+
+
+# EXCHANGE TYPE
+
+module.exports = hub = (host, channel, cb) ->
+
+ cb ?= ->
+
+ # you're going to need two kinds of exchanges here
+ # one for fanouts, and one for topics?
+
+
+ exchange = null
+ connection = amqp.createConnection { host: host }
+ connection.on 'error', (err) ->
+ if err? then throw new Error "Could not connect to RabbitMQ server at #{host}"
+
+ connection.on 'ready', ->
+ connection.exchange channel, {type: 'direct'}, (exc) ->
+ exchange = exc
+ connection.emit 'exchangeReady', exchange
+ cb null, newhub
+
+
+ # lets you get things ready before everything is all ready
+ getExchange = (cb) ->
+ if exchange? then return cb exchange
+ connection.on 'exchangeReady', cb
+
+ ## PUB/SUB Events #######
+
+ # send an event into the system
+
+ newhub =
+ emit: (id, data) ->
+ getExchange (exchange) ->
+ exchange.publish id, data
+
+ # one of many handlers for an event. We want to create a new queue for this and bind to our id on it
+ # maybe when you bind an exchange, you have to bind it separately
+ on: (id, cb) ->
+ getExchange (exchange) ->
+ connection.queue '', (q) ->
+ q.bind exchange, id
+ q.subscribe (data) ->
+ cb data
+
+ # create a new job. make sure it's durable
+ job: (id, data) ->
+ getExchange (exchange) ->
+ exchange.publish id, data, {deliveryMode: 2}
+
+ # handle a job. Assume prefetch count is 1 for now? Will result in low CPU utilization. is it bad to just bind several workers?
+ worker: (id, cb) ->
+ getExchange (exchange) ->
+ options = {autoDelete: false, durable: true}
+ # creating a queue takes a bit longer if it isn't already created :)
+ connection.queue id, options, (q) ->
+ q.bind exchange, id
+ q.subscribe {ack: true, prefetchCount: 1}, (data) ->
+ cb data, -> q.shift()
+
View
@@ -0,0 +1,29 @@
+{
+ "name": "messagehub",
+ "version": "0.0.1",
+ "description": "Simple message, queue and pubsub system compatible with RabbitMQ",
+ "main": "index.js",
+ "scripts": {
+ "test": "node_modules/.bin/mocha -R spec --compilers coffee:coffee-script test.coffee",
+ "prepublish": "node_modules/.bin/coffee -c index.coffee"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/idottv/messagehub.git"
+ },
+ "keywords": [
+ "rabbitmq",
+ "pub/sub",
+ "messages",
+ "queue"
+ ],
+ "author": "Sean Hess",
+ "license": "BSD",
+ "dependencies": {
+ "amqp": "~0.1.3"
+ },
+ "devDependencies": {
+ "coffee-script": "~1.3.3",
+ "mocha": "~1.4.1"
+ }
+}
Oops, something went wrong.

0 comments on commit 83ee1f8

Please sign in to comment.