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
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2019-2021 MongoDB Inc.
5
4
  #
@@ -18,15 +17,13 @@
18
17
  module Mongo
19
18
  module Crypt
20
19
  module KMS
21
-
22
20
  # KMS master key document object contains KMS master key parameters
23
21
  # that are used for creation of data keys.
24
22
  #
25
23
  # @api private
26
24
  class MasterKeyDocument
27
-
28
25
  # Known KMS provider names.
29
- KMS_PROVIDERS = %w(aws azure gcp kmip local).freeze
26
+ KMS_PROVIDERS = %w[aws azure gcp kmip local].freeze
30
27
 
31
28
  # Creates a master key document object form a parameters hash.
32
29
  #
@@ -38,19 +35,18 @@ module Mongo
38
35
  #
39
36
  # @raise [ ArgumentError ] If required options are missing or incorrectly.
40
37
  def initialize(kms_provider, options)
41
- if options.nil?
42
- raise ArgumentError.new('Key document options must not be nil')
43
- end
38
+ raise ArgumentError.new('Key document options must not be nil') if options.nil?
39
+
44
40
  master_key = options.fetch(:master_key, {})
45
41
  @key_document = case kms_provider.to_s
46
- when 'aws' then KMS::AWS::MasterKeyDocument.new(master_key)
47
- when 'azure' then KMS::Azure::MasterKeyDocument.new(master_key)
48
- when 'gcp' then KMS::GCP::MasterKeyDocument.new(master_key)
49
- when 'kmip' then KMS::KMIP::MasterKeyDocument.new(master_key)
50
- when 'local' then KMS::Local::MasterKeyDocument.new(master_key)
51
- else
52
- raise ArgumentError.new("KMS provider must be one of #{KMS_PROVIDERS}")
53
- end
42
+ when 'aws' then KMS::AWS::MasterKeyDocument.new(master_key)
43
+ when 'azure' then KMS::Azure::MasterKeyDocument.new(master_key)
44
+ when 'gcp' then KMS::GCP::MasterKeyDocument.new(master_key)
45
+ when 'kmip' then KMS::KMIP::MasterKeyDocument.new(master_key)
46
+ when 'local' then KMS::Local::MasterKeyDocument.new(master_key)
47
+ else
48
+ raise ArgumentError.new("KMS provider must be one of #{KMS_PROVIDERS}")
49
+ end
54
50
  end
55
51
 
56
52
  # Convert master key document object to a BSON document in libmongocrypt format.
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2019-2021 MongoDB Inc.
5
4
  #
@@ -43,10 +42,11 @@ module Mongo
43
42
  def validate_param(key, opts, format_hint, required: true)
44
43
  value = opts.fetch(key)
45
44
  return nil if value.nil? && !required
45
+
46
46
  if value.nil?
47
47
  raise ArgumentError.new(
48
48
  "The #{key} option must be a String with at least one character; " \
49
- "currently have nil"
49
+ 'currently have nil'
50
50
  )
51
51
  end
52
52
  unless value.is_a?(String)
@@ -58,7 +58,7 @@ module Mongo
58
58
  if value.empty?
59
59
  raise ArgumentError.new(
60
60
  "The #{key} option must be a String with at least one character; " \
61
- "it is currently an empty string"
61
+ 'it is currently an empty string'
62
62
  )
63
63
  end
64
64
  value
@@ -68,8 +68,6 @@ module Mongo
68
68
  "The specified KMS provider options are invalid: #{opts}. " +
69
69
  format_hint
70
70
  )
71
- else
72
- nil
73
71
  end
74
72
  end
75
73
 
@@ -92,17 +90,17 @@ module Mongo
92
90
  "Incorrect TLS options for #{provider}: TLS is required"
93
91
  )
94
92
  end
95
- %i(
93
+ %i[
96
94
  ssl_verify_certificate
97
95
  ssl_verify_hostname
98
- ).each do |opt|
99
- if provider_opts[opt] == false
100
- raise ArgumentError.new(
101
- "Incorrect TLS options for #{provider}: " +
102
- 'Insecure TLS options prohibited, ' +
103
- "#{opt} cannot be set to false for KMS"
104
- )
105
- end
96
+ ].each do |opt|
97
+ next unless provider_opts[opt] == false
98
+
99
+ raise ArgumentError.new(
100
+ "Incorrect TLS options for #{provider}: " +
101
+ 'Insecure TLS options prohibited, ' +
102
+ "#{opt} cannot be set to false for KMS"
103
+ )
106
104
  end
107
105
  end
108
106
  opts
@@ -113,8 +111,8 @@ module Mongo
113
111
  end
114
112
  end
115
113
 
116
- require "mongo/crypt/kms/credentials"
117
- require "mongo/crypt/kms/master_key_document"
114
+ require 'mongo/crypt/kms/credentials'
115
+ require 'mongo/crypt/kms/master_key_document'
118
116
  require 'mongo/crypt/kms/aws'
119
117
  require 'mongo/crypt/kms/azure'
120
118
  require 'mongo/crypt/kms/gcp'
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2019-2020 MongoDB Inc.
5
4
  #
@@ -17,7 +16,6 @@
17
16
 
18
17
  module Mongo
19
18
  module Crypt
20
-
21
19
  # Wraps a libmongocrypt mongocrypt_kms_ctx_t object. Contains information
22
20
  # about making an HTTP request to fetch information about a KMS
23
21
  # data key.
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2019-2020 MongoDB Inc.
5
4
  #
@@ -17,13 +16,11 @@
17
16
 
18
17
  module Mongo
19
18
  module Crypt
20
-
21
19
  # A Context object initialized specifically for the purpose of rewrapping
22
- # data keys (decrypting and re-rencryting using a new KEK).
20
+ # data keys (decrypting and re-encrypting using a new KEK).
23
21
  #
24
22
  # @api private
25
23
  class RewrapManyDataKeyContext < Context
26
-
27
24
  # Create a new RewrapManyDataKeyContext object
28
25
  #
29
26
  # @param [ Mongo::Crypt::Handle ] mongocrypt a Handle that
@@ -36,9 +33,7 @@ module Mongo
36
33
  # key document that contains master encryption key parameters.
37
34
  def initialize(mongocrypt, io, filter, master_key_document)
38
35
  super(mongocrypt, io)
39
- if master_key_document
40
- Binding.ctx_setopt_key_encryption_key(self, master_key_document.to_document)
41
- end
36
+ Binding.ctx_setopt_key_encryption_key(self, master_key_document.to_document) if master_key_document
42
37
  Binding.ctx_rewrap_many_datakey_init(self, filter)
43
38
  end
44
39
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2019-2022 MongoDB Inc.
5
4
  #
@@ -17,12 +16,11 @@
17
16
 
18
17
  module Mongo
19
18
  module Crypt
20
- # Represent result of the rewrap many data ke operation.
19
+ # Represent result of the rewrap many data key operation.
21
20
  #
22
21
  # @api semiprivate
23
22
  class RewrapManyDataKeyResult
24
-
25
- # @returns [ BulkWrite::Result ] the result of the bulk write operation
23
+ # @return [ BulkWrite::Result ] the result of the bulk write operation
26
24
  # used to update the key vault collection with rewrapped data keys.
27
25
  attr_reader :bulk_write_result
28
26
 
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  ## Copyright (C) 2019-2020 MongoDB Inc.
5
4
  #
@@ -19,7 +18,6 @@ require 'ffi'
19
18
 
20
19
  module Mongo
21
20
  module Crypt
22
-
23
21
  # A wrapper around mongocrypt_status_t, representing the status of
24
22
  # a mongocrypt_t handle.
25
23
  #
@@ -39,9 +37,9 @@ module Mongo
39
37
  # FFI::AutoPointer uses a custom release strategy to automatically free
40
38
  # the pointer once this object goes out of scope
41
39
  @status = pointer || FFI::AutoPointer.new(
42
- Binding.mongocrypt_status_new,
43
- Binding.method(:mongocrypt_status_destroy)
44
- )
40
+ Binding.mongocrypt_status_new,
41
+ Binding.method(:mongocrypt_status_destroy)
42
+ )
45
43
  end
46
44
 
47
45
  # Initialize a Status object from an existing pointer to a
@@ -52,7 +50,7 @@ module Mongo
52
50
  #
53
51
  # @return [ Mongo::Crypt::Status ] A new Status object
54
52
  def self.from_pointer(pointer)
55
- self.new(pointer: pointer)
53
+ new(pointer: pointer)
56
54
  end
57
55
 
58
56
  # Set a label, code, and message on the Status
@@ -63,10 +61,10 @@ module Mongo
63
61
  #
64
62
  # @return [ Mongo::Crypt::Status ] returns self
65
63
  def update(label, code, message)
66
- unless [:ok, :error_client, :error_kms].include?(label)
64
+ unless %i[ok error_client error_kms].include?(label)
67
65
  raise ArgumentError.new(
68
66
  "#{label} is an invalid value for a Mongo::Crypt::Status label. " +
69
- "Label must have one of the following values: :ok, :error_client, :error_kms"
67
+ 'Label must have one of the following values: :ok, :error_client, :error_kms'
70
68
  )
71
69
  end
72
70
 
@@ -109,7 +107,7 @@ module Mongo
109
107
  # Returns the reference to the underlying mongocrypt_status_t
110
108
  # object
111
109
  #
112
- # @return [ FFI::Pointer ] Pointer to the underlying mongocrypt_status_t oject
110
+ # @return [ FFI::Pointer ] Pointer to the underlying mongocrypt_status_t object
113
111
  def ref
114
112
  @status
115
113
  end
@@ -127,11 +125,11 @@ module Mongo
127
125
  def raise_crypt_error(kms: false)
128
126
  return if ok?
129
127
 
130
- if kms || label == :error_kms
131
- error = Error::KmsError.new(message, code: code)
132
- else
133
- error = Error::CryptError.new(message, code: code)
134
- end
128
+ error = if kms || label == :error_kms
129
+ Error::KmsError.new(message, code: code)
130
+ else
131
+ Error::CryptError.new(message, code: code)
132
+ end
135
133
 
136
134
  raise error
137
135
  end
data/lib/mongo/crypt.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2019-2020 MongoDB Inc.
5
4
  #
@@ -101,9 +101,10 @@ module Mongo
101
101
  end
102
102
 
103
103
  def check_no_override_inside_transaction!(opts, session)
104
- return unless opts[:operation_timeout_ms] && session&.with_transaction_deadline
104
+ return unless opts[:operation_timeout_ms] && session&.inside_with_transaction?
105
105
 
106
- raise ArgumentError, 'Cannot override timeout_ms inside with_transaction block'
106
+ raise Mongo::Error::InvalidTransactionOperation,
107
+ 'timeoutMS cannot be overridden inside a withTransaction callback'
107
108
  end
108
109
 
109
110
  def calculate_deadline_from_timeout_ms(operation_timeout_ms)
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2021 MongoDB Inc.
5
4
  #
@@ -17,14 +16,12 @@
17
16
 
18
17
  module Mongo
19
18
  class Cursor
20
-
21
19
  # This class contains the operation specification for KillCursors.
22
20
  #
23
21
  # Its purpose is to ensure we don't misspell attribute names accidentally.
24
22
  #
25
23
  # @api private
26
24
  class KillSpec
27
-
28
25
  def initialize(
29
26
  cursor_id:,
30
27
  coll_name:,
@@ -44,12 +41,12 @@ module Mongo
44
41
  end
45
42
 
46
43
  attr_reader :cursor_id,
47
- :coll_name,
48
- :db_name,
49
- :connection_global_id,
50
- :server_address,
51
- :session,
52
- :connection
44
+ :coll_name,
45
+ :db_name,
46
+ :connection_global_id,
47
+ :server_address,
48
+ :session,
49
+ :connection
53
50
 
54
51
  def ==(other)
55
52
  cursor_id == other.cursor_id &&
@@ -61,7 +58,7 @@ module Mongo
61
58
  end
62
59
 
63
60
  def eql?(other)
64
- self.==(other)
61
+ self == other
65
62
  end
66
63
 
67
64
  def hash
data/lib/mongo/cursor.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2014-2020 MongoDB Inc.
5
4
  #
@@ -16,7 +15,6 @@
16
15
  # limitations under the License.
17
16
 
18
17
  module Mongo
19
-
20
18
  # Client-side representation of an iterator over a query result set on
21
19
  # the server.
22
20
  #
@@ -82,14 +80,14 @@ module Mongo
82
80
  @namespace = result.namespace
83
81
  @remaining = limit if limited?
84
82
  set_cursor_id(result)
85
- if @cursor_id.nil?
86
- raise ArgumentError, 'Cursor id must be present in the result'
87
- end
83
+ raise ArgumentError, 'Cursor id must be present in the result' if @cursor_id.nil?
84
+
88
85
  @options = options
89
86
  @session = @options[:session]
90
87
  @connection_global_id = result.connection_global_id
91
88
  @context = @options[:context]&.with(connection_global_id: connection_global_id_for_context) || fresh_context
92
89
  @explicitly_closed = false
90
+ @get_more_network_error = false
93
91
  @lock = Mutex.new
94
92
  if server.load_balancer?
95
93
  # We need the connection in the cursor only in load balanced topology;
@@ -126,9 +124,8 @@ module Mongo
126
124
  #
127
125
  # @api private
128
126
  def self.finalize(kill_spec, cluster)
129
- unless KillSpec === kill_spec
130
- raise ArgumentError, "First argument must be a KillSpec: #{kill_spec.inspect}"
131
- end
127
+ raise ArgumentError, "First argument must be a KillSpec: #{kill_spec.inspect}" unless kill_spec.is_a?(KillSpec)
128
+
132
129
  proc do
133
130
  cluster.schedule_kill_cursor(kill_spec)
134
131
  end
@@ -161,7 +158,6 @@ module Mongo
161
158
  #
162
159
  # @since 2.0.0
163
160
  def each
164
-
165
161
  # If we already iterated past the first batch (i.e., called get_more
166
162
  # at least once), the cursor on the server side has advanced past
167
163
  # the first batch and restarting iteration from the beginning by
@@ -184,9 +180,8 @@ module Mongo
184
180
  # StopIteration raised by try_next ends this loop.
185
181
  loop do
186
182
  document = try_next
187
- if explicitly_closed?
188
- raise Error::InvalidCursorOperation, 'Cursor was explicitly closed'
189
- end
183
+ raise Error::InvalidCursorOperation, 'Cursor was explicitly closed' if explicitly_closed?
184
+
190
185
  yield document if document
191
186
  end
192
187
  self
@@ -195,9 +190,8 @@ module Mongo
195
190
  # StopIteration raised by try_next ends this loop.
196
191
  loop do
197
192
  document = try_next
198
- if explicitly_closed?
199
- raise Error::InvalidCursorOperation, 'Cursor was explicitly closed'
200
- end
193
+ raise Error::InvalidCursorOperation, 'Cursor was explicitly closed' if explicitly_closed?
194
+
201
195
  documents << document if document
202
196
  end
203
197
  documents
@@ -235,16 +229,16 @@ module Mongo
235
229
  # On empty batches, we cache the batch resume token
236
230
  cache_batch_resume_token
237
231
 
238
- unless closed?
232
+ if closed?
233
+ @fully_iterated = true
234
+ raise StopIteration
235
+ else
239
236
  if exhausted?
240
237
  close
241
238
  @fully_iterated = true
242
239
  raise StopIteration
243
240
  end
244
241
  @documents = get_more
245
- else
246
- @fully_iterated = true
247
- raise StopIteration
248
242
  end
249
243
  else
250
244
  # cursor is closed here
@@ -252,20 +246,16 @@ module Mongo
252
246
  end
253
247
 
254
248
  # If there is at least one document, cache its _id
255
- if @documents[0]
256
- cache_resume_token(@documents[0])
257
- end
249
+ cache_resume_token(@documents[0]) if @documents[0]
258
250
 
259
251
  # Cache the batch resume token if we are iterating
260
252
  # over the last document, or if the batch is empty
261
253
  if @documents.size <= 1
262
254
  cache_batch_resume_token
263
- if closed?
264
- @fully_iterated = true
265
- end
255
+ @fully_iterated = true if closed?
266
256
  end
267
257
 
268
- return @documents.shift
258
+ @documents.shift
269
259
  end
270
260
 
271
261
  # Get the batch size.
@@ -277,7 +267,7 @@ module Mongo
277
267
  #
278
268
  # @since 2.2.0
279
269
  def batch_size
280
- value = @view.batch_size && @view.batch_size > 0 ? @view.batch_size : limit
270
+ value = (@view.batch_size && @view.batch_size > 0) ? @view.batch_size : limit
281
271
  if value == 0
282
272
  nil
283
273
  else
@@ -308,19 +298,21 @@ module Mongo
308
298
  ctx = context ? context.refresh(timeout_ms: opts[:timeout_ms]) : fresh_context(opts)
309
299
 
310
300
  unregister
311
- read_with_one_retry do
312
- spec = {
313
- coll_name: collection_name,
314
- db_name: database.name,
315
- cursor_ids: [id],
316
- }
317
- op = Operation::KillCursors.new(spec)
318
- execute_operation(op, context: ctx)
301
+ unless @get_more_network_error
302
+ read_with_one_retry do
303
+ spec = {
304
+ coll_name: collection_name,
305
+ db_name: database.name,
306
+ cursor_ids: [ id ],
307
+ }
308
+ op = Operation::KillCursors.new(spec)
309
+ execute_operation(op, context: ctx)
310
+ end
319
311
  end
320
312
 
321
313
  nil
322
- rescue Error::OperationFailure::Family, Error::SocketError, Error::SocketTimeoutError, Error::ServerNotUsable
323
- # Errors are swallowed since there is noting can be done by handling them.
314
+ rescue Error::OperationFailure::Family, Error::SocketError, Error::SocketTimeoutError, Error::ServerNotUsable, Error::ConnectionPerished
315
+ # Errors are swallowed since there is nothing can be done by handling them.
324
316
  ensure
325
317
  end_session
326
318
  @cursor_id = 0
@@ -369,19 +361,6 @@ module Mongo
369
361
  @cursor_id
370
362
  end
371
363
 
372
- # Get the number of documents to return. Used on 3.0 and lower server
373
- # versions.
374
- #
375
- # @example Get the number to return.
376
- # cursor.to_return
377
- #
378
- # @return [ Integer ] The number of documents to return.
379
- #
380
- # @since 2.2.0
381
- def to_return
382
- use_limit? ? @remaining : (batch_size || 0)
383
- end
384
-
385
364
  # Execute a getMore command and return the batch of documents
386
365
  # obtained from the server.
387
366
  #
@@ -396,7 +375,21 @@ module Mongo
396
375
  # doing so may result in silent data loss, the driver no longer retries
397
376
  # getMore operations in any circumstance.
398
377
  # https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.md#qa
399
- process(execute_operation(get_more_operation))
378
+ #
379
+ # However, overload errors (SystemOverloadedError + RetryableError) are
380
+ # retried with exponential backoff since the server never processed
381
+ # the request.
382
+ with_overload_retry(context: possibly_refreshed_context) do
383
+ process(execute_operation(get_more_operation))
384
+ end
385
+ rescue Error::SocketError, Error::SocketTimeoutError
386
+ @get_more_network_error = true
387
+ raise
388
+ rescue Error::OperationFailure => e
389
+ # When overload retries are exhausted on getMore, close the cursor
390
+ # so that killCursors is sent to the server.
391
+ close if e.label?('RetryableError') && e.label?('SystemOverloadedError')
392
+ raise
400
393
  end
401
394
 
402
395
  # @api private
@@ -417,6 +410,18 @@ module Mongo
417
410
  !!@fully_iterated
418
411
  end
419
412
 
413
+ # Refreshes the cursor's CSOT context so that the next getMore starts
414
+ # with a fresh timeout deadline. Used by tailable awaitData cursors to
415
+ # implement per-iteration timeout refresh as required by the CSOT spec.
416
+ # Only refreshes if this is a tailable awaitData cursor with an active timeout.
417
+ #
418
+ # @api private
419
+ def refresh_timeout!
420
+ return unless view.cursor_type == :tailable_await && context.timeout?
421
+
422
+ @context = @context.refresh(view: view)
423
+ end
424
+
420
425
  private
421
426
 
422
427
  def explicitly_closed?
@@ -427,7 +432,7 @@ module Mongo
427
432
 
428
433
  def batch_size_for_get_more
429
434
  if batch_size && use_limit?
430
- [batch_size, @remaining].min
435
+ [ batch_size, @remaining ].min
431
436
  else
432
437
  batch_size
433
438
  end
@@ -438,9 +443,9 @@ module Mongo
438
443
  end
439
444
 
440
445
  def cache_resume_token(doc)
441
- if doc[:_id] && doc[:_id].is_a?(Hash)
442
- @resume_token = doc[:_id] && doc[:_id].dup.freeze
443
- end
446
+ return unless doc[:_id] && doc[:_id].is_a?(Hash)
447
+
448
+ @resume_token = doc[:_id] && doc[:_id].dup.freeze
444
449
  end
445
450
 
446
451
  def cache_batch_resume_token
@@ -453,13 +458,10 @@ module Mongo
453
458
  db_name: database.name,
454
459
  coll_name: collection_name,
455
460
  cursor_id: id,
456
- # 3.2+ servers use batch_size, 3.0- servers use to_return.
457
- # TODO should to_return be calculated in the operation layer?
458
461
  batch_size: batch_size_for_get_more,
459
- to_return: to_return
460
462
  }
461
- if view.respond_to?(:options) && view.options.is_a?(Hash)
462
- spec[:comment] = view.options[:comment] unless view.options[:comment].nil?
463
+ if view.respond_to?(:options) && view.options.is_a?(Hash) && !view.options[:comment].nil?
464
+ spec[:comment] = view.options[:comment]
463
465
  end
464
466
  Operation::GetMore.new(spec)
465
467
  end
@@ -484,9 +486,7 @@ module Mongo
484
486
  end
485
487
  @cursor_id = set_cursor_id(result)
486
488
 
487
- if result.respond_to?(:post_batch_resume_token)
488
- @post_batch_resume_token = result.post_batch_resume_token
489
- end
489
+ @post_batch_resume_token = result.post_batch_resume_token if result.respond_to?(:post_batch_resume_token)
490
490
 
491
491
  end_session if closed?
492
492
 
@@ -527,6 +527,11 @@ module Mongo
527
527
  # @return [ Operation::Context ] the (possibly-refreshed) context.
528
528
  def possibly_refreshed_context
529
529
  return context if view.timeout_mode == :cursor_lifetime
530
+ # For tailable await cursors with CSOT, the timeout budget is shared across
531
+ # all getMore commands (cumulative). Only update the view reference; keep
532
+ # the same deadline so remaining time decreases across getMores.
533
+ return context.with(view: view) if view.cursor_type == :tailable_await
534
+
530
535
  context.refresh(view: view)
531
536
  end
532
537
 
@@ -580,7 +585,12 @@ module Mongo
580
585
  return if @connection.nil?
581
586
  return unless @connection.server.load_balancer?
582
587
 
583
- @connection.connection_pool.check_in(@connection)
588
+ @connection.unpin
589
+ # Do not check in if the connection is still pinned by something
590
+ # else (e.g. a transaction).
591
+ unless @connection.pinned?
592
+ @connection.connection_pool.check_in(@connection)
593
+ end
584
594
  @connection = nil
585
595
  end
586
596
  end
@@ -31,7 +31,6 @@ module Mongo
31
31
  # detected.
32
32
  #
33
33
  # @api private
34
- # rubocop:disable Metrics
35
34
  def validate_timeout_mode!(options, forbid: [])
36
35
  forbid.each do |key|
37
36
  raise ArgumentError, "#{key} is not allowed here" if options.key?(key)
@@ -49,19 +48,19 @@ module Mongo
49
48
  if timeout_mode == :cursor_lifetime
50
49
  raise ArgumentError, 'tailable cursors only support `timeout_mode: :iteration`'
51
50
  end
52
-
53
- # "Drivers MUST error if [the maxAwaitTimeMS] option is set,
54
- # timeoutMS is set to a non-zero value, and maxAwaitTimeMS is
55
- # greater than or equal to timeoutMS."
56
- max_await_time_ms = options[:max_await_time_ms] || 0
57
- if cursor_type == :tailable_await && max_await_time_ms >= timeout_ms
58
- raise ArgumentError, ':max_await_time_ms must not be >= :timeout_ms'
59
- end
60
51
  else
61
52
  # "For non-tailable cursors, the default value of timeoutMode
62
53
  # is CURSOR_LIFETIME."
63
54
  timeout_mode ||= :cursor_lifetime
64
55
  end
56
+
57
+ # "Drivers MUST error if [the maxAwaitTimeMS] option is set,
58
+ # timeoutMS is set to a non-zero value, and maxAwaitTimeMS is
59
+ # greater than or equal to timeoutMS."
60
+ max_await_time_ms = options[:max_await_time_ms] || 0
61
+ if max_await_time_ms.positive? && max_await_time_ms >= timeout_ms
62
+ raise ArgumentError, ':max_await_time_ms must not be >= :timeout_ms'
63
+ end
65
64
  elsif timeout_mode
66
65
  # "Drivers MUST error if timeoutMode is set and timeoutMS is not."
67
66
  raise ArgumentError, ':timeout_ms must be set if :timeout_mode is set'
@@ -77,6 +76,5 @@ module Mongo
77
76
  # if no timeout_mode was set initially.
78
77
  @timeout_mode = timeout_mode
79
78
  end
80
- # rubocop:enable Metrics
81
79
  end
82
80
  end