Reactor
A Sidekiq-driven pub/sub layer for your ruby app
View on GitHub
Hired was written with “log every relevant user click for analysis later” in mind from day one. It began as little ActiveRecord::Base#create calls sprinkled across the controller layer like so:
def create
employment = Employment.new params[:employment]
if employment.save
action_event :employment_created
redirect_to profile_path
else
render :new
end
end
def action_event(name, options)
Activity.create options.merge(actor: current_user, type: name.to_s.camelize)
end
Each of these lines was refactored to pass through a new pub/sub layer that would allow us to bind arbitrary blocks of code and database-driven transactional emails as well as create a log of the activity.
def action_event(name, options)
Reactor::Event.publish name, options.merge(actor: current_user)
end
Read the full story in this blog post.
Pros
- Easy to grep for event name publishing and their hard-coded subscribers
- Easy enough to query for dynamic database-driven listeners
- Faster tests - all background work is stubbed out, simply test that the event was fired
- Fast and scalable in production (built on Sidekiq)
Cons
- Tests of publish and subscribe are slightly decoupled mentally
- All the cons of a redis-backed Sidekiq
- Potential for abuse of abstractions