Badger
Badger is designed as a Javascript library to act as a the subscriber
in a
Publish / Subscribe system. The motivation for this is to allow updates from a
server to notify the browser based clients as quickly as possible.
Badger is written in a modular fashion so that different technologies can be used for the channel. For instance:
- XMPP Pubsub
- Polled Atom feeds
- ...
There is also provision for fallbacks. This allows multiple channels to be used. This can be used to help aid development (where a channel may not be available), or add resilience (where browser capabilities, or the network link quality are insufficient).
Callbacks are then used to allow Badger to be integrated into the rest of the system.
Usage
In order to avoid any namespace conflicts Badger
uses the public namespace
com.jivatechnology
(reverse DNS scheme). You can import this into your local
scope with something like:
var Badger = com.jivatechnology.Badger;
Badger allows you to easily specify nodes that you are interested in. First off
you will need an instance of a Badger.Coordinator
(sounds fancy doesn't it):
var badger = new Badger.Coordinator();
From here we can tell our badger to start listening out for things:
badger.subscribe('mash potato');
badger.subscribe('worms');
Or stop listening for things:
badger.unsubscribe('carrots');
We can also add callbacks (see Callback docs) to specify what to do when these events are raised:
onSubscribeSuccess
passingnode
onSubscribeFailure
passingnode
onUnsubscribeSuccess
passingnode
onUnsubscribeFailure
passingnode
onMessage
passingnode
,id
,verb
,payload
For example:
badger.onMessage.add(function(node,id,verb,payload){
...
Message handling code
...
});
Or we can add a handler that is specific to a certain node:
badger.subscribe('mash potato').onMessage.add(function(id,verb,payload){
...
Mashing code
...
});
This passes an item id
, the verb
(update
or remove
) and the payload
.
The payload
is processed by a Badger.Parser
before being sent to the callback.
A few are parsers are bundled to give you an idea, but these can easily be
customised to suit your needs. Parsers are linked to Badger.Channels
. So far
there are channels for:
- Polled Atom feed
- XMPP Pubsub
However, it's not too tricky to write your own.
We can add multiple channels to our coordinator. Lets see that in action:
var plain = new Badger.Parser.Plain();
var atom_channel = Badger.Channel.Atom({delay: 2000, parser: plain});
badger.backendAppend(atom_channel);
Or we could add a higher priority XMPP channel:
var strophe = ... strophe setup ...
var data_form = new Badger.Parser.DataForm();
var xmpp_channel = new Badger.Channel.XMPP({
connection: strophe,
parser: data_form,
});
badger.backendPrepend(xmpp_channel);
Adding a new channel will cause any failed subscriptions to be retried. Also changing the priority of channels will cause subscriptions to be renegotiated so that the best one is used that works.
Some channels like the Polled Atom feed do not really support push
. These
channels can have an extra method called hint
. This allows hint
to be called
when you know there is new content available which triggers a check immediately.
This means the next schedulded poll does not have to execute before the update
can be discovered.
badger.hint("node/i/know/has/been/updated")
Tests
All of the tests are written in Jasmine. Sprockets is used to describe dependencies between the files. To run the tests, you will first need to install Ruby and Bundler. Once you have this:
$ bundle install
$ bundle exec rake jasmine
Open your browser to http://localhost:8888
If you want to run the tests directly in the console just type:
$ bundle exec rake jasmine:ci
/Users/theo/.rvm/rubies/ruby-1.9.3-p0/bin/ruby -S rspec spec/javascripts/support/jasmine_runner.rb --colour --format progress
[2012-03-15 15:46:50] INFO WEBrick 1.3.1
[2012-03-15 15:46:50] INFO ruby 1.9.3 (2011-10-30) [x86_64-darwin11.1.0]
[2012-03-15 15:46:50] INFO WEBrick::HTTPServer#start: pid=39919 port=63714
Waiting for jasmine server on 63714...
jasmine server started.
Waiting for suite to finish in browser ...
..........................................
Or you can check the current status of master using Travis
Building
Provided you have all of the software installed to run the tests (see above). You can build the code using:
$ bundle exec rake build
This will create a copy of the code in the build
folder. It will also package
up any external dependencies (such as callback-js).
If you are already using Sprockets
then it is best to copy the src
folder
to your project and let that deal with the build dependencies (avoids
duplication).
TODO
Add support for:
- socket.io
- pusher