Promiscuous
Promiscuous is a pub-sub framework for easily replicating data across your Ruby applications. Promiscuous guarantees that a subscriber never sees out of order updates and that all updates are eventually replicated.
Benefits over database replication
- Hetrogenous replication. e.g. replicate from Mongo -> Postgres | ElasticSearch | Redis ...
- "Remote observers". The ability to observe model changes in one application from another.
- Publish virtual attributes
Rails Quick Tutorial
1. Preparation
We need a few things for the promiscuous tutorial:
- The AMQP broker RabbitMQ up and running.
- The key-value storage system Redis (at least 2.6) up and running.
- Two Rails applications with the promiscuous gem installed.
- Both applications must be running on separate databases.
- Both applications must have a User model (ActiveRecord or Mongoid) with two attributes name and email.
2. Publishing
By including the Promiscuous publisher mixin, we can publish the model attributes:
# app/models/user.rb on the publisher app
class User
include Promiscuous::Publisher
publish :name, :email
end
3. Subscribing
Similarly to the publisher app, we can subscribe to the attributes:
# app/models/user.rb on the subscriber app
class User
include Promiscuous::Subscriber
subscribe :name, :email
after_create { Rails.logger.info "Hi #{name}!" }
end
4. Replication
The subscriber must listen for new data to arrive. Promiscuous has a worker that we can launch with the following command:
bundle exec promiscuous subscribe
You should start the subscriber first, otherwise the appropriate queues will not be created. From now on, you should see the queue in the RabbitMQ web admin page. Create a new user in the publisher's Rails console with:
User.create(:name => 'Yoda')`
You should see the message "Hi Yoda!" appearing in the log file of the subscriber.
5. Checking Migrations
Historically promiscuous would check the schemas of subscribing models to ensure that the models had the required version column.
Since this could get in the way when running the project this has been moved to a CLI command which can be run with the following command:
bundle exec promiscuous migrations
Promiscuous in Depth
Features and Recipes
- Attributes
- Ephemerals & Observers
- Polymorphism
- Embedded Documents
- Foreign Keys
- Namespace Mapping
- Promiscuous DSL
Configuration
Testing
Going to Production
- RabbitMQ & Redis
- Initial Sync
- Error Handling
- Instrumentation
- Managing Deploys
- Setup with Unicorn, Resque, etc.