@@ -1129,55 +1129,104 @@ Note that when creating a client using the `block syntax <#block-syntax>`_ descr
1129
1129
Usage with Forking Servers
1130
1130
==========================
1131
1131
1132
- *Note:* Applications using Mongoid should follow `Mongoid's forking guidance
1133
- <https://docs.mongodb.com/mongoid/current/tutorials/mongoid-configuration/#usage-with-forking-servers>`_.
1134
- The sample code below is provided for applications using the Ruby driver directly.
1135
-
1136
- When using the Mongo Ruby driver with a forking web server such as Unicorn,
1137
- worker processes should generally each have their own Mongo::Client instances.
1132
+ .. note::
1133
+
1134
+ Applications using Mongoid should follow `Mongoid's forking guidance
1135
+ <https://docs.mongodb.com/mongoid/current/tutorials/mongoid-configuration/#usage-with-forking-servers>`_.
1136
+ The guidance and sample code below is provided for applications using the
1137
+ Ruby driver directly.
1138
+
1139
+ When using the Mongo Ruby driver in a Web application with a forking web server
1140
+ such as Unicorn, Puma or Passenger, or when the application otherwise forks,
1141
+ each process should generally each have their own ``Mongo::Client`` instances.
1138
1142
This is because:
1139
1143
1140
1144
1. The background threads remain in the parent process and are not transfered
1141
1145
to the child process.
1142
1146
2. File descriptors like network sockets are shared between parent and
1143
1147
child processes.
1144
1148
1145
- It is recommended to not create any Mongo::Client instances prior to the fork.
1146
- If the parent process needs to perform operations on the MongoDB database,
1147
- reset the client in an ``after_fork`` handler which is defined in
1148
- ``unicorn.rb``:
1149
+ The driver attempts to detect client use from forked processes and
1150
+ reestablish network connections when such use is detected, alleviating
1151
+ the issue of file descriptor sharing.
1152
+
1153
+ If both parent and child processes need to perform MongoDB operations,
1154
+ it is recommended for each of the processes to create their own
1155
+ ``Mongo::Client`` instances. Specifically, the child process should create
1156
+ its own client instance and not use any of the instances that were created
1157
+ in the parent.
1158
+
1159
+ If the parent continues to perform MongoDB operations using an already
1160
+ established client instance after forking children, this client instance will
1161
+ continue to operate normally as long as no child uses it in any way.
1162
+ The child processes will not inherit any of the monitoring threads, and
1163
+ will not perform background operations on the client instance.
1164
+
1165
+ If the parent does not need to perform MongoDB operation after forking
1166
+ children (which is what typically happens in web applications), the parent
1167
+ should close all of the client instances it created to free up connections
1168
+ and cease background monitoring:
1149
1169
1150
1170
.. code-block:: ruby
1151
1171
1152
- after_fork do |server, worker|
1153
- $client.close
1154
- $client.reconnect
1155
- end
1172
+ client.reconnect
1173
+
1174
+ .. note::
1175
+
1176
+ If the parent process performs operations on the Mongo client and does not
1177
+ close it, the parent process will continue consuming a connection slot
1178
+ in the cluster and will continue monitoring the cluster for as long as the
1179
+ parent remains alive.
1180
+
1181
+ Reconnecting Client Instances
1182
+ `````````````````````````````
1183
+
1184
+ When the Ruby driver is used in a web application, it is recommended to not
1185
+ create any ``Mongo::Client`` instances in the management processes (prior to
1186
+ the workers being forked), and instead only create client instances in the
1187
+ workers.
1156
1188
1157
- The above code assumes your Mongo::Client instance is stored in the $client
1158
- global variable. It also keeps the MongoDB connection in the parent process
1159
- around, and this connection will continue to consume resources such as
1160
- a connection slot. If the parent process performs one time operation(s) on
1161
- MongoDB and does not need its MongoDB connection once workers are forked,
1162
- the following code will close the connection in the parent:
1189
+ It is possible, although not recommended, to use the same ``Mongo::Client``
1190
+ instances in parent and child processes. In order to do so, the instance
1191
+ must be closed and reconnected in the child process so that the background
1192
+ threads can be recreated:
1163
1193
1164
1194
.. code-block:: ruby
1165
1195
1166
- before_fork do |server, worker|
1167
- $client.close
1168
- end
1196
+ client.close
1197
+ client.reconnect
1169
1198
1170
- after_fork do |server, worker|
1171
- $client.reconnect
1172
- end
1199
+ .. note::
1200
+
1201
+ This pattern should be used with Ruby driver version 2.6.2 or higher.
1202
+ Previous driver versions did not recreate monitoring threads when
1203
+ reconnecting.
1173
1204
1174
- *Note:* This pattern should be used with Ruby driver version 2.6.2 or higher.
1175
- Previous driver versions did not recreate monitoring threads when reconnecting.
1205
+ .. note::
1176
1206
1177
- *Note:* If the parent process performs operations on the Mongo client and
1178
- does not close it, the parent process will continue consuming a connection slot
1179
- in the cluster and will continue monitoring the cluster for as long as the
1180
- parent remains alive.
1207
+ When closing and reconnecting the client instance in the child,
1208
+ due to file descriptor sharing, the parent process may experience network
1209
+ and monitoring errors.
1210
+
1211
+ Web servers generally provide hooks that can be used by applications to
1212
+ perform actions when the worker processes are forked. The recommended hooks
1213
+ to use are:
1214
+
1215
+ - For `Puma <https://puma.io/puma/>`_, ``before_fork`` to close clients in the
1216
+ parent process and ``on_worker_boot`` to reconnect in the child processes.
1217
+ - For `Unicorn <https://yhbt.net/unicorn/Unicorn/Configurator.html>`_,
1218
+ ``before_fork`` to close clients in the parent process and
1219
+ ``after_fork`` to reconnect clients in the child processes.
1220
+ - For `Passenger <https://www.phusionpassenger.com/library/indepth/ruby/spawn_methods/#unintentional-file-descriptor-sharing>`_,
1221
+ ``starting_worker_process`` to reconnect clients in the child processes
1222
+ (Passenger does not appear to have a pre-fork hook).
1223
+
1224
+ This documentation does not provide example code for using the aforementioned
1225
+ hooks, because there is no standard for client instance management when
1226
+ using the Ruby driver directly. `Mongoid documentation
1227
+ <https://docs.mongodb.com/mongoid/current/tutorials/mongoid-configuration/#usage-with-forking-servers>`_
1228
+ however provides examples for closing clients in the parent process and
1229
+ reconnecting clients in the child processes.
1181
1230
1182
1231
1183
1232
Details on Retryable Reads
0 commit comments