AR callbacks after_create/after_update/after_destroy to generate background job etc are useful, but these callbacks are still wrapped in database transaction, and you may probably get unexpected errors on production servers.
Before It’s common to generate a background job to send emails like
class Comment < ActiveRecord::Base
after_create :asyns_send_notification
def async_send_notification
Notifier.send_new_comment_notification(self).deliver
end
handle_asynchronously :async_send_notification
end
# It looks fine that comment record passed to delayed job and then delayed job will fetch this
#comment and then post on which this comment has been made and a notification will
#send via email to the author of that post. Right?
You won’t see any issue in development, as local db can commit fast. But in production server, db traffic might be huge, worker probably finish faster than transaction commit. e.g
- main process
- worker process
- BEGIN
INSERT comment in comments table # return id 10 for newly-created notification SELECT * FROM notifications WHERE id = 10 COMMIT
In this case, the worker process query the newly-created notification before main process commits the transaction, it will raise NotFoundError, because transaction in worker process can’t read uncommitted notification from transaction in main process.
Refactor
So we should tell activerecord to generate notification worker after notification insertion transaction committed.
class Comment < ActiveRecord::Base
after_commit :asyns_send_notification,:on => :create # This is the main point of the whole thing.
def async_send_notification
Notifier.send_new_comment_notification(self).deliver
end
handle_asynchronously :async_send_notification
end
Now the transactions order becomes
- main process
- worker process
- BEGIN
INSERT comment into comments_table return id 10 for newly-created notification COMMIT SELECT * FROM notifications WHERE id = 10
Worker process won’t receive NotFoundErrors any more. :)
For More Details visit http://www.codebeerstartups.com
No comments:
Post a Comment