During the Christmas break me and Mike were discussing a new feature at Product Hunt. The feature required scheduling an ActiveJobs when a user signs up, votes or submits a comment.
SignUp object which handles user registration. So scheduling a new background job there is quite simple:
module SignUp # ... handle user sign up def after_sign_up(user) WelcomeEmailWorker.perform_later(user) WelcomeTweetWorker.perform_later(user) SyncProfileImageWorker.perform_later(user) NewFancyFeatureWorker.perform_later(user) # <- new worker end end
after_sign_up method was becoming quite large ☹️
Now imagine having to add
NewFancyFeatureWorker to 10 other places 😫
Those issues pushed us to create a simple wrapper around ActiveJobs, which we call KittyEvents.
SignUp there is just one trigger for an "event":
module SignUp # ... handle user sign up def after_sign_up(user) ApplicationEvents.trigger(:user_signup, user) end end
And there is a central place, where events are mapped to ActiveJobs Workers:
# config/initializers/application_events.rb module ApplicationEvents extend KittyEvents event :user_signup, [ WelcomeEmailWorker, WelcomeTweetWorker, SyncProfileImageWorker, NewFancyFeatureWorker, # <- new worker ] # ... other events end
When an event is triggered, all ActiveJobs Workers for this events are scheduled and executed.
Another bonus, is when using KittyEvents, you only make a single Redis call to trigger any number of events. This shaves off precious milliseconds when using KittyEvents in request.