mongo 2.23.0 → 2.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. checksums.yaml +4 -4
  2. data/bin/mongo_console +0 -1
  3. data/lib/mongo/active_support.rb +1 -2
  4. data/lib/mongo/address/ipv4.rb +3 -6
  5. data/lib/mongo/address/ipv6.rb +6 -10
  6. data/lib/mongo/address/unix.rb +1 -4
  7. data/lib/mongo/address/validator.rb +16 -28
  8. data/lib/mongo/address.rb +30 -40
  9. data/lib/mongo/auth/aws/conversation.rb +6 -10
  10. data/lib/mongo/auth/aws/credentials.rb +0 -1
  11. data/lib/mongo/auth/aws/credentials_cache.rb +0 -1
  12. data/lib/mongo/auth/aws/credentials_retriever.rb +45 -59
  13. data/lib/mongo/auth/aws/request.rb +20 -35
  14. data/lib/mongo/auth/aws.rb +1 -2
  15. data/lib/mongo/auth/base.rb +20 -29
  16. data/lib/mongo/auth/conversation_base.rb +14 -18
  17. data/lib/mongo/auth/cr/conversation.rb +0 -3
  18. data/lib/mongo/auth/cr.rb +1 -4
  19. data/lib/mongo/auth/credential_cache.rb +0 -2
  20. data/lib/mongo/auth/gssapi/conversation.rb +3 -8
  21. data/lib/mongo/auth/gssapi.rb +1 -4
  22. data/lib/mongo/auth/ldap/conversation.rb +0 -3
  23. data/lib/mongo/auth/ldap.rb +1 -4
  24. data/lib/mongo/auth/roles.rb +16 -19
  25. data/lib/mongo/auth/sasl_conversation_base.rb +7 -11
  26. data/lib/mongo/auth/scram/conversation.rb +2 -5
  27. data/lib/mongo/auth/scram.rb +5 -10
  28. data/lib/mongo/auth/scram256/conversation.rb +2 -5
  29. data/lib/mongo/auth/scram256.rb +1 -3
  30. data/lib/mongo/auth/scram_conversation_base.rb +18 -24
  31. data/lib/mongo/auth/stringprep/profiles/sasl.rb +17 -18
  32. data/lib/mongo/auth/stringprep/tables.rb +2209 -2210
  33. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +36 -38
  34. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +1142 -1150
  35. data/lib/mongo/auth/stringprep.rb +9 -12
  36. data/lib/mongo/auth/user/view.rb +3 -5
  37. data/lib/mongo/auth/user.rb +14 -24
  38. data/lib/mongo/auth/x509/conversation.rb +0 -3
  39. data/lib/mongo/auth/x509.rb +7 -9
  40. data/lib/mongo/auth.rb +18 -30
  41. data/lib/mongo/background_thread.rb +9 -17
  42. data/lib/mongo/bson.rb +0 -2
  43. data/lib/mongo/bulk_write/combineable.rb +0 -3
  44. data/lib/mongo/bulk_write/ordered_combiner.rb +1 -3
  45. data/lib/mongo/bulk_write/result.rb +11 -16
  46. data/lib/mongo/bulk_write/result_combiner.rb +9 -12
  47. data/lib/mongo/bulk_write/transformable.rb +16 -19
  48. data/lib/mongo/bulk_write/unordered_combiner.rb +1 -3
  49. data/lib/mongo/bulk_write/validatable.rb +11 -18
  50. data/lib/mongo/bulk_write.rb +76 -91
  51. data/lib/mongo/caching_cursor.rb +2 -7
  52. data/lib/mongo/client.rb +230 -275
  53. data/lib/mongo/client_encryption.rb +4 -5
  54. data/lib/mongo/cluster/periodic_executor.rb +2 -5
  55. data/lib/mongo/cluster/reapers/cursor_reaper.rb +21 -29
  56. data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -6
  57. data/lib/mongo/cluster/sdam_flow.rb +136 -159
  58. data/lib/mongo/cluster/topology/base.rb +15 -18
  59. data/lib/mongo/cluster/topology/load_balanced.rb +24 -14
  60. data/lib/mongo/cluster/topology/no_replica_set_options.rb +3 -6
  61. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +20 -23
  62. data/lib/mongo/cluster/topology/replica_set_with_primary.rb +0 -2
  63. data/lib/mongo/cluster/topology/sharded.rb +19 -9
  64. data/lib/mongo/cluster/topology/single.rb +24 -14
  65. data/lib/mongo/cluster/topology/unknown.rb +20 -10
  66. data/lib/mongo/cluster/topology.rb +29 -25
  67. data/lib/mongo/cluster.rb +148 -183
  68. data/lib/mongo/cluster_time.rb +14 -31
  69. data/lib/mongo/collection/helpers.rb +5 -8
  70. data/lib/mongo/collection/view/aggregation.rb +5 -10
  71. data/lib/mongo/collection/view/builder/aggregation.rb +6 -9
  72. data/lib/mongo/collection/view/builder/map_reduce.rb +18 -17
  73. data/lib/mongo/collection/view/builder.rb +0 -1
  74. data/lib/mongo/collection/view/change_stream/retryable.rb +3 -8
  75. data/lib/mongo/collection/view/change_stream.rb +59 -58
  76. data/lib/mongo/collection/view/explainable.rb +11 -20
  77. data/lib/mongo/collection/view/immutable.rb +1 -3
  78. data/lib/mongo/collection/view/iterable.rb +35 -28
  79. data/lib/mongo/collection/view/map_reduce.rb +20 -25
  80. data/lib/mongo/collection/view/readable.rb +50 -57
  81. data/lib/mongo/collection/view/writable.rb +56 -72
  82. data/lib/mongo/collection/view.rb +9 -8
  83. data/lib/mongo/collection.rb +63 -76
  84. data/lib/mongo/condition_variable.rb +4 -4
  85. data/lib/mongo/config/options.rb +0 -3
  86. data/lib/mongo/config/validators/option.rb +3 -5
  87. data/lib/mongo/config.rb +2 -4
  88. data/lib/mongo/crypt/auto_decryption_context.rb +0 -3
  89. data/lib/mongo/crypt/auto_encrypter.rb +34 -43
  90. data/lib/mongo/crypt/auto_encryption_context.rb +0 -3
  91. data/lib/mongo/crypt/binary.rb +5 -9
  92. data/lib/mongo/crypt/binding.rb +149 -155
  93. data/lib/mongo/crypt/context.rb +10 -17
  94. data/lib/mongo/crypt/data_key_context.rb +2 -7
  95. data/lib/mongo/crypt/encryption_io.rb +29 -39
  96. data/lib/mongo/crypt/explicit_decryption_context.rb +0 -3
  97. data/lib/mongo/crypt/explicit_encrypter.rb +1 -1
  98. data/lib/mongo/crypt/explicit_encryption_context.rb +19 -30
  99. data/lib/mongo/crypt/explicit_encryption_expression_context.rb +0 -2
  100. data/lib/mongo/crypt/handle.rb +42 -48
  101. data/lib/mongo/crypt/hooks.rb +12 -15
  102. data/lib/mongo/crypt/kms/aws/credentials.rb +12 -16
  103. data/lib/mongo/crypt/kms/aws/master_document.rb +6 -9
  104. data/lib/mongo/crypt/kms/aws.rb +0 -2
  105. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +2 -7
  106. data/lib/mongo/crypt/kms/azure/master_document.rb +15 -19
  107. data/lib/mongo/crypt/kms/azure.rb +0 -1
  108. data/lib/mongo/crypt/kms/credentials.rb +13 -27
  109. data/lib/mongo/crypt/kms/gcp/credentials.rb +12 -14
  110. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +7 -9
  111. data/lib/mongo/crypt/kms/gcp/master_document.rb +12 -16
  112. data/lib/mongo/crypt/kms/gcp.rb +0 -2
  113. data/lib/mongo/crypt/kms/kmip/credentials.rb +7 -8
  114. data/lib/mongo/crypt/kms/kmip/master_document.rb +3 -5
  115. data/lib/mongo/crypt/kms/kmip.rb +0 -1
  116. data/lib/mongo/crypt/kms/local/credentials.rb +7 -8
  117. data/lib/mongo/crypt/kms/local/master_document.rb +2 -6
  118. data/lib/mongo/crypt/kms/local.rb +0 -1
  119. data/lib/mongo/crypt/kms/master_key_document.rb +11 -15
  120. data/lib/mongo/crypt/kms.rb +14 -16
  121. data/lib/mongo/crypt/kms_context.rb +0 -2
  122. data/lib/mongo/crypt/rewrap_many_data_key_context.rb +2 -7
  123. data/lib/mongo/crypt/rewrap_many_data_key_result.rb +2 -4
  124. data/lib/mongo/crypt/status.rb +12 -14
  125. data/lib/mongo/crypt.rb +0 -1
  126. data/lib/mongo/csot_timeout_holder.rb +3 -2
  127. data/lib/mongo/cursor/kill_spec.rb +7 -10
  128. data/lib/mongo/cursor.rb +74 -64
  129. data/lib/mongo/cursor_host.rb +8 -10
  130. data/lib/mongo/database/view.rb +16 -37
  131. data/lib/mongo/database.rb +52 -56
  132. data/lib/mongo/dbref.rb +0 -1
  133. data/lib/mongo/distinguishing_semaphore.rb +0 -1
  134. data/lib/mongo/error/auth_error.rb +0 -2
  135. data/lib/mongo/error/bad_load_balancer_target.rb +0 -2
  136. data/lib/mongo/error/bulk_write_error.rb +7 -10
  137. data/lib/mongo/error/change_stream_resumable.rb +0 -2
  138. data/lib/mongo/error/client_closed.rb +0 -2
  139. data/lib/mongo/error/closed_stream.rb +1 -4
  140. data/lib/mongo/error/connection_check_out_timeout.rb +3 -6
  141. data/lib/mongo/error/connection_perished.rb +0 -2
  142. data/lib/mongo/error/connection_unavailable.rb +0 -2
  143. data/lib/mongo/error/credential_check_error.rb +0 -2
  144. data/lib/mongo/error/crypt_error.rb +0 -2
  145. data/lib/mongo/error/extra_file_chunk.rb +1 -4
  146. data/lib/mongo/error/failed_string_prep_validation.rb +5 -6
  147. data/lib/mongo/error/file_not_found.rb +0 -3
  148. data/lib/mongo/error/handshake_error.rb +0 -2
  149. data/lib/mongo/error/insufficient_iteration_count.rb +1 -4
  150. data/lib/mongo/error/internal_driver_error.rb +0 -2
  151. data/lib/mongo/error/invalid_address.rb +0 -2
  152. data/lib/mongo/error/invalid_application_name.rb +0 -3
  153. data/lib/mongo/error/invalid_bulk_operation.rb +1 -4
  154. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -4
  155. data/lib/mongo/error/invalid_collection_name.rb +1 -4
  156. data/lib/mongo/error/invalid_config_option.rb +0 -3
  157. data/lib/mongo/error/invalid_cursor_operation.rb +0 -2
  158. data/lib/mongo/error/invalid_database_name.rb +1 -4
  159. data/lib/mongo/error/invalid_document.rb +1 -4
  160. data/lib/mongo/error/invalid_file.rb +0 -3
  161. data/lib/mongo/error/invalid_file_revision.rb +0 -3
  162. data/lib/mongo/error/invalid_min_pool_size.rb +0 -3
  163. data/lib/mongo/error/invalid_nonce.rb +0 -3
  164. data/lib/mongo/error/invalid_read_concern.rb +2 -4
  165. data/lib/mongo/error/invalid_read_option.rb +0 -3
  166. data/lib/mongo/error/invalid_replacement_document.rb +2 -5
  167. data/lib/mongo/error/invalid_server_auth_host.rb +0 -2
  168. data/lib/mongo/error/invalid_server_auth_response.rb +0 -2
  169. data/lib/mongo/error/invalid_server_preference.rb +7 -16
  170. data/lib/mongo/error/invalid_session.rb +1 -4
  171. data/lib/mongo/error/invalid_signature.rb +0 -3
  172. data/lib/mongo/error/invalid_transaction_operation.rb +5 -8
  173. data/lib/mongo/error/invalid_txt_record.rb +0 -2
  174. data/lib/mongo/error/invalid_update_document.rb +2 -5
  175. data/lib/mongo/error/invalid_uri.rb +1 -4
  176. data/lib/mongo/error/invalid_write_concern.rb +2 -5
  177. data/lib/mongo/error/kms_error.rb +0 -2
  178. data/lib/mongo/error/labelable.rb +0 -3
  179. data/lib/mongo/error/lint_error.rb +0 -2
  180. data/lib/mongo/error/max_bson_size.rb +8 -11
  181. data/lib/mongo/error/max_message_size.rb +2 -5
  182. data/lib/mongo/error/mismatched_domain.rb +0 -2
  183. data/lib/mongo/error/missing_connection.rb +0 -2
  184. data/lib/mongo/error/missing_file_chunk.rb +0 -3
  185. data/lib/mongo/error/missing_password.rb +0 -2
  186. data/lib/mongo/error/missing_resume_token.rb +1 -4
  187. data/lib/mongo/error/missing_scram_server_signature.rb +2 -4
  188. data/lib/mongo/error/missing_service_id.rb +0 -2
  189. data/lib/mongo/error/mongocryptd_spawn_error.rb +0 -2
  190. data/lib/mongo/error/multi_index_drop.rb +0 -3
  191. data/lib/mongo/error/need_primary_server.rb +0 -2
  192. data/lib/mongo/error/no_server_available.rb +3 -8
  193. data/lib/mongo/error/no_service_connection_available.rb +1 -3
  194. data/lib/mongo/error/no_srv_records.rb +0 -2
  195. data/lib/mongo/error/notable.rb +8 -16
  196. data/lib/mongo/error/operation_failure.rb +22 -35
  197. data/lib/mongo/error/parser.rb +33 -75
  198. data/lib/mongo/error/pool_cleared_error.rb +1 -3
  199. data/lib/mongo/error/pool_closed_error.rb +0 -3
  200. data/lib/mongo/error/pool_error.rb +0 -3
  201. data/lib/mongo/error/pool_paused_error.rb +0 -2
  202. data/lib/mongo/error/raise_original_error.rb +1 -3
  203. data/lib/mongo/error/read_write_retryable.rb +14 -17
  204. data/lib/mongo/error/sdam_error_detection.rb +3 -5
  205. data/lib/mongo/error/server_api_conflict.rb +0 -2
  206. data/lib/mongo/error/server_certificate_revoked.rb +0 -2
  207. data/lib/mongo/error/server_not_usable.rb +0 -2
  208. data/lib/mongo/error/session_ended.rb +1 -3
  209. data/lib/mongo/error/session_not_materialized.rb +1 -3
  210. data/lib/mongo/error/sessions_not_supported.rb +1 -4
  211. data/lib/mongo/error/snapshot_session_invalid_server_version.rb +1 -4
  212. data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +1 -4
  213. data/lib/mongo/error/socket_error.rb +0 -2
  214. data/lib/mongo/error/socket_timeout_error.rb +0 -2
  215. data/lib/mongo/error/transactions_not_supported.rb +3 -6
  216. data/lib/mongo/error/unchangeable_collection_option.rb +1 -4
  217. data/lib/mongo/error/unexpected_chunk_length.rb +0 -3
  218. data/lib/mongo/error/unexpected_response.rb +1 -4
  219. data/lib/mongo/error/unknown_payload_type.rb +0 -3
  220. data/lib/mongo/error/unmet_dependency.rb +0 -2
  221. data/lib/mongo/error/unsupported_array_filters.rb +3 -24
  222. data/lib/mongo/error/unsupported_collation.rb +3 -24
  223. data/lib/mongo/error/unsupported_features.rb +0 -2
  224. data/lib/mongo/error/unsupported_message_type.rb +0 -2
  225. data/lib/mongo/error/unsupported_option.rb +19 -21
  226. data/lib/mongo/error/write_retryable.rb +0 -2
  227. data/lib/mongo/error.rb +10 -24
  228. data/lib/mongo/event/base.rb +0 -2
  229. data/lib/mongo/event/listeners.rb +0 -3
  230. data/lib/mongo/event/publisher.rb +0 -3
  231. data/lib/mongo/event/subscriber.rb +0 -4
  232. data/lib/mongo/event.rb +4 -6
  233. data/lib/mongo/grid/file/chunk.rb +7 -10
  234. data/lib/mongo/grid/file/info.rb +20 -24
  235. data/lib/mongo/grid/file.rb +7 -8
  236. data/lib/mongo/grid/fs_bucket.rb +40 -48
  237. data/lib/mongo/grid/stream/read.rb +25 -35
  238. data/lib/mongo/grid/stream/write.rb +17 -22
  239. data/lib/mongo/grid/stream.rb +2 -4
  240. data/lib/mongo/grid.rb +0 -1
  241. data/lib/mongo/id.rb +0 -1
  242. data/lib/mongo/index/view.rb +49 -48
  243. data/lib/mongo/index.rb +7 -10
  244. data/lib/mongo/lint.rb +31 -37
  245. data/lib/mongo/loggable.rb +5 -8
  246. data/lib/mongo/logger.rb +1 -7
  247. data/lib/mongo/monitoring/cmap_log_subscriber.rb +0 -2
  248. data/lib/mongo/monitoring/command_log_subscriber.rb +25 -33
  249. data/lib/mongo/monitoring/event/cmap/base.rb +0 -2
  250. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -4
  251. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +0 -3
  252. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +1 -4
  253. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +2 -5
  254. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +1 -4
  255. data/lib/mongo/monitoring/event/cmap/connection_created.rb +1 -4
  256. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +1 -4
  257. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +0 -3
  258. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +1 -4
  259. data/lib/mongo/monitoring/event/cmap/pool_created.rb +1 -4
  260. data/lib/mongo/monitoring/event/cmap/pool_ready.rb +1 -4
  261. data/lib/mongo/monitoring/event/cmap.rb +0 -1
  262. data/lib/mongo/monitoring/event/command_failed.rb +5 -9
  263. data/lib/mongo/monitoring/event/command_started.rb +8 -12
  264. data/lib/mongo/monitoring/event/command_succeeded.rb +7 -15
  265. data/lib/mongo/monitoring/event/secure.rb +15 -20
  266. data/lib/mongo/monitoring/event/server_closed.rb +1 -4
  267. data/lib/mongo/monitoring/event/server_description_changed.rb +4 -8
  268. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +5 -10
  269. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +1 -4
  270. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +3 -8
  271. data/lib/mongo/monitoring/event/server_opening.rb +1 -4
  272. data/lib/mongo/monitoring/event/topology_changed.rb +2 -5
  273. data/lib/mongo/monitoring/event/topology_closed.rb +1 -4
  274. data/lib/mongo/monitoring/event/topology_opening.rb +1 -4
  275. data/lib/mongo/monitoring/event.rb +0 -1
  276. data/lib/mongo/monitoring/publishable.rb +20 -30
  277. data/lib/mongo/monitoring/sdam_log_subscriber.rb +0 -2
  278. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +0 -3
  279. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +0 -3
  280. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +0 -3
  281. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +5 -8
  282. data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +0 -3
  283. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +0 -3
  284. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +1 -3
  285. data/lib/mongo/monitoring.rb +38 -39
  286. data/lib/mongo/operation/aggregate/op_msg.rb +0 -2
  287. data/lib/mongo/operation/aggregate/result.rb +3 -6
  288. data/lib/mongo/operation/aggregate.rb +0 -2
  289. data/lib/mongo/operation/collections_info/result.rb +0 -3
  290. data/lib/mongo/operation/collections_info.rb +0 -2
  291. data/lib/mongo/operation/command/op_msg.rb +1 -4
  292. data/lib/mongo/operation/command.rb +0 -2
  293. data/lib/mongo/operation/context.rb +13 -16
  294. data/lib/mongo/operation/count/op_msg.rb +2 -4
  295. data/lib/mongo/operation/count.rb +0 -2
  296. data/lib/mongo/operation/create/op_msg.rb +2 -5
  297. data/lib/mongo/operation/create.rb +0 -2
  298. data/lib/mongo/operation/create_index/op_msg.rb +3 -7
  299. data/lib/mongo/operation/create_index.rb +0 -2
  300. data/lib/mongo/operation/create_user/op_msg.rb +2 -4
  301. data/lib/mongo/operation/create_user.rb +0 -2
  302. data/lib/mongo/operation/delete/bulk_result.rb +2 -3
  303. data/lib/mongo/operation/delete/op_msg.rb +3 -10
  304. data/lib/mongo/operation/delete/result.rb +0 -3
  305. data/lib/mongo/operation/delete.rb +1 -5
  306. data/lib/mongo/operation/distinct/op_msg.rb +2 -5
  307. data/lib/mongo/operation/distinct.rb +0 -2
  308. data/lib/mongo/operation/drop/op_msg.rb +0 -2
  309. data/lib/mongo/operation/drop.rb +0 -2
  310. data/lib/mongo/operation/drop_database/op_msg.rb +0 -2
  311. data/lib/mongo/operation/drop_database.rb +0 -2
  312. data/lib/mongo/operation/drop_index/op_msg.rb +4 -6
  313. data/lib/mongo/operation/drop_index.rb +0 -2
  314. data/lib/mongo/operation/explain/op_msg.rb +0 -2
  315. data/lib/mongo/operation/explain/result.rb +0 -3
  316. data/lib/mongo/operation/explain.rb +0 -2
  317. data/lib/mongo/operation/find/builder/command.rb +4 -12
  318. data/lib/mongo/operation/find/builder/flags.rb +9 -15
  319. data/lib/mongo/operation/find/builder/modifiers.rb +1 -4
  320. data/lib/mongo/operation/find/builder.rb +0 -1
  321. data/lib/mongo/operation/find/op_msg.rb +4 -12
  322. data/lib/mongo/operation/find/result.rb +0 -3
  323. data/lib/mongo/operation/find.rb +0 -2
  324. data/lib/mongo/operation/get_more/command_builder.rb +1 -6
  325. data/lib/mongo/operation/get_more/op_msg.rb +10 -4
  326. data/lib/mongo/operation/get_more/result.rb +0 -3
  327. data/lib/mongo/operation/get_more.rb +0 -2
  328. data/lib/mongo/operation/indexes/op_msg.rb +0 -2
  329. data/lib/mongo/operation/indexes/result.rb +1 -5
  330. data/lib/mongo/operation/indexes.rb +0 -2
  331. data/lib/mongo/operation/insert/bulk_result.rb +2 -6
  332. data/lib/mongo/operation/insert/op_msg.rb +2 -4
  333. data/lib/mongo/operation/insert/result.rb +0 -3
  334. data/lib/mongo/operation/insert.rb +2 -5
  335. data/lib/mongo/operation/kill_cursors/command_builder.rb +0 -3
  336. data/lib/mongo/operation/kill_cursors/op_msg.rb +1 -3
  337. data/lib/mongo/operation/kill_cursors.rb +0 -2
  338. data/lib/mongo/operation/list_collections/op_msg.rb +4 -6
  339. data/lib/mongo/operation/list_collections/result.rb +1 -4
  340. data/lib/mongo/operation/list_collections.rb +0 -2
  341. data/lib/mongo/operation/map_reduce/op_msg.rb +0 -2
  342. data/lib/mongo/operation/map_reduce/result.rb +3 -6
  343. data/lib/mongo/operation/map_reduce.rb +0 -2
  344. data/lib/mongo/operation/op_msg_base.rb +0 -1
  345. data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -5
  346. data/lib/mongo/operation/parallel_scan/result.rb +2 -5
  347. data/lib/mongo/operation/parallel_scan.rb +0 -2
  348. data/lib/mongo/operation/remove_user/op_msg.rb +2 -4
  349. data/lib/mongo/operation/remove_user.rb +0 -2
  350. data/lib/mongo/operation/result.rb +38 -48
  351. data/lib/mongo/operation/shared/bypass_document_validation.rb +3 -7
  352. data/lib/mongo/operation/shared/causal_consistency_supported.rb +0 -3
  353. data/lib/mongo/operation/shared/executable.rb +19 -28
  354. data/lib/mongo/operation/shared/executable_no_validate.rb +0 -3
  355. data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -2
  356. data/lib/mongo/operation/shared/idable.rb +3 -6
  357. data/lib/mongo/operation/shared/limited.rb +0 -3
  358. data/lib/mongo/operation/shared/object_id_generator.rb +0 -3
  359. data/lib/mongo/operation/shared/op_msg_executable.rb +0 -2
  360. data/lib/mongo/operation/shared/polymorphic_lookup.rb +0 -2
  361. data/lib/mongo/operation/shared/polymorphic_result.rb +2 -4
  362. data/lib/mongo/operation/shared/read_preference_supported.rb +10 -15
  363. data/lib/mongo/operation/shared/response_handling.rb +13 -26
  364. data/lib/mongo/operation/shared/result/aggregatable.rb +12 -13
  365. data/lib/mongo/operation/shared/sessions_supported.rb +87 -99
  366. data/lib/mongo/operation/shared/specifiable.rb +32 -58
  367. data/lib/mongo/operation/shared/write.rb +12 -17
  368. data/lib/mongo/operation/shared/write_concern_supported.rb +4 -7
  369. data/lib/mongo/operation/update/bulk_result.rb +13 -17
  370. data/lib/mongo/operation/update/op_msg.rb +2 -5
  371. data/lib/mongo/operation/update/result.rb +5 -5
  372. data/lib/mongo/operation/update.rb +1 -5
  373. data/lib/mongo/operation/update_user/op_msg.rb +2 -4
  374. data/lib/mongo/operation/update_user.rb +0 -2
  375. data/lib/mongo/operation/users_info/op_msg.rb +2 -4
  376. data/lib/mongo/operation/users_info/result.rb +1 -4
  377. data/lib/mongo/operation/users_info.rb +0 -2
  378. data/lib/mongo/operation/write_command/op_msg.rb +2 -10
  379. data/lib/mongo/operation/write_command.rb +0 -2
  380. data/lib/mongo/operation.rb +9 -14
  381. data/lib/mongo/options/mapper.rb +8 -15
  382. data/lib/mongo/options/redacted.rb +7 -9
  383. data/lib/mongo/options.rb +0 -1
  384. data/lib/mongo/protocol/bit_vector.rb +3 -5
  385. data/lib/mongo/protocol/caching_hash.rb +2 -7
  386. data/lib/mongo/protocol/compressed.rb +5 -10
  387. data/lib/mongo/protocol/get_more.rb +2 -8
  388. data/lib/mongo/protocol/kill_cursors.rb +2 -8
  389. data/lib/mongo/protocol/message.rb +103 -105
  390. data/lib/mongo/protocol/msg.rb +48 -63
  391. data/lib/mongo/protocol/query.rb +32 -41
  392. data/lib/mongo/protocol/registry.rb +2 -5
  393. data/lib/mongo/protocol/reply.rb +10 -16
  394. data/lib/mongo/protocol/serializers.rb +41 -59
  395. data/lib/mongo/protocol.rb +0 -1
  396. data/lib/mongo/query_cache.rb +7 -15
  397. data/lib/mongo/retryable/backpressure.rb +31 -0
  398. data/lib/mongo/retryable/base_worker.rb +39 -13
  399. data/lib/mongo/retryable/read_worker.rb +77 -21
  400. data/lib/mongo/retryable/retry_policy.rb +59 -0
  401. data/lib/mongo/retryable/write_worker.rb +155 -56
  402. data/lib/mongo/retryable.rb +70 -9
  403. data/lib/mongo/search_index/view.rb +1 -1
  404. data/lib/mongo/semaphore.rb +0 -1
  405. data/lib/mongo/server/app_metadata/environment.rb +3 -3
  406. data/lib/mongo/server/app_metadata.rb +4 -5
  407. data/lib/mongo/server/connection.rb +61 -61
  408. data/lib/mongo/server/connection_base.rb +43 -53
  409. data/lib/mongo/server/connection_common.rb +41 -64
  410. data/lib/mongo/server/connection_pool/generation_manager.rb +6 -11
  411. data/lib/mongo/server/connection_pool/populator.rb +1 -4
  412. data/lib/mongo/server/connection_pool.rb +195 -167
  413. data/lib/mongo/server/description/features.rb +23 -60
  414. data/lib/mongo/server/description/load_balancer.rb +0 -2
  415. data/lib/mongo/server/description.rb +117 -138
  416. data/lib/mongo/server/monitor/app_metadata.rb +3 -4
  417. data/lib/mongo/server/monitor/connection.rb +28 -35
  418. data/lib/mongo/server/monitor.rb +65 -60
  419. data/lib/mongo/server/pending_connection.rb +70 -71
  420. data/lib/mongo/server/push_monitor/connection.rb +0 -3
  421. data/lib/mongo/server/push_monitor.rb +21 -29
  422. data/lib/mongo/server/round_trip_time_calculator.rb +11 -17
  423. data/lib/mongo/server.rb +60 -93
  424. data/lib/mongo/server_selector/base.rb +133 -157
  425. data/lib/mongo/server_selector/nearest.rb +2 -5
  426. data/lib/mongo/server_selector/primary.rb +1 -5
  427. data/lib/mongo/server_selector/primary_preferred.rb +2 -6
  428. data/lib/mongo/server_selector/secondary.rb +2 -6
  429. data/lib/mongo/server_selector/secondary_preferred.rb +1 -5
  430. data/lib/mongo/server_selector.rb +3 -4
  431. data/lib/mongo/session/server_session.rb +6 -7
  432. data/lib/mongo/session/session_pool.rb +20 -34
  433. data/lib/mongo/session.rb +287 -188
  434. data/lib/mongo/socket/ocsp_cache.rb +8 -13
  435. data/lib/mongo/socket/ocsp_verifier.rb +69 -70
  436. data/lib/mongo/socket/ssl.rb +44 -43
  437. data/lib/mongo/socket/tcp.rb +5 -8
  438. data/lib/mongo/socket/unix.rb +0 -4
  439. data/lib/mongo/socket.rb +80 -102
  440. data/lib/mongo/srv/monitor.rb +6 -11
  441. data/lib/mongo/srv/resolver.rb +15 -24
  442. data/lib/mongo/srv/result.rb +18 -24
  443. data/lib/mongo/srv.rb +0 -1
  444. data/lib/mongo/timeout.rb +4 -11
  445. data/lib/mongo/topology_version.rb +8 -13
  446. data/lib/mongo/tracing/open_telemetry/command_tracer.rb +1 -1
  447. data/lib/mongo/tracing/open_telemetry/operation_tracer.rb +1 -1
  448. data/lib/mongo/tracing/open_telemetry/tracer.rb +1 -1
  449. data/lib/mongo/uri/options_mapper.rb +135 -126
  450. data/lib/mongo/uri/srv_protocol.rb +25 -38
  451. data/lib/mongo/uri.rb +95 -139
  452. data/lib/mongo/utils.rb +5 -12
  453. data/lib/mongo/version.rb +1 -1
  454. data/lib/mongo/write_concern/acknowledged.rb +0 -2
  455. data/lib/mongo/write_concern/base.rb +6 -6
  456. data/lib/mongo/write_concern/unacknowledged.rb +0 -2
  457. data/lib/mongo/write_concern.rb +14 -15
  458. data/lib/mongo.rb +1 -3
  459. data/mongo.gemspec +17 -17
  460. metadata +5 -5
  461. data/lib/mongo/error/server_api_not_supported.rb +0 -27
  462. data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +0 -32
  463. data/lib/mongo/operation/shared/validatable.rb +0 -87
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongo
4
+ module Retryable
5
+ # Constants and helpers for client backpressure (exponential backoff
6
+ # and jitter in retry loops).
7
+ #
8
+ # @api private
9
+ module Backpressure
10
+ # Base backoff delay in seconds.
11
+ BASE_BACKOFF = 0.1
12
+
13
+ # Maximum backoff delay in seconds.
14
+ MAX_BACKOFF = 10
15
+
16
+ # Default maximum number of retries for overload errors.
17
+ DEFAULT_MAX_RETRIES = 2
18
+
19
+ # Calculate the backoff delay for a given retry attempt.
20
+ #
21
+ # @param [ Integer ] attempt The retry attempt number (1-indexed).
22
+ # @param [ Float ] jitter A random float in [0.0, 1.0). Defaults to
23
+ # a random value. Can be injected for deterministic testing.
24
+ #
25
+ # @return [ Float ] The backoff delay in seconds.
26
+ def self.backoff_delay(attempt, jitter: rand)
27
+ jitter * [ MAX_BACKOFF, BASE_BACKOFF * (2**(attempt - 1)) ].min
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2015-2023 MongoDB Inc.
5
4
  #
@@ -17,7 +16,6 @@
17
16
 
18
17
  module Mongo
19
18
  module Retryable
20
-
21
19
  # The abstract superclass for workers employed by Mongo::Retryable.
22
20
  #
23
21
  # @api private
@@ -25,12 +23,12 @@ module Mongo
25
23
  extend Forwardable
26
24
 
27
25
  def_delegators :retryable,
28
- :client,
29
- :cluster,
30
- :select_server
26
+ :client,
27
+ :cluster,
28
+ :select_server
31
29
 
32
30
  # @return [ Mongo::Retryable ] retryable A reference to the client object
33
- # that instatiated this worker.
31
+ # that instantiated this worker.
34
32
  attr_reader :retryable
35
33
 
36
34
  # Constructs a new worker.
@@ -79,7 +77,6 @@ module Mongo
79
77
  ].freeze
80
78
  end
81
79
 
82
-
83
80
  # Tests to see if the given exception instance is of a type that can
84
81
  # be retried with modern retry mechanism.
85
82
  #
@@ -95,22 +92,51 @@ module Mongo
95
92
  def is_legacy_retryable_exception?(e)
96
93
  legacy_retryable_exceptions.any? { |klass| klass === e }
97
94
  end
95
+
98
96
  # Logs the given deprecation warning the first time it is called for a
99
97
  # given key; after that, it does nothing when given the same key.
100
98
  def deprecation_warning(key, warning)
101
99
  $_deprecation_warnings ||= {}
102
- unless $_deprecation_warnings[key]
103
- $_deprecation_warnings[key] = true
104
- Logger.logger.warn(warning)
105
- end
100
+ return if $_deprecation_warnings[key]
101
+
102
+ $_deprecation_warnings[key] = true
103
+ Logger.logger.warn(warning)
106
104
  end
107
105
 
108
106
  # Log a warning so that any application slow down is immediately obvious.
109
107
  def log_retry(e, options = nil)
110
- message = (options || {}).fetch(:message, "Retry")
108
+ message = (options || {}).fetch(:message, 'Retry')
111
109
  Logger.logger.warn "#{message} due to: #{e.class.name}: #{e.message}"
112
110
  end
113
- end
114
111
 
112
+ # Returns the retry policy from the client.
113
+ #
114
+ # @return [ Mongo::Retryable::RetryPolicy ] The retry policy.
115
+ def retry_policy
116
+ client.retry_policy
117
+ end
118
+
119
+ # Whether the error indicates server overload.
120
+ #
121
+ # @param [ Exception ] e The error to check.
122
+ #
123
+ # @return [ true | false ] true if the error has the
124
+ # SystemOverloadedError label.
125
+ def overload_error?(e)
126
+ e.respond_to?(:label?) && e.label?('SystemOverloadedError')
127
+ end
128
+
129
+ # Whether the error is a retryable overload error. An error is
130
+ # retryable overload when it has both the SystemOverloadedError and
131
+ # RetryableError labels.
132
+ #
133
+ # @param [ Exception ] e The error to check.
134
+ #
135
+ # @return [ true | false ] true if the error has both labels.
136
+ def retryable_overload_error?(e)
137
+ overload_error?(e) &&
138
+ e.respond_to?(:label?) && e.label?('RetryableError')
139
+ end
140
+ end
115
141
  end
116
142
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2015-2023 MongoDB Inc.
5
4
  #
@@ -19,7 +18,6 @@ require 'mongo/retryable/base_worker'
19
18
 
20
19
  module Mongo
21
20
  module Retryable
22
-
23
21
  # Implements the logic around retrying read operations.
24
22
  #
25
23
  # @api private
@@ -65,7 +63,7 @@ module Mongo
65
63
  # @param [ Proc ] block The block to execute.
66
64
  #
67
65
  # @return [ Cursor ] The cursor for the result set.
68
- def read_with_retry_cursor(session, server_selector, view, context: nil, &block)
66
+ def read_with_retry_cursor(session, server_selector, view, context: nil)
69
67
  read_with_retry(session, server_selector, context) do |server|
70
68
  result = yield server
71
69
 
@@ -171,8 +169,8 @@ module Mongo
171
169
  # @return [ Result ] The result of the operation.
172
170
  def deprecated_legacy_read_with_retry(&block)
173
171
  deprecation_warning :read_with_retry,
174
- 'Legacy read_with_retry invocation - ' \
175
- 'please update the application and/or its dependencies'
172
+ 'Legacy read_with_retry invocation - ' \
173
+ 'please update the application and/or its dependencies'
176
174
 
177
175
  # Since we don't have a session, we cannot use the modern read retries.
178
176
  # And we need to select a server but we don't have a server selector.
@@ -205,9 +203,15 @@ module Mongo
205
203
  yield server
206
204
  rescue *retryable_exceptions, Error::OperationFailure::Family, Auth::Unauthorized, Error::PoolError => e
207
205
  e.add_notes('modern retry', 'attempt 1')
208
- raise e if session.in_transaction?
209
- raise e if !is_retryable_exception?(e) && !e.write_retryable?
210
- retry_read(e, session, server_selector, context: context, failed_server: server, &block)
206
+ raise e if session.in_transaction? && !retryable_overload_error?(e)
207
+
208
+ if retryable_overload_error?(e)
209
+ overload_read_retry(e, session, server_selector, context, server, error_count: 1, &block)
210
+ else
211
+ raise e if !is_retryable_exception?(e) && !e.write_retryable?
212
+
213
+ retry_read(e, session, server_selector, context: context, failed_server: server, &block)
214
+ end
211
215
  end
212
216
 
213
217
  # Attempts to do a "legacy" read with retry. The operation will be
@@ -223,7 +227,7 @@ module Mongo
223
227
  # @param [ Proc ] block The block to execute.
224
228
  #
225
229
  # @return [ Result ] The result of the operation.
226
- def legacy_read_with_retry(session, server_selector, context = nil, &block)
230
+ def legacy_read_with_retry(session, server_selector, context = nil)
227
231
  context&.check_timeout!
228
232
  attempt = attempt ? attempt + 1 : 1
229
233
  yield select_server(cluster, server_selector, session)
@@ -253,7 +257,7 @@ module Mongo
253
257
  # @param [ Proc ] block The block to execute.
254
258
  #
255
259
  # @return [ Result ] The result of the operation.
256
- def read_without_retry(session, server_selector, &block)
260
+ def read_without_retry(session, server_selector)
257
261
  server = select_server(cluster, server_selector, session)
258
262
 
259
263
  begin
@@ -294,22 +298,25 @@ module Mongo
294
298
  raise
295
299
  rescue *retryable_exceptions => e
296
300
  e.add_notes('modern retry', "attempt #{attempt}")
297
- if context&.csot?
298
- failed_server = server
299
- retry
300
- else
301
- raise e
301
+ if retryable_overload_error?(e)
302
+ return overload_read_retry(e, session, server_selector, context, server, error_count: attempt, &block)
302
303
  end
304
+
305
+ raise e unless context&.csot?
306
+
307
+ retry
303
308
  rescue Error::OperationFailure::Family, Error::PoolError => e
304
309
  e.add_note('modern retry')
310
+ if retryable_overload_error?(e)
311
+ e.add_note("attempt #{attempt}")
312
+ return overload_read_retry(e, session, server_selector, context, server, error_count: attempt, &block)
313
+ end
305
314
  if e.write_retryable?
306
315
  e.add_note("attempt #{attempt}")
307
- if context&.csot?
308
- failed_server = server
309
- retry
310
- else
311
- raise e
312
- end
316
+ raise e unless context&.csot?
317
+
318
+ retry
319
+
313
320
  else
314
321
  original_error.add_note("later retry failed: #{e.class}: #{e}")
315
322
  raise original_error
@@ -321,12 +328,61 @@ module Mongo
321
328
  end
322
329
  end
323
330
 
331
+ # Retry loop for overload errors with exponential backoff.
332
+ # Each retry sleeps with jittered backoff, respects MAX_RETRIES,
333
+ # and consumes a token from the bucket when adaptive retries
334
+ # are enabled.
335
+ #
336
+ # Per the client-backpressure spec, backoff is applied if and only
337
+ # if the error triggering the retry is an overload error. Non-overload
338
+ # retryable errors that occur within this loop are retried immediately
339
+ # (without backoff) but still count toward MAX_RETRIES.
340
+ def overload_read_retry(last_error, session, server_selector, context, failed_server, error_count:)
341
+ last_was_overload = true
342
+ loop do
343
+ delay = last_was_overload ? retry_policy.backoff_delay(error_count) : 0
344
+ raise last_error unless retry_policy.should_retry_overload?(error_count, delay, context: context)
345
+
346
+ log_retry(last_error, message: 'Read retry (overload backoff)')
347
+ sleep(delay) if last_was_overload
348
+
349
+ begin
350
+ server = select_server(
351
+ cluster, server_selector, session, failed_server,
352
+ error: last_error,
353
+ timeout: context&.remaining_timeout_sec
354
+ )
355
+ rescue Error, Error::AuthError => e
356
+ last_error.add_note("later retry failed: #{e.class}: #{e}")
357
+ raise last_error
358
+ end
359
+
360
+ begin
361
+ context&.check_timeout!
362
+ result = yield server, true
363
+ return result
364
+ rescue Error::TimeoutError
365
+ raise
366
+ rescue *retryable_exceptions, Error::OperationFailure::Family, Auth::Unauthorized, Error::PoolError => e
367
+ error_count += 1
368
+ e.add_notes('modern retry', "attempt #{error_count}")
369
+ is_overload = retryable_overload_error?(e)
370
+ raise e unless is_overload || is_retryable_exception?(e) || e.write_retryable?
371
+
372
+ last_was_overload = is_overload
373
+ failed_server = server
374
+ last_error = e
375
+ end
376
+ end
377
+ end
378
+
324
379
  def select_server_for_retry(original_error, session, server_selector, context, failed_server)
325
380
  select_server(
326
381
  cluster,
327
382
  server_selector,
328
383
  session,
329
384
  failed_server,
385
+ error: original_error,
330
386
  timeout: context&.remaining_timeout_sec
331
387
  )
332
388
  rescue Error, Error::AuthError => e
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongo
4
+ module Retryable
5
+ # Encapsulates the retry policy for client backpressure with
6
+ # exponential backoff and jitter.
7
+ #
8
+ # One instance is created per Client and shared across all operations
9
+ # on that client.
10
+ #
11
+ # @api private
12
+ class RetryPolicy
13
+ # @return [ Integer ] The maximum number of overload retries.
14
+ attr_reader :max_retries
15
+
16
+ # Create a new retry policy.
17
+ #
18
+ # @param [ Integer ] max_retries The maximum number of overload
19
+ # retry attempts. Defaults to Backpressure::DEFAULT_MAX_RETRIES.
20
+ def initialize(max_retries: Backpressure::DEFAULT_MAX_RETRIES)
21
+ @max_retries = max_retries
22
+ end
23
+
24
+ # Calculate the backoff delay for a given retry attempt.
25
+ #
26
+ # @param [ Integer ] attempt The retry attempt number (1-indexed).
27
+ # @param [ Float ] jitter A random float in [0.0, 1.0).
28
+ #
29
+ # @return [ Float ] The backoff delay in seconds.
30
+ def backoff_delay(attempt, jitter: rand)
31
+ Backpressure.backoff_delay(attempt, jitter: jitter)
32
+ end
33
+
34
+ # Determine whether an overload retry should be attempted.
35
+ #
36
+ # @param [ Integer ] attempt The retry attempt number (1-indexed).
37
+ # @param [ Float ] delay The backoff delay in seconds.
38
+ # @param [ Mongo::Operation::Context | nil ] context The operation
39
+ # context (for CSOT deadline checking).
40
+ #
41
+ # @return [ true | false ] Whether the retry should proceed.
42
+ def should_retry_overload?(attempt, delay, context: nil)
43
+ return false if attempt > @max_retries
44
+ return false if exceeds_deadline?(delay, context)
45
+
46
+ true
47
+ end
48
+
49
+ private
50
+
51
+ def exceeds_deadline?(delay, context)
52
+ return false unless context&.csot?
53
+
54
+ deadline = context&.deadline
55
+ deadline&.nonzero? && Utils.monotonic_time + delay > deadline
56
+ end
57
+ end
58
+ end
59
+ end