Last active
May 12, 2017 08:38
-
-
Save Paxa/6b9765c63526960198e0b04f56f7b24f to your computer and use it in GitHub Desktop.
Safe way to run threads on rails
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Async | |
## | |
# Run code in thread, handle exceptions, release DB connections | |
# | |
# Async(:send_email) { Mailer.send } | |
# | |
def self.run(name) | |
parent_t = Thread.current | |
working_thread = Thread.new do | |
begin | |
# copy thread variables | |
# Rails and some other libraries may save something in thread variables | |
# such as Timezone and locale | |
parent_t.keys.each do |key| | |
next if key =~ /activerecord|activesupport|__recursive_key__/i | |
Thread.current[key] = parent_t[key] | |
end | |
# make sure DB connection is closed | |
ActiveRecord::Base.connection_pool.with_connection do | |
yield | |
end | |
rescue => error | |
Rails.logger.info "Error in thread!" | |
Rails.logger.info(error.message) | |
Rails.logger.info(error.backtrace.join("\n")) | |
# Send exception to airbrake/sentry/raygun/newrelic/slack | |
end | |
end | |
# Wait for code to finish in testing environment | |
# to avoid race condition when you expect changes made by thread | |
if Rails.env.test? | |
working_thread.join | |
end | |
working_thread | |
end | |
end | |
## USAGE: | |
Async.run do | |
user.send_welcome_email! | |
user.update!(welcome_email_sent: true) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment