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