1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
= Fork Safety
If you are forking or using a library that forks after you have created a
Sequel::Database instance, then you must disconnect database connections before forking. If you
don't do this, you can end up with child processes sharing database connections
and all sorts of weird behavior, including crashes. Sequel will automatically create new
connections on an as needed basis in the child processes, so you only need to do the following in
the parent process:
DB.disconnect
Or if you have connections to multiple databases:
Sequel::DATABASES.each(&:disconnect)
== Puma
When using the Puma web server in clustered mode (which is the default behavior in Puma 5+ when
using multiple processes), you should disconnect inside the +before_fork+ hook in your
Puma config:
before_fork do
Sequel::DATABASES.each(&:disconnect)
end
== Unicorn
When using the Unicorn web server and preloading the application (+preload_app true+ in the Unicorn
config), you should disconnect inside the +before_fork+ hook in the Unicorn config:
before_fork do
Sequel::DATABASES.each(&:disconnect)
end
== Passenger
In Passenger web server, you should disconnect inside the
+starting_worker_process+ event hook:
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
Sequel::DATABASES.each(&:disconnect) if forked
end
end
Note that this disconnects after forking instead of before forking. Passenger does not
offer a before fork hook.
== Spring
In Spring application preloader, you should disconnect inside the +after_fork+ hook:
if defined?(Spring)
Spring.after_fork do
Sequel::DATABASES.each(&:disconnect)
end
end
As the method indicates, this disconnects after forking instead of before forking.
Spring does not offer a before fork hook.
== Resque
In Resque, you should disconnect inside the +before_fork+ hook:
Resque.before_fork do |job|
Sequel::DATABASES.each(&:disconnect)
end
== Parallel
If you're using the Parallel gem with processes, you should disconnect before
calling it:
Sequel::DATABASES.each(&:disconnect)
Parallel.map(['a','b','c'], in_processes: 3) { |one_letter| }
== Other Libraries Calling fork
For any other library that calls fork, you should disconnect before calling
a method that forks:
Sequel::DATABASES.each(&:disconnect)
SomeLibrary.method_that_forks
|