This gem simplifies syncing data between services by using delayed job processing and a message queue for guaranteed delivery and eventual consistency. SyncClient defines messages based on a resource and action system to simplify message publishing and handling. It supports inline processing and delayed job processeding by Resque, DelayedJob, and Sidekiq. See Queuel for a list of supported message queues.
Add this line to your application's Gemfile:
gem 'sync_client'
And then execute:
$ bundle
Then setup your app as a client (if it isn't already):
$ rails g sync_client:install
Edit configuation in config/initializers/sync_client.rb
SyncClient requires that message queue creditials, a background task queue, and message handler definitions to be defined in the configuration file. Note that any message that does not match a defined handler is simply dropped from the queue.
SyncClient.config do |config|
config.queuel do |c|
# c.default_queue 'VenueService'
# c.credentials token: [token], project_id: 'project_id'
# c.engine :iron_mq
end
# config.background_task_queue SyncClient::Resque #or SyncClient::DelayedJob or write your own.
# config.queue_suffix 'suffix'
# config.logger Logger.new
# config.add_message_handler object_name, handler_class, actions
# config.add_message_handler 'Service::Game', 'Service::Game', [:update, :create, :destroy]
end
SyncClient provides a simple interface to define what attributes to publish to a service for associated actions where the message class is the class of the resource. For models that inherit from ActiveRecord::Base
or include Mongoid::Document
, add the SyncClient::Publisher
module and configure like the following:
class Team < ActiveRecord::Base
include SyncClient::Publisher
publish_changes_of :name, :color, to: :queue, for: [:update, :destroy], if: lambda{|team| !team.name.nil?}
# options:
# to: name of queue for publishing (required)
# for: callbacks for publishing (default: :create, :update, :destroy)
# if/unless: condition for publishing
end
If you are just working with a "Plain Old Ruby Object", you can do something like this:
class TeamSchedulerService
include SyncClient::Publisher
publish_to :queue
# options:
# for: callbacks for publishing (default: :sync)
# if/unless: condition for publishing
def do_some_stuffs
# CODEZ
sync
# return value
end
end
And then in a seperate method, you are able to call the sync
method and fire
the queue syncing yourself.
The sync
method is mapped to the :sync
action in the ServiceResource by
default, but :create
, :update
and :destroy
are still available for you to
use as well.
Run the message queue poller:
$ bundle exec script/sync_client start
$ bundle exec script/sync_client status
$ bundle exec script/sync_client restart
$ bundle exec script/sync_client stop
Message handlers for the actions are then defined matching the handler class set in the configuration file where each method corresponds to the message action as follows:
module Service
class Game < SyncClient::ServiceResource::Base
# Determine what attributes are to be accessible using attr_accessors
attr_accessor :id
attr_accessor :starts_at
attr_accessor :ends_at
def create
Game.create(:game_id => self.id, :starts_at => self.starts_at, :ends_at => self.ends_at)
end
def update
game = Game.find(self.id).first
game.update_attributes(:starts_at => self.starts_at, :ends_at => self. ends_at)
end
def destroy
game = Game.find(self.id)
game.destroy
end
end
end
- Fork it ( https://github.com/[my-github-username]/sync_client/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