Skip to content

Instantly share code, notes, and snippets.

@tompave
Last active July 5, 2023 17:13
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save tompave/ae53fbab32ebebf1072e to your computer and use it in GitHub Desktop.
Save tompave/ae53fbab32ebebf1072e to your computer and use it in GitHub Desktop.
how to run rake tasks asynchronously from controllers by spawning child processes
class ApplicationController < ActionController::Base
private
# Runs a rake task asyncronously in a child process
#
# for example, in any controller:
# async_rake("async:import_fixtures")
# async_rake("db:maintenance:cleanup", table: "things", ids: [12, 114, 539])
#
# Options will be converted to strings and passed as unix env variables.
# The rake tasks will then be responsible of retrieving and parsing them
# (e.g. if they are supposed to be collections).
#
def async_rake(task, options = {})
options[:rails_env] ||= Rails.env
# format the options as unix environmental variables
env_vars = options.map { |key, value| "#{key.to_s.upcase}='#{value.to_s}'" }
env_vars_string = env_vars.join(' ')
log_file = File.join(Rails.root, "log/async_rake.#{Rails.env}.log")
# fire and forget
Process.fork {
exec("#{env_vars_string} bin/rake #{task} --trace 2>&1 >> #{log_file}")
}
# or:
# system("#{env_vars_string} bin/rake #{task} --trace 2>&1 >> #{log_file} &")
end
end
@timnovinger
Copy link

This snippet was super helpful, thanks for putting it out there!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment