mongo 2.22.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 (467) 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 +267 -276
  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 +152 -184
  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/behavior.rb +1 -1
  71. data/lib/mongo/collection/view/aggregation.rb +10 -12
  72. data/lib/mongo/collection/view/builder/aggregation.rb +6 -9
  73. data/lib/mongo/collection/view/builder/map_reduce.rb +18 -17
  74. data/lib/mongo/collection/view/builder.rb +0 -1
  75. data/lib/mongo/collection/view/change_stream/retryable.rb +3 -8
  76. data/lib/mongo/collection/view/change_stream.rb +59 -58
  77. data/lib/mongo/collection/view/explainable.rb +11 -20
  78. data/lib/mongo/collection/view/immutable.rb +1 -3
  79. data/lib/mongo/collection/view/iterable.rb +44 -35
  80. data/lib/mongo/collection/view/map_reduce.rb +20 -25
  81. data/lib/mongo/collection/view/readable.rb +96 -94
  82. data/lib/mongo/collection/view/writable.rb +104 -114
  83. data/lib/mongo/collection/view.rb +11 -8
  84. data/lib/mongo/collection.rb +103 -106
  85. data/lib/mongo/condition_variable.rb +4 -4
  86. data/lib/mongo/config/options.rb +0 -3
  87. data/lib/mongo/config/validators/option.rb +3 -5
  88. data/lib/mongo/config.rb +6 -4
  89. data/lib/mongo/crypt/auto_decryption_context.rb +9 -3
  90. data/lib/mongo/crypt/auto_encrypter.rb +34 -43
  91. data/lib/mongo/crypt/auto_encryption_context.rb +0 -3
  92. data/lib/mongo/crypt/binary.rb +5 -9
  93. data/lib/mongo/crypt/binding.rb +150 -156
  94. data/lib/mongo/crypt/context.rb +20 -17
  95. data/lib/mongo/crypt/data_key_context.rb +2 -7
  96. data/lib/mongo/crypt/encryption_io.rb +29 -39
  97. data/lib/mongo/crypt/explicit_decryption_context.rb +9 -3
  98. data/lib/mongo/crypt/explicit_encrypter.rb +1 -1
  99. data/lib/mongo/crypt/explicit_encryption_context.rb +19 -30
  100. data/lib/mongo/crypt/explicit_encryption_expression_context.rb +0 -2
  101. data/lib/mongo/crypt/handle.rb +42 -48
  102. data/lib/mongo/crypt/hooks.rb +12 -15
  103. data/lib/mongo/crypt/kms/aws/credentials.rb +12 -16
  104. data/lib/mongo/crypt/kms/aws/master_document.rb +6 -9
  105. data/lib/mongo/crypt/kms/aws.rb +0 -2
  106. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +2 -7
  107. data/lib/mongo/crypt/kms/azure/master_document.rb +15 -19
  108. data/lib/mongo/crypt/kms/azure.rb +0 -1
  109. data/lib/mongo/crypt/kms/credentials.rb +13 -27
  110. data/lib/mongo/crypt/kms/gcp/credentials.rb +12 -14
  111. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +7 -9
  112. data/lib/mongo/crypt/kms/gcp/master_document.rb +12 -16
  113. data/lib/mongo/crypt/kms/gcp.rb +0 -2
  114. data/lib/mongo/crypt/kms/kmip/credentials.rb +7 -8
  115. data/lib/mongo/crypt/kms/kmip/master_document.rb +3 -5
  116. data/lib/mongo/crypt/kms/kmip.rb +0 -1
  117. data/lib/mongo/crypt/kms/local/credentials.rb +7 -8
  118. data/lib/mongo/crypt/kms/local/master_document.rb +2 -6
  119. data/lib/mongo/crypt/kms/local.rb +0 -1
  120. data/lib/mongo/crypt/kms/master_key_document.rb +11 -15
  121. data/lib/mongo/crypt/kms.rb +14 -16
  122. data/lib/mongo/crypt/kms_context.rb +0 -2
  123. data/lib/mongo/crypt/rewrap_many_data_key_context.rb +2 -7
  124. data/lib/mongo/crypt/rewrap_many_data_key_result.rb +2 -4
  125. data/lib/mongo/crypt/status.rb +12 -14
  126. data/lib/mongo/crypt.rb +0 -1
  127. data/lib/mongo/csot_timeout_holder.rb +3 -2
  128. data/lib/mongo/cursor/kill_spec.rb +7 -10
  129. data/lib/mongo/cursor.rb +74 -64
  130. data/lib/mongo/cursor_host.rb +8 -10
  131. data/lib/mongo/database/view.rb +23 -39
  132. data/lib/mongo/database.rb +68 -65
  133. data/lib/mongo/dbref.rb +0 -1
  134. data/lib/mongo/deprecations.rb +98 -0
  135. data/lib/mongo/distinguishing_semaphore.rb +0 -1
  136. data/lib/mongo/error/auth_error.rb +0 -2
  137. data/lib/mongo/error/bad_load_balancer_target.rb +0 -2
  138. data/lib/mongo/error/bulk_write_error.rb +7 -10
  139. data/lib/mongo/error/change_stream_resumable.rb +0 -2
  140. data/lib/mongo/error/client_closed.rb +0 -2
  141. data/lib/mongo/error/closed_stream.rb +1 -4
  142. data/lib/mongo/error/connection_check_out_timeout.rb +3 -6
  143. data/lib/mongo/error/connection_perished.rb +0 -2
  144. data/lib/mongo/error/connection_unavailable.rb +0 -2
  145. data/lib/mongo/error/credential_check_error.rb +0 -2
  146. data/lib/mongo/error/crypt_error.rb +0 -2
  147. data/lib/mongo/error/extra_file_chunk.rb +1 -4
  148. data/lib/mongo/error/failed_string_prep_validation.rb +5 -6
  149. data/lib/mongo/error/file_not_found.rb +0 -3
  150. data/lib/mongo/error/handshake_error.rb +0 -2
  151. data/lib/mongo/error/insufficient_iteration_count.rb +1 -4
  152. data/lib/mongo/error/internal_driver_error.rb +0 -2
  153. data/lib/mongo/error/invalid_address.rb +0 -2
  154. data/lib/mongo/error/invalid_application_name.rb +0 -3
  155. data/lib/mongo/error/invalid_bulk_operation.rb +1 -4
  156. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -4
  157. data/lib/mongo/error/invalid_collection_name.rb +1 -4
  158. data/lib/mongo/error/invalid_config_option.rb +0 -3
  159. data/lib/mongo/error/invalid_cursor_operation.rb +0 -2
  160. data/lib/mongo/error/invalid_database_name.rb +1 -4
  161. data/lib/mongo/error/invalid_document.rb +1 -4
  162. data/lib/mongo/error/invalid_file.rb +0 -3
  163. data/lib/mongo/error/invalid_file_revision.rb +0 -3
  164. data/lib/mongo/error/invalid_min_pool_size.rb +0 -3
  165. data/lib/mongo/error/invalid_nonce.rb +0 -3
  166. data/lib/mongo/error/invalid_read_concern.rb +2 -4
  167. data/lib/mongo/error/invalid_read_option.rb +0 -3
  168. data/lib/mongo/error/invalid_replacement_document.rb +2 -5
  169. data/lib/mongo/error/invalid_server_auth_host.rb +0 -2
  170. data/lib/mongo/error/invalid_server_auth_response.rb +0 -2
  171. data/lib/mongo/error/invalid_server_preference.rb +7 -16
  172. data/lib/mongo/error/invalid_session.rb +1 -4
  173. data/lib/mongo/error/invalid_signature.rb +0 -3
  174. data/lib/mongo/error/invalid_transaction_operation.rb +5 -8
  175. data/lib/mongo/error/invalid_txt_record.rb +0 -2
  176. data/lib/mongo/error/invalid_update_document.rb +2 -5
  177. data/lib/mongo/error/invalid_uri.rb +1 -4
  178. data/lib/mongo/error/invalid_write_concern.rb +2 -5
  179. data/lib/mongo/error/kms_error.rb +0 -2
  180. data/lib/mongo/error/labelable.rb +0 -3
  181. data/lib/mongo/error/lint_error.rb +0 -2
  182. data/lib/mongo/error/max_bson_size.rb +8 -11
  183. data/lib/mongo/error/max_message_size.rb +2 -5
  184. data/lib/mongo/error/mismatched_domain.rb +0 -2
  185. data/lib/mongo/error/missing_connection.rb +0 -2
  186. data/lib/mongo/error/missing_file_chunk.rb +0 -3
  187. data/lib/mongo/error/missing_password.rb +0 -2
  188. data/lib/mongo/error/missing_resume_token.rb +1 -4
  189. data/lib/mongo/error/missing_scram_server_signature.rb +2 -4
  190. data/lib/mongo/error/missing_service_id.rb +0 -2
  191. data/lib/mongo/error/mongocryptd_spawn_error.rb +0 -2
  192. data/lib/mongo/error/multi_index_drop.rb +0 -3
  193. data/lib/mongo/error/need_primary_server.rb +0 -2
  194. data/lib/mongo/error/no_server_available.rb +3 -8
  195. data/lib/mongo/error/no_service_connection_available.rb +1 -3
  196. data/lib/mongo/error/no_srv_records.rb +0 -2
  197. data/lib/mongo/error/notable.rb +8 -16
  198. data/lib/mongo/error/operation_failure.rb +22 -35
  199. data/lib/mongo/error/parser.rb +33 -75
  200. data/lib/mongo/error/pool_cleared_error.rb +1 -3
  201. data/lib/mongo/error/pool_closed_error.rb +0 -3
  202. data/lib/mongo/error/pool_error.rb +0 -3
  203. data/lib/mongo/error/pool_paused_error.rb +0 -2
  204. data/lib/mongo/error/raise_original_error.rb +1 -3
  205. data/lib/mongo/error/read_write_retryable.rb +14 -17
  206. data/lib/mongo/error/sdam_error_detection.rb +3 -5
  207. data/lib/mongo/error/server_api_conflict.rb +0 -2
  208. data/lib/mongo/error/server_certificate_revoked.rb +0 -2
  209. data/lib/mongo/error/server_not_usable.rb +0 -2
  210. data/lib/mongo/error/session_ended.rb +1 -3
  211. data/lib/mongo/error/session_not_materialized.rb +1 -3
  212. data/lib/mongo/error/sessions_not_supported.rb +1 -4
  213. data/lib/mongo/error/snapshot_session_invalid_server_version.rb +1 -4
  214. data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +1 -4
  215. data/lib/mongo/error/socket_error.rb +0 -2
  216. data/lib/mongo/error/socket_timeout_error.rb +0 -2
  217. data/lib/mongo/error/transactions_not_supported.rb +3 -6
  218. data/lib/mongo/error/unchangeable_collection_option.rb +1 -4
  219. data/lib/mongo/error/unexpected_chunk_length.rb +0 -3
  220. data/lib/mongo/error/unexpected_response.rb +1 -4
  221. data/lib/mongo/error/unknown_payload_type.rb +0 -3
  222. data/lib/mongo/error/unmet_dependency.rb +0 -2
  223. data/lib/mongo/error/unsupported_array_filters.rb +3 -24
  224. data/lib/mongo/error/unsupported_collation.rb +3 -24
  225. data/lib/mongo/error/unsupported_features.rb +0 -2
  226. data/lib/mongo/error/unsupported_message_type.rb +0 -2
  227. data/lib/mongo/error/unsupported_option.rb +19 -21
  228. data/lib/mongo/error/write_retryable.rb +0 -2
  229. data/lib/mongo/error.rb +10 -24
  230. data/lib/mongo/event/base.rb +0 -2
  231. data/lib/mongo/event/listeners.rb +0 -3
  232. data/lib/mongo/event/publisher.rb +0 -3
  233. data/lib/mongo/event/subscriber.rb +0 -4
  234. data/lib/mongo/event.rb +4 -6
  235. data/lib/mongo/grid/file/chunk.rb +7 -10
  236. data/lib/mongo/grid/file/info.rb +20 -24
  237. data/lib/mongo/grid/file.rb +7 -8
  238. data/lib/mongo/grid/fs_bucket.rb +40 -48
  239. data/lib/mongo/grid/stream/read.rb +25 -35
  240. data/lib/mongo/grid/stream/write.rb +17 -22
  241. data/lib/mongo/grid/stream.rb +2 -4
  242. data/lib/mongo/grid.rb +0 -1
  243. data/lib/mongo/id.rb +0 -1
  244. data/lib/mongo/index/view.rb +68 -58
  245. data/lib/mongo/index.rb +7 -10
  246. data/lib/mongo/lint.rb +31 -37
  247. data/lib/mongo/loggable.rb +5 -8
  248. data/lib/mongo/logger.rb +1 -7
  249. data/lib/mongo/monitoring/cmap_log_subscriber.rb +0 -2
  250. data/lib/mongo/monitoring/command_log_subscriber.rb +25 -33
  251. data/lib/mongo/monitoring/event/cmap/base.rb +0 -2
  252. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -4
  253. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +0 -3
  254. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +1 -4
  255. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +2 -5
  256. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +1 -4
  257. data/lib/mongo/monitoring/event/cmap/connection_created.rb +1 -4
  258. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +1 -4
  259. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +0 -3
  260. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +1 -4
  261. data/lib/mongo/monitoring/event/cmap/pool_created.rb +1 -4
  262. data/lib/mongo/monitoring/event/cmap/pool_ready.rb +1 -4
  263. data/lib/mongo/monitoring/event/cmap.rb +0 -1
  264. data/lib/mongo/monitoring/event/command_failed.rb +5 -9
  265. data/lib/mongo/monitoring/event/command_started.rb +8 -12
  266. data/lib/mongo/monitoring/event/command_succeeded.rb +7 -15
  267. data/lib/mongo/monitoring/event/secure.rb +15 -20
  268. data/lib/mongo/monitoring/event/server_closed.rb +1 -4
  269. data/lib/mongo/monitoring/event/server_description_changed.rb +4 -8
  270. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +5 -10
  271. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +1 -4
  272. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +3 -8
  273. data/lib/mongo/monitoring/event/server_opening.rb +1 -4
  274. data/lib/mongo/monitoring/event/topology_changed.rb +2 -5
  275. data/lib/mongo/monitoring/event/topology_closed.rb +1 -4
  276. data/lib/mongo/monitoring/event/topology_opening.rb +1 -4
  277. data/lib/mongo/monitoring/event.rb +0 -1
  278. data/lib/mongo/monitoring/publishable.rb +20 -30
  279. data/lib/mongo/monitoring/sdam_log_subscriber.rb +0 -2
  280. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +0 -3
  281. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +0 -3
  282. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +0 -3
  283. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +5 -8
  284. data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +0 -3
  285. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +0 -3
  286. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +1 -3
  287. data/lib/mongo/monitoring.rb +38 -39
  288. data/lib/mongo/operation/aggregate/op_msg.rb +0 -2
  289. data/lib/mongo/operation/aggregate/result.rb +3 -6
  290. data/lib/mongo/operation/aggregate.rb +0 -2
  291. data/lib/mongo/operation/collections_info/result.rb +0 -3
  292. data/lib/mongo/operation/collections_info.rb +0 -2
  293. data/lib/mongo/operation/command/op_msg.rb +1 -4
  294. data/lib/mongo/operation/command.rb +0 -2
  295. data/lib/mongo/operation/context.rb +13 -16
  296. data/lib/mongo/operation/count/op_msg.rb +2 -4
  297. data/lib/mongo/operation/count.rb +0 -2
  298. data/lib/mongo/operation/create/op_msg.rb +2 -5
  299. data/lib/mongo/operation/create.rb +4 -2
  300. data/lib/mongo/operation/create_index/op_msg.rb +3 -7
  301. data/lib/mongo/operation/create_index.rb +0 -2
  302. data/lib/mongo/operation/create_user/op_msg.rb +2 -4
  303. data/lib/mongo/operation/create_user.rb +0 -2
  304. data/lib/mongo/operation/delete/bulk_result.rb +2 -3
  305. data/lib/mongo/operation/delete/op_msg.rb +3 -10
  306. data/lib/mongo/operation/delete/result.rb +0 -3
  307. data/lib/mongo/operation/delete.rb +1 -5
  308. data/lib/mongo/operation/distinct/op_msg.rb +2 -5
  309. data/lib/mongo/operation/distinct.rb +0 -2
  310. data/lib/mongo/operation/drop/op_msg.rb +0 -2
  311. data/lib/mongo/operation/drop.rb +0 -2
  312. data/lib/mongo/operation/drop_database/op_msg.rb +0 -2
  313. data/lib/mongo/operation/drop_database.rb +0 -2
  314. data/lib/mongo/operation/drop_index/op_msg.rb +4 -6
  315. data/lib/mongo/operation/drop_index.rb +0 -2
  316. data/lib/mongo/operation/explain/op_msg.rb +0 -2
  317. data/lib/mongo/operation/explain/result.rb +0 -3
  318. data/lib/mongo/operation/explain.rb +0 -2
  319. data/lib/mongo/operation/find/builder/command.rb +4 -12
  320. data/lib/mongo/operation/find/builder/flags.rb +9 -15
  321. data/lib/mongo/operation/find/builder/modifiers.rb +1 -4
  322. data/lib/mongo/operation/find/builder.rb +0 -1
  323. data/lib/mongo/operation/find/op_msg.rb +4 -12
  324. data/lib/mongo/operation/find/result.rb +0 -3
  325. data/lib/mongo/operation/find.rb +0 -2
  326. data/lib/mongo/operation/get_more/command_builder.rb +1 -6
  327. data/lib/mongo/operation/get_more/op_msg.rb +10 -4
  328. data/lib/mongo/operation/get_more/result.rb +0 -3
  329. data/lib/mongo/operation/get_more.rb +0 -2
  330. data/lib/mongo/operation/indexes/op_msg.rb +0 -2
  331. data/lib/mongo/operation/indexes/result.rb +1 -5
  332. data/lib/mongo/operation/indexes.rb +0 -2
  333. data/lib/mongo/operation/insert/bulk_result.rb +2 -6
  334. data/lib/mongo/operation/insert/op_msg.rb +7 -6
  335. data/lib/mongo/operation/insert/result.rb +0 -3
  336. data/lib/mongo/operation/insert.rb +2 -5
  337. data/lib/mongo/operation/kill_cursors/command_builder.rb +0 -3
  338. data/lib/mongo/operation/kill_cursors/op_msg.rb +1 -3
  339. data/lib/mongo/operation/kill_cursors.rb +0 -2
  340. data/lib/mongo/operation/list_collections/op_msg.rb +4 -6
  341. data/lib/mongo/operation/list_collections/result.rb +1 -4
  342. data/lib/mongo/operation/list_collections.rb +0 -2
  343. data/lib/mongo/operation/map_reduce/op_msg.rb +0 -2
  344. data/lib/mongo/operation/map_reduce/result.rb +3 -6
  345. data/lib/mongo/operation/map_reduce.rb +0 -2
  346. data/lib/mongo/operation/op_msg_base.rb +0 -1
  347. data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -5
  348. data/lib/mongo/operation/parallel_scan/result.rb +2 -5
  349. data/lib/mongo/operation/parallel_scan.rb +0 -2
  350. data/lib/mongo/operation/remove_user/op_msg.rb +2 -4
  351. data/lib/mongo/operation/remove_user.rb +0 -2
  352. data/lib/mongo/operation/result.rb +38 -48
  353. data/lib/mongo/operation/shared/bypass_document_validation.rb +3 -7
  354. data/lib/mongo/operation/shared/causal_consistency_supported.rb +0 -3
  355. data/lib/mongo/operation/shared/executable.rb +29 -31
  356. data/lib/mongo/operation/shared/executable_no_validate.rb +0 -3
  357. data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -2
  358. data/lib/mongo/operation/shared/idable.rb +3 -6
  359. data/lib/mongo/operation/shared/limited.rb +0 -3
  360. data/lib/mongo/operation/shared/object_id_generator.rb +0 -3
  361. data/lib/mongo/operation/shared/op_msg_executable.rb +0 -2
  362. data/lib/mongo/operation/shared/polymorphic_lookup.rb +0 -2
  363. data/lib/mongo/operation/shared/polymorphic_result.rb +2 -4
  364. data/lib/mongo/operation/shared/read_preference_supported.rb +10 -15
  365. data/lib/mongo/operation/shared/response_handling.rb +13 -26
  366. data/lib/mongo/operation/shared/result/aggregatable.rb +12 -13
  367. data/lib/mongo/operation/shared/sessions_supported.rb +87 -99
  368. data/lib/mongo/operation/shared/specifiable.rb +37 -59
  369. data/lib/mongo/operation/shared/write.rb +12 -17
  370. data/lib/mongo/operation/shared/write_concern_supported.rb +4 -7
  371. data/lib/mongo/operation/update/bulk_result.rb +13 -17
  372. data/lib/mongo/operation/update/op_msg.rb +2 -5
  373. data/lib/mongo/operation/update/result.rb +5 -5
  374. data/lib/mongo/operation/update.rb +1 -5
  375. data/lib/mongo/operation/update_user/op_msg.rb +2 -4
  376. data/lib/mongo/operation/update_user.rb +0 -2
  377. data/lib/mongo/operation/users_info/op_msg.rb +2 -4
  378. data/lib/mongo/operation/users_info/result.rb +1 -4
  379. data/lib/mongo/operation/users_info.rb +0 -2
  380. data/lib/mongo/operation/write_command/op_msg.rb +2 -10
  381. data/lib/mongo/operation/write_command.rb +0 -2
  382. data/lib/mongo/operation.rb +9 -14
  383. data/lib/mongo/options/mapper.rb +8 -15
  384. data/lib/mongo/options/redacted.rb +7 -9
  385. data/lib/mongo/options.rb +0 -1
  386. data/lib/mongo/protocol/bit_vector.rb +3 -5
  387. data/lib/mongo/protocol/caching_hash.rb +2 -7
  388. data/lib/mongo/protocol/compressed.rb +5 -10
  389. data/lib/mongo/protocol/get_more.rb +2 -8
  390. data/lib/mongo/protocol/kill_cursors.rb +2 -8
  391. data/lib/mongo/protocol/message.rb +103 -105
  392. data/lib/mongo/protocol/msg.rb +48 -63
  393. data/lib/mongo/protocol/query.rb +32 -41
  394. data/lib/mongo/protocol/registry.rb +2 -5
  395. data/lib/mongo/protocol/reply.rb +10 -16
  396. data/lib/mongo/protocol/serializers.rb +41 -59
  397. data/lib/mongo/protocol.rb +0 -1
  398. data/lib/mongo/query_cache.rb +7 -15
  399. data/lib/mongo/retryable/backpressure.rb +31 -0
  400. data/lib/mongo/retryable/base_worker.rb +39 -13
  401. data/lib/mongo/retryable/read_worker.rb +77 -21
  402. data/lib/mongo/retryable/retry_policy.rb +59 -0
  403. data/lib/mongo/retryable/write_worker.rb +155 -56
  404. data/lib/mongo/retryable.rb +70 -9
  405. data/lib/mongo/search_index/view.rb +30 -10
  406. data/lib/mongo/semaphore.rb +0 -1
  407. data/lib/mongo/server/app_metadata/environment.rb +3 -3
  408. data/lib/mongo/server/app_metadata/platform.rb +17 -4
  409. data/lib/mongo/server/app_metadata.rb +4 -5
  410. data/lib/mongo/server/connection.rb +79 -61
  411. data/lib/mongo/server/connection_base.rb +43 -53
  412. data/lib/mongo/server/connection_common.rb +41 -64
  413. data/lib/mongo/server/connection_pool/generation_manager.rb +6 -11
  414. data/lib/mongo/server/connection_pool/populator.rb +1 -4
  415. data/lib/mongo/server/connection_pool.rb +195 -167
  416. data/lib/mongo/server/description/features.rb +51 -59
  417. data/lib/mongo/server/description/load_balancer.rb +0 -2
  418. data/lib/mongo/server/description.rb +117 -138
  419. data/lib/mongo/server/monitor/app_metadata.rb +3 -4
  420. data/lib/mongo/server/monitor/connection.rb +28 -35
  421. data/lib/mongo/server/monitor.rb +65 -60
  422. data/lib/mongo/server/pending_connection.rb +70 -71
  423. data/lib/mongo/server/push_monitor/connection.rb +0 -3
  424. data/lib/mongo/server/push_monitor.rb +21 -29
  425. data/lib/mongo/server/round_trip_time_calculator.rb +11 -17
  426. data/lib/mongo/server.rb +62 -94
  427. data/lib/mongo/server_selector/base.rb +133 -157
  428. data/lib/mongo/server_selector/nearest.rb +2 -5
  429. data/lib/mongo/server_selector/primary.rb +1 -5
  430. data/lib/mongo/server_selector/primary_preferred.rb +2 -6
  431. data/lib/mongo/server_selector/secondary.rb +2 -6
  432. data/lib/mongo/server_selector/secondary_preferred.rb +1 -5
  433. data/lib/mongo/server_selector.rb +3 -4
  434. data/lib/mongo/session/server_session.rb +6 -7
  435. data/lib/mongo/session/session_pool.rb +20 -34
  436. data/lib/mongo/session.rb +334 -199
  437. data/lib/mongo/socket/ocsp_cache.rb +8 -13
  438. data/lib/mongo/socket/ocsp_verifier.rb +69 -70
  439. data/lib/mongo/socket/ssl.rb +44 -43
  440. data/lib/mongo/socket/tcp.rb +5 -8
  441. data/lib/mongo/socket/unix.rb +0 -4
  442. data/lib/mongo/socket.rb +80 -102
  443. data/lib/mongo/srv/monitor.rb +10 -11
  444. data/lib/mongo/srv/resolver.rb +15 -24
  445. data/lib/mongo/srv/result.rb +25 -21
  446. data/lib/mongo/srv.rb +0 -1
  447. data/lib/mongo/timeout.rb +4 -11
  448. data/lib/mongo/topology_version.rb +8 -13
  449. data/lib/mongo/tracing/open_telemetry/command_tracer.rb +320 -0
  450. data/lib/mongo/tracing/open_telemetry/operation_tracer.rb +227 -0
  451. data/lib/mongo/tracing/open_telemetry/tracer.rb +236 -0
  452. data/lib/mongo/{error/server_api_not_supported.rb → tracing/open_telemetry.rb} +10 -10
  453. data/lib/mongo/tracing.rb +42 -0
  454. data/lib/mongo/uri/options_mapper.rb +135 -126
  455. data/lib/mongo/uri/srv_protocol.rb +34 -42
  456. data/lib/mongo/uri.rb +95 -139
  457. data/lib/mongo/utils.rb +5 -12
  458. data/lib/mongo/version.rb +1 -1
  459. data/lib/mongo/write_concern/acknowledged.rb +0 -2
  460. data/lib/mongo/write_concern/base.rb +6 -6
  461. data/lib/mongo/write_concern/unacknowledged.rb +0 -2
  462. data/lib/mongo/write_concern.rb +14 -15
  463. data/lib/mongo.rb +4 -3
  464. data/mongo.gemspec +17 -17
  465. metadata +11 -5
  466. data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +0 -32
  467. 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-2020 MongoDB Inc.
5
4
  #
@@ -27,12 +26,14 @@ module Mongo
27
26
  #
28
27
  # @api private
29
28
  class ClusterTime < BSON::Document
29
+ include Comparable
30
+
30
31
  def initialize(elements = nil)
31
32
  super
32
33
 
33
- if Lint.enabled? && !self['clusterTime']
34
- raise ArgumentError, 'Creating a cluster time without clusterTime field'
35
- end
34
+ return unless Lint.enabled? && !self['clusterTime']
35
+
36
+ raise ArgumentError, 'Creating a cluster time without clusterTime field'
36
37
  end
37
38
 
38
39
  # Advances the cluster time in the receiver to the cluster time in +other+.
@@ -44,8 +45,7 @@ module Mongo
44
45
  # Return value is nil or a ClusterTime instance.
45
46
  def advance(other)
46
47
  if self['clusterTime'] && other['clusterTime'] &&
47
- other['clusterTime'] > self['clusterTime']
48
- then
48
+ other['clusterTime'] > self['clusterTime']
49
49
  ClusterTime[other]
50
50
  else
51
51
  self
@@ -58,32 +58,16 @@ module Mongo
58
58
  self['clusterTime'] <=> other['clusterTime']
59
59
  elsif !self['clusterTime']
60
60
  raise ArgumentError, "Cannot compare cluster times when receiver is missing clusterTime key: #{inspect}"
61
- else other['clusterTime']
61
+ else
62
+ other['clusterTime']
62
63
  raise ArgumentError, "Cannot compare cluster times when other is missing clusterTime key: #{other.inspect}"
63
64
  end
64
65
  end
65
66
 
66
- # Older Rubies do not implement other logical operators through <=>.
67
- # TODO revise whether these methods are needed when
68
- # https://jira.mongodb.org/browse/RUBY-1622 is implemented.
69
- def >=(other)
70
- (self <=> other) != -1
71
- end
72
- def >(other)
73
- (self <=> other) == 1
74
- end
75
- def <=(other)
76
- (self <=> other) != 1
77
- end
78
- def <(other)
79
- (self <=> other) == -1
80
- end
81
-
82
67
  # Compares two ClusterTime instances by comparing their timestamps.
83
68
  def ==(other)
84
69
  if self['clusterTime'] && other['clusterTime'] &&
85
- self['clusterTime'] == other['clusterTime']
86
- then
70
+ self['clusterTime'] == other['clusterTime']
87
71
  true
88
72
  else
89
73
  false
@@ -110,7 +94,6 @@ module Mongo
110
94
  # the methods are defined on this module and not directly on the
111
95
  # including classes is not part of the public API.
112
96
  module Consumer
113
-
114
97
  # The cluster time tracked by the object including this module.
115
98
  #
116
99
  # @return [ nil | ClusterTime ] The cluster time.
@@ -131,11 +114,11 @@ module Mongo
131
114
  #
132
115
  # @since 2.5.0
133
116
  def advance_cluster_time(new_cluster_time)
134
- if @cluster_time
135
- @cluster_time = @cluster_time.advance(new_cluster_time)
136
- else
137
- @cluster_time = ClusterTime[new_cluster_time]
138
- end
117
+ @cluster_time = if @cluster_time
118
+ @cluster_time.advance(new_cluster_time)
119
+ else
120
+ ClusterTime[new_cluster_time]
121
+ end
139
122
  end
140
123
  end
141
124
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2014-2022 MongoDB Inc.
5
4
  #
@@ -21,7 +20,7 @@ module Mongo
21
20
  #
22
21
  # @api private
23
22
  module Helpers
24
- # Executes drop operation and and ignores NamespaceNotFound error.
23
+ # Executes drop operation and ignores NamespaceNotFound error.
25
24
  #
26
25
  # @param [ Operation::Drop ] operation Drop operation to be executed.
27
26
  # @param [ Session ] session Session to be use for execution.
@@ -30,13 +29,11 @@ module Mongo
30
29
  # @return [ Result ] The result of the execution.
31
30
  def do_drop(operation, session, context)
32
31
  operation.execute(next_primary(nil, session), context: context)
33
- rescue Error::OperationFailure::Family => ex
32
+ rescue Error::OperationFailure::Family => e
34
33
  # NamespaceNotFound
35
- if ex.code == 26 || ex.code.nil? && ex.message =~ /ns not found/
36
- false
37
- else
38
- raise
39
- end
34
+ raise unless e.code == 26 || (e.code.nil? && e.message =~ /ns not found/)
35
+
36
+ false
40
37
  end
41
38
  end
42
39
  end
@@ -88,7 +88,7 @@ module Mongo
88
88
  @view.send(:server_selector)
89
89
  end
90
90
 
91
- def aggregate_spec(session, read_preference)
91
+ def aggregate_spec(session, read_preference = nil)
92
92
  Builder::Aggregation.new(
93
93
  pipeline,
94
94
  view,
@@ -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
  #
@@ -20,16 +19,18 @@ require 'mongo/collection/view/aggregation/behavior'
20
19
  module Mongo
21
20
  class Collection
22
21
  class View
23
-
24
22
  # Provides behavior around an aggregation pipeline on a collection view.
25
23
  #
26
24
  # @since 2.0.0
27
25
  class Aggregation
26
+ extend Forwardable
28
27
  include Behavior
29
28
 
30
29
  # @return [ Array<Hash> ] pipeline The aggregation pipeline.
31
30
  attr_reader :pipeline
32
31
 
32
+ def_delegators :view, :tracer
33
+
33
34
  # Initialize the aggregation for the provided collection view, pipeline
34
35
  # and options.
35
36
  #
@@ -68,9 +69,7 @@ module Mongo
68
69
  def initialize(view, pipeline, options = {})
69
70
  perform_setup(view, options) do
70
71
  @pipeline = pipeline.dup
71
- unless Mongo.broken_view_aggregate || view.filter.empty?
72
- @pipeline.unshift(:$match => view.filter)
73
- end
72
+ @pipeline.unshift(:$match => view.filter) unless Mongo.broken_view_aggregate || view.filter.empty?
74
73
  end
75
74
  end
76
75
 
@@ -80,7 +79,7 @@ module Mongo
80
79
  Aggregation.new(view, pipeline, options)
81
80
  end
82
81
 
83
- def initial_query_op(session, read_preference)
82
+ def initial_query_op(session, read_preference = nil)
84
83
  Operation::Aggregate.new(aggregate_spec(session, read_preference))
85
84
  end
86
85
 
@@ -101,23 +100,22 @@ module Mongo
101
100
  def effective_read_preference(connection)
102
101
  return unless view.read_preference
103
102
  return view.read_preference unless write?
104
- return view.read_preference unless [:secondary, :secondary_preferred].include?(view.read_preference[:mode])
103
+ return view.read_preference unless %i[secondary secondary_preferred].include?(view.read_preference[:mode])
105
104
 
106
- primary_read_preference = {mode: :primary}
105
+ primary_read_preference = { mode: :primary }
107
106
  description = connection.description
108
107
  if description.primary?
109
- log_warn("Routing the Aggregation operation to the primary server")
108
+ log_warn('Routing the Aggregation operation to the primary server')
110
109
  primary_read_preference
111
110
  elsif description.mongos? && !description.features.merge_out_on_secondary_enabled?
112
- log_warn("Routing the Aggregation operation to the primary server")
111
+ log_warn('Routing the Aggregation operation to the primary server')
113
112
  primary_read_preference
114
113
  else
115
114
  view.read_preference
116
115
  end
117
-
118
116
  end
119
117
 
120
- def send_initial_query(server, context)
118
+ def send_initial_query(server, context, operation: nil)
121
119
  if server.load_balancer?
122
120
  # Connection will be checked in when cursor is drained.
123
121
  connection = server.pool.check_out(context: context)
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2015-2020 MongoDB Inc.
5
4
  #
@@ -19,7 +18,6 @@ module Mongo
19
18
  class Collection
20
19
  class View
21
20
  module Builder
22
-
23
21
  # Builds an aggregation command specification from the view and options.
24
22
  #
25
23
  # @since 2.2.0
@@ -40,7 +38,7 @@ module Mongo
40
38
  # This is intentional; max_await_time_ms is an alias for maxTimeMS
41
39
  # used on getMore commands for change streams.
42
40
  max_await_time_ms: 'maxTimeMS',
43
- max_time_ms: 'maxTimeMS',
41
+ max_time_ms: 'maxTimeMS'
44
42
  ).freeze
45
43
 
46
44
  def_delegators :@view, :collection, :database, :read, :write_concern
@@ -83,9 +81,7 @@ module Mongo
83
81
  session: @options[:session],
84
82
  collation: @options[:collation],
85
83
  }
86
- if write?
87
- spec.update(write_concern: write_concern)
88
- end
84
+ spec.update(write_concern: write_concern) if write?
89
85
  spec
90
86
  end
91
87
 
@@ -94,7 +90,7 @@ module Mongo
94
90
  def write?
95
91
  pipeline.any? do |operator|
96
92
  operator[:$out] || operator['$out'] ||
97
- operator[:$merge] || operator['$merge']
93
+ operator[:$merge] || operator['$merge']
98
94
  end
99
95
  end
100
96
 
@@ -111,7 +107,8 @@ module Mongo
111
107
  command[:pipeline] = pipeline
112
108
  if read_concern = view.read_concern
113
109
  command[:readConcern] = Options::Mapper.transform_values_to_strings(
114
- read_concern)
110
+ read_concern
111
+ )
115
112
  end
116
113
  command[:cursor] = batch_size_doc
117
114
  command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
@@ -123,7 +120,7 @@ module Mongo
123
120
  if value == 0 && write?
124
121
  {}
125
122
  elsif value
126
- { :batchSize => value }
123
+ { batchSize: value }
127
124
  else
128
125
  {}
129
126
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2015-2020 MongoDB Inc.
5
4
  #
@@ -19,7 +18,6 @@ module Mongo
19
18
  class Collection
20
19
  class View
21
20
  module Builder
22
-
23
21
  # Builds a map/reduce specification from the view and options.
24
22
  #
25
23
  # @since 2.2.0
@@ -36,7 +34,7 @@ module Mongo
36
34
  scope: 'scope',
37
35
  verbose: 'verbose',
38
36
  bypass_document_validation: 'bypassDocumentValidation',
39
- collation: 'collation',
37
+ collation: 'collation'
40
38
  ).freeze
41
39
 
42
40
  def_delegators :@view, :collection, :database, :filter, :read, :write_concern
@@ -94,24 +92,25 @@ module Mongo
94
92
  private
95
93
 
96
94
  def write?(spec)
97
- if out = spec[:selector][:out]
98
- out.is_a?(String) ||
99
- (out.respond_to?(:keys) && out.keys.first.to_s.downcase != View::MapReduce::INLINE)
100
- end
95
+ return unless out = spec[:selector][:out]
96
+
97
+ out.is_a?(String) ||
98
+ (out.respond_to?(:keys) && out.keys.first.to_s.downcase != View::MapReduce::INLINE)
101
99
  end
102
100
 
103
101
  def map_reduce_command
104
102
  command = BSON::Document.new(
105
- :mapReduce => collection.name,
106
- :map => map,
107
- :reduce => reduce,
108
- :query => filter,
109
- :out => { inline: 1 },
103
+ mapReduce: collection.name,
104
+ map: map,
105
+ reduce: reduce,
106
+ query: filter,
107
+ out: { inline: 1 }
110
108
  )
111
109
  # Shouldn't this use self.read ?
112
110
  if collection.read_concern
113
111
  command[:readConcern] = Options::Mapper.transform_values_to_strings(
114
- collection.read_concern)
112
+ collection.read_concern
113
+ )
115
114
  end
116
115
  command.update(view_options)
117
116
  command.update(options.slice(:collation))
@@ -121,16 +120,18 @@ module Mongo
121
120
  # Ideally it should be removed here, however due to Mongoid 7
122
121
  # using this method and requiring :read to be returned from it,
123
122
  # we cannot do this just yet - see RUBY-2932.
124
- #command.delete(:read)
123
+ # command.delete(:read)
125
124
 
126
125
  command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
127
126
  command
128
127
  end
129
128
 
130
129
  def view_options
131
- @view_options ||= (opts = view.options.dup
132
- opts.delete(:session)
133
- opts)
130
+ @view_options ||= begin
131
+ opts = view.options.dup
132
+ opts.delete(:session)
133
+ opts
134
+ end
134
135
  end
135
136
  end
136
137
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2015-2020 MongoDB Inc.
5
4
  #
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2017-2020 MongoDB Inc.
5
4
  #
@@ -19,22 +18,18 @@ module Mongo
19
18
  class Collection
20
19
  class View
21
20
  class ChangeStream < Aggregation
22
-
23
21
  # Behavior around resuming a change stream.
24
22
  #
25
23
  # @since 2.5.0
26
24
  module Retryable
27
-
28
25
  private
29
26
 
30
27
  def read_with_one_retry
31
28
  yield
32
29
  rescue Mongo::Error => e
33
- if e.change_stream_resumable?
34
- yield
35
- else
36
- raise(e)
37
- end
30
+ raise(e) unless e.change_stream_resumable?
31
+
32
+ yield
38
33
  end
39
34
  end
40
35
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2017-2020 MongoDB Inc.
5
4
  #
@@ -21,20 +20,11 @@ require 'mongo/collection/view/change_stream/retryable'
21
20
  module Mongo
22
21
  class Collection
23
22
  class View
24
-
25
23
  # Provides behavior around a `$changeStream` pipeline stage in the
26
24
  # aggregation framework. Specifying this stage allows users to request
27
25
  # that notifications are sent for all changes to a particular collection
28
26
  # or database.
29
27
  #
30
- # @note Only available in server versions 3.6 and higher.
31
- # @note ChangeStreams do not work properly with JRuby because of the
32
- # issue documented here: https://github.com/jruby/jruby/issues/4212.
33
- # Namely, JRuby eagerly evaluates #next on an Enumerator in a background
34
- # green thread, therefore calling #next on the change stream will cause
35
- # getMores to be called in a loop in the background.
36
- #
37
- #
38
28
  # @since 2.5.0
39
29
  class ChangeStream
40
30
  include Aggregation::Behavior
@@ -43,7 +33,7 @@ module Mongo
43
33
  # @return [ String ] The fullDocument option default value.
44
34
  #
45
35
  # @since 2.5.0
46
- FULL_DOCUMENT_DEFAULT = 'default'.freeze
36
+ FULL_DOCUMENT_DEFAULT = 'default'
47
37
 
48
38
  # @return [ Symbol ] Used to indicate that the change stream should listen for changes on
49
39
  # the entire database rather than just the collection.
@@ -66,6 +56,16 @@ module Mongo
66
56
  # @api private
67
57
  attr_reader :cursor
68
58
 
59
+ # Refreshes the CSOT timeout for the next iteration. Delegates to the
60
+ # underlying cursor's refresh_timeout! method so that each call to
61
+ # try_next starts with a fresh timeout deadline, as required by the
62
+ # CSOT spec for tailable awaitData cursors.
63
+ #
64
+ # @api private
65
+ def refresh_timeout!
66
+ @cursor&.refresh_timeout!
67
+ end
68
+
69
69
  # Initialize the change stream for the provided collection view, pipeline
70
70
  # and options.
71
71
  #
@@ -114,7 +114,7 @@ module Mongo
114
114
  # @option options [ BSON::Timestamp ] :start_at_operation_time Only
115
115
  # return changes that occurred at or after the specified timestamp. Any
116
116
  # command run against the server will return a cluster time that can
117
- # be used here. Only recognized by server versions 4.0+.
117
+ # be used here.
118
118
  # @option options [ Bson::Document, Hash ] :start_after Similar to :resume_after, this
119
119
  # option takes a resume token and starts a new change stream returning the first
120
120
  # notification after the token. This will allow users to watch collections that have been
@@ -168,12 +168,13 @@ module Mongo
168
168
  # @yieldparam [ BSON::Document ] Each change stream document.
169
169
  def each
170
170
  raise StopIteration.new if closed?
171
+
171
172
  loop do
172
173
  document = try_next
173
174
  yield document if document
174
175
  end
175
176
  rescue StopIteration
176
- return self
177
+ self
177
178
  end
178
179
 
179
180
  # Return one document from the change stream, if one is available.
@@ -218,9 +219,8 @@ module Mongo
218
219
 
219
220
  # We need to verify each doc has an _id, so we
220
221
  # have a resume token to work with
221
- if doc && doc['_id'].nil?
222
- raise Error::MissingResumeToken
223
- end
222
+ raise Error::MissingResumeToken if doc && doc['_id'].nil?
223
+
224
224
  doc
225
225
  end
226
226
 
@@ -252,14 +252,14 @@ module Mongo
252
252
  #
253
253
  # @since 2.5.0
254
254
  def close(opts = {})
255
- unless closed?
256
- begin
257
- @cursor.close(opts)
258
- rescue Error::OperationFailure::Family, Error::SocketError, Error::SocketTimeoutError, Error::MissingConnection
259
- # ignore
260
- end
261
- @cursor = nil
255
+ return if closed?
256
+
257
+ begin
258
+ @cursor.close(opts)
259
+ rescue Error::OperationFailure::Family, Error::SocketError, Error::SocketTimeoutError, Error::MissingConnection
260
+ # ignore
262
261
  end
262
+ @cursor = nil
263
263
  end
264
264
 
265
265
  # Is the change stream closed?
@@ -340,61 +340,66 @@ module Mongo
340
340
  def create_cursor!(timeout_ms = nil)
341
341
  # clear the cache because we may get a newer or an older server
342
342
  # (rolling upgrades)
343
- @start_at_operation_time_supported = nil
344
-
345
343
  session = client.get_session(@options)
346
- context = Operation::Context.new(client: client, session: session, view: self, operation_timeouts: timeout_ms ? { operation_timeout_ms: timeout_ms } : operation_timeouts)
344
+ context = Operation::Context.new(client: client, session: session, view: self,
345
+ operation_timeouts: timeout_ms ? { operation_timeout_ms: timeout_ms } : operation_timeouts)
347
346
 
348
347
  start_at_operation_time = nil
349
- start_at_operation_time_supported = nil
350
348
 
351
349
  @cursor = read_with_retry_cursor(session, server_selector, self, context: context) do |server|
352
- server.with_connection do |connection|
353
- start_at_operation_time_supported = connection.description.server_version_gte?('4.0')
354
-
350
+ if server.load_balancer?
351
+ # In load balanced topology, manually check out a connection
352
+ # so it remains checked out and pinned to the cursor.
353
+ connection = server.pool.check_out(context: context)
355
354
  result = send_initial_query(connection, context)
356
355
 
357
- if doc = result.replies.first && result.replies.first.documents.first
358
- start_at_operation_time = doc['operationTime']
359
- else
360
- # The above may set @start_at_operation_time to nil
361
- # if it was not in the document for some reason,
362
- # for consistency set it to nil here as well.
363
- # NB: since this block may be executed more than once, each
364
- # execution must write to start_at_operation_time either way.
365
- start_at_operation_time = nil
366
- end
356
+ start_at_operation_time = if doc = result.replies.first && result.replies.first.documents.first
357
+ doc['operationTime']
358
+ else
359
+ nil
360
+ end
367
361
  result
362
+ else
363
+ server.with_connection do |connection|
364
+ result = send_initial_query(connection, context)
365
+
366
+ start_at_operation_time = if doc = result.replies.first && result.replies.first.documents.first
367
+ doc['operationTime']
368
+ else
369
+ # The above may set @start_at_operation_time to nil
370
+ # if it was not in the document for some reason,
371
+ # for consistency set it to nil here as well.
372
+ # NB: since this block may be executed more than once, each
373
+ # execution must write to start_at_operation_time either way.
374
+ nil
375
+ end
376
+ result
377
+ end
368
378
  end
369
379
  end
370
380
 
371
381
  @start_at_operation_time = start_at_operation_time
372
- @start_at_operation_time_supported = start_at_operation_time_supported
373
382
  end
374
383
 
375
384
  def pipeline
376
- [{ '$changeStream' => change_doc }] + @change_stream_filters
385
+ [ { '$changeStream' => change_doc } ] + @change_stream_filters
377
386
  end
378
387
 
379
388
  def aggregate_spec(session, read_preference)
380
- super(session, read_preference).tap do |spec|
389
+ super.tap do |spec|
381
390
  spec[:selector][:aggregate] = 1 unless for_collection?
382
391
  end
383
392
  end
384
393
 
385
394
  def change_doc
386
395
  {}.tap do |doc|
387
- if @options[:full_document]
388
- doc[:fullDocument] = @options[:full_document]
389
- end
396
+ doc[:fullDocument] = @options[:full_document] if @options[:full_document]
390
397
 
391
398
  if @options[:full_document_before_change]
392
399
  doc[:fullDocumentBeforeChange] = @options[:full_document_before_change]
393
400
  end
394
401
 
395
- if @options.key?(:show_expanded_events)
396
- doc[:showExpandedEvents] = @options[:show_expanded_events]
397
- end
402
+ doc[:showExpandedEvents] = @options[:show_expanded_events] if @options.key?(:show_expanded_events)
398
403
 
399
404
  if resuming?
400
405
  # We have a resume token once we retrieved any documents.
@@ -405,12 +410,7 @@ module Mongo
405
410
  # Spec says we need to remove both startAtOperationTime and startAfter if
406
411
  # either was passed in by user, thus we won't forward them
407
412
  doc[:resumeAfter] = resume_token
408
- elsif @start_at_operation_time_supported && @start_at_operation_time
409
- # It is crucial to check @start_at_operation_time_supported
410
- # here - we may have switched to an older server that
411
- # does not support operation times and therefore shouldn't
412
- # try to send one to it!
413
- #
413
+ elsif @start_at_operation_time
414
414
  # @start_at_operation_time is already a BSON::Timestamp
415
415
  doc[:startAtOperationTime] = @start_at_operation_time
416
416
  else
@@ -426,7 +426,8 @@ module Mongo
426
426
 
427
427
  if options[:start_at_operation_time]
428
428
  doc[:startAtOperationTime] = time_to_bson_timestamp(
429
- options[:start_at_operation_time])
429
+ options[:start_at_operation_time]
430
+ )
430
431
  end
431
432
  end
432
433
 
@@ -438,14 +439,14 @@ module Mongo
438
439
  initial_query_op(context.session, view.read_preference)
439
440
  .execute_with_connection(
440
441
  connection,
441
- context: context,
442
+ context: context
442
443
  )
443
444
  end
444
445
 
445
446
  def time_to_bson_timestamp(time)
446
447
  if time.is_a?(Time)
447
448
  seconds = time.to_f
448
- BSON::Timestamp.new(seconds.to_i, ((seconds - seconds.to_i) * 1000000).to_i)
449
+ BSON::Timestamp.new(seconds.to_i, ((seconds - seconds.to_i) * 1_000_000).to_i)
449
450
  elsif time.is_a?(BSON::Timestamp)
450
451
  time
451
452
  else