ActivePubsub
Service oriented observers for active record, via RabbitMQ and Bunny gem. Publish/Observe changes made to ActiveRecord models asynchronously, from different applications/services.
Best examples can be found here: https://github.com/jasonayre/active_pubsub_examples
Publisher Example
class Post < ::ActiveRecord::Base
include ::ActivePubsub::Publishable
# This is the namespace for the local service
# The following Will set up a cms.post rabbit exchange
publish_as "cms"
end
Subscriber example
# this is an example of a service that wants to do something when posts are created,
# updated, or destroyed, in the publishing service
class PostSubscriber < ::ActivePubsub::Subscriber
observes "cms"
as "aggregator"
on :created do |record|
puts record.inspect
end
on :destroyed do |record|
puts record.inspect
end
on :updated do |record|
puts record.inspect
end
end
Publishing events
Just include ::ActivePubsub::Publishable module into an active record class whose events you want to publish.
class Post < ::ActiveRecord::Base
include ::ActivePubsub::Publishable
end
Also, you need to declare a namespace to publish under, either in the main configuration or in the model
class Post < ::ActiveRecord::Base
include ::ActivePubsub::Publishable
publish_as "cms"
end
Or in initializer
::ActivePubsub.configure do |config|
config.publish_as = "cms"
end
IMPORTANT: If you don't do one of the above the publisher will not be started.
The publisher simply runs in a new thread alongside your main application, connects to rabbit, and publishes the events.
Subscribing to Events
Subscriber runs in a separate process from your application itself. You can start the subscriber with:
Starting the subscriber
bundle exec subscriber start
Benchmarks/Performance
No full benchmarks, but here are the results Ive seen so far via rabbit. MacbookPro, 2.6 i7 w 16gb ram. Running one publisher app and one subscriber, via examples at https://github.com/jasonayre/active_pubsub_examples
Celluloid version > 0.16
I removed the gem lock to be compatibile with the most recent version of sidekiq which uses celluloid (0.15.2) or something, however I noticed a significant speed boost with > 0.16 version of celluloid.
Range of published messages/second: 250-500 Range processed (subscriber) messages/second: 250-500
Celluloid version 15.2
Average published messages/second: 100-150 Average processed (subscriber) messages/second: 100-150
The throughput seems to be limited by the publisher mostly, from the very limited benchmarks thus far.
Connecting to rabbit
If you are running rabbit at different address or port, set address via ENV variable, i.e.
RABBITMQ_URL=amqp://guest:[email protected]:XXXX bundle exec subscriber start
Or you can set via config
::ActivePubsub.configure do |config|
config.address = "amqp://guest:[email protected]:XXXX"
end
Its still really early in development cycle, so there may be issues running tests if you aren't running rabbit. Should probably fix that.
Installation
Add this line to your application's Gemfile:
gem 'active_pubsub'
And then execute:
$ bundle
Or install it yourself as:
$ gem install active_pubsub
Contributing
- Fork it ( https://github.com/[my-github-username]/active_pubsub/fork )
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request