Docs Menu

Forking Server Configuration

In this guide, you can learn about configuring your application to use a forking web server.

When using Mongoid with a forking web server, adhere to the following guidelines:

  • If possible, do not perform any MongoDB operations in the parent process before forking. To learn more about how the Ruby driver handles forking, see Usage with Forking Servers in the driver documentation.

  • You can avoid connection errors such as Mongo::Error::SocketError and Mongo::Error::NoServerAvailable by performing the following actions:

    1. Disconnect MongoDB clients in the parent Ruby process immediately before forking by using the Mongoid.disconnect_clients method. This ensures that the parent and child processes do not accidentally reuse the same sockets and have I/O conflicts. Mongoid.disconnect_clients does not disrupt any in-flight MongoDB operations, and automatically reconnects when you perform new operations.

    2. Reconnect your MongoDB clients in the child Ruby process immediately after forking by using the Mongoid.reconnect_clients method. This is required to respawn the driver's monitoring threads in the child process.

Most web servers provide hooks that your application can use to perform actions when the worker processes are forked. The following sections provide configuration examples for some common Ruby web servers.

Use the on_worker_boot hook to reconnect clients in the workers. Use the before_fork and on_refork hooks to close clients in the parent process. To learn more about these hooks, see Clustered mode hooks in the Puma API documentation.

The following code uses the on_worker_boot, before_fork, and on_refork hooks in a sample Puma configuration file:

config/puma.rb
# Runs in the Puma master process before it forks a child worker.
before_fork do
Mongoid.disconnect_clients
end
# Required when using Puma's fork_worker option. Runs in the
# child worker 0 process before it forks grandchild workers.
on_refork do
Mongoid.disconnect_clients
end
# Runs in each Puma child process after it forks from its parent.
on_worker_boot do
Mongoid.reconnect_clients
end

Use the before_fork hook to close clients in the parent process. Use the after_fork hook to reconnect clients in the workers. To learn more about these hooks, see Configurator in the Unicorn API documentation.

The following code uses the before_fork and after_fork hooks in a sample Unicorn configuration file:

config/unicorn.rb
before_fork do |_server, _worker|
Mongoid.disconnect_clients
end
after_fork do |_server, _worker|
Mongoid.reconnect_clients
end

Use the starting_worker_process hook to reconnect clients in the workers. To learn more about this hook, see Smart spawning hooks in the Passenger documentation.

Note

Passenger does have a hook that is invoked in the parent process before the workers are forked.

The following code uses the starting_worker_process hook to reconnect clients:

if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
Mongoid.reconnect_clients if forked
end
end