Skip to content

Instantly share code, notes, and snippets.

@cbrunnkvist
Created September 29, 2010 15:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cbrunnkvist/602983 to your computer and use it in GitHub Desktop.
Save cbrunnkvist/602983 to your computer and use it in GitHub Desktop.
Rails ActiveRecord aware fork() wrapper
# Rails ActiveRecord aware fork() wrapper
$child_pids = []
def wait_for_child(pid=nil)
begin
pid, child_result = (pid.nil? ? Process.wait2 : Process.waitpid2(pid))
unless child_result.exitstatus.zero?
$child_pids.each {|child_pid| Process.kill('TERM', child_pid) rescue true}
raise "Child PID:#{pid} exited with status #{child_result.exitstatus} - batch aborting"
end
rescue Errno::ECHILD
true
end
end
def fork_and_reconnect
on_all_db_connections(:disconnect!)
fork do
begin
on_all_db_connections(:reconnect!)
yield
ensure
on_all_db_connections(:disconnect!)
end
end
end
def on_all_db_connections(action)
# There may be others (i.e. DbCharmer) sitting on connections somewhere, so we need to find them
ObjectSpace.each_object(ActiveRecord::ConnectionAdapters::AbstractAdapter).each {|a| a.send(action)}
end
def final_wait
$child_pids.each do |pid|
wait_for_child(pid)
end
on_all_db_connections(:reconnect!)
end
@tigris
Copy link

tigris commented Aug 29, 2012

Busted in rails 3 :(

If anyone knows a way to fork in rails 3 i'd love to hear it. Having to use threads for now, but don't feel too safe about it.

puts "before block: #{ActiveRecord::Base.connection.active?}"
fork_and_reconnect { puts "inside block: #{ActiveRecord::Base.connection.active?}" }
puts "after block: #{ActiveRecord::Base.connection.active?}"

#=> "after block: false"

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