File: fork_safety.rdoc

package info (click to toggle)
ruby-sequel 5.63.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,408 kB
  • sloc: ruby: 113,747; makefile: 3
file content (84 lines) | stat: -rw-r--r-- 2,401 bytes parent folder | download | duplicates (3)
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