mongo 2.18.2 → 2.19.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 (1133) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +12 -2
  4. data/Rakefile +4 -3
  5. data/bin/mongo_console +2 -0
  6. data/lib/mongo/active_support.rb +1 -1
  7. data/lib/mongo/address/ipv4.rb +1 -1
  8. data/lib/mongo/address/ipv6.rb +1 -1
  9. data/lib/mongo/address/unix.rb +1 -1
  10. data/lib/mongo/address/validator.rb +1 -1
  11. data/lib/mongo/address.rb +1 -1
  12. data/lib/mongo/auth/aws/conversation.rb +1 -5
  13. data/lib/mongo/auth/aws/credentials.rb +38 -0
  14. data/lib/mongo/auth/aws/credentials_cache.rb +75 -0
  15. data/lib/mongo/auth/aws/credentials_retriever.rb +172 -37
  16. data/lib/mongo/auth/aws/request.rb +1 -2
  17. data/lib/mongo/auth/aws.rb +6 -6
  18. data/lib/mongo/auth/base.rb +1 -1
  19. data/lib/mongo/auth/conversation_base.rb +1 -1
  20. data/lib/mongo/auth/cr/conversation.rb +1 -1
  21. data/lib/mongo/auth/cr.rb +1 -1
  22. data/lib/mongo/auth/credential_cache.rb +1 -1
  23. data/lib/mongo/auth/gssapi/conversation.rb +1 -1
  24. data/lib/mongo/auth/gssapi.rb +1 -1
  25. data/lib/mongo/auth/ldap/conversation.rb +1 -1
  26. data/lib/mongo/auth/ldap.rb +1 -1
  27. data/lib/mongo/auth/roles.rb +17 -17
  28. data/lib/mongo/auth/sasl_conversation_base.rb +1 -1
  29. data/lib/mongo/auth/scram/conversation.rb +1 -1
  30. data/lib/mongo/auth/scram.rb +1 -1
  31. data/lib/mongo/auth/scram256/conversation.rb +1 -1
  32. data/lib/mongo/auth/scram256.rb +1 -1
  33. data/lib/mongo/auth/scram_conversation_base.rb +1 -1
  34. data/lib/mongo/auth/stringprep/profiles/sasl.rb +1 -1
  35. data/lib/mongo/auth/stringprep/tables.rb +1 -1
  36. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +1 -1
  37. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +2 -1
  38. data/lib/mongo/auth/stringprep.rb +1 -1
  39. data/lib/mongo/auth/user/view.rb +1 -1
  40. data/lib/mongo/auth/user.rb +1 -1
  41. data/lib/mongo/auth/x509/conversation.rb +1 -1
  42. data/lib/mongo/auth/x509.rb +1 -1
  43. data/lib/mongo/auth.rb +1 -1
  44. data/lib/mongo/background_thread.rb +1 -1
  45. data/lib/mongo/bson.rb +1 -1
  46. data/lib/mongo/bulk_write/combineable.rb +1 -1
  47. data/lib/mongo/bulk_write/ordered_combiner.rb +1 -1
  48. data/lib/mongo/bulk_write/result.rb +1 -1
  49. data/lib/mongo/bulk_write/result_combiner.rb +1 -1
  50. data/lib/mongo/bulk_write/transformable.rb +1 -1
  51. data/lib/mongo/bulk_write/unordered_combiner.rb +1 -1
  52. data/lib/mongo/bulk_write/validatable.rb +1 -1
  53. data/lib/mongo/bulk_write.rb +1 -1
  54. data/lib/mongo/caching_cursor.rb +1 -1
  55. data/lib/mongo/client.rb +27 -4
  56. data/lib/mongo/client_encryption.rb +102 -1
  57. data/lib/mongo/cluster/periodic_executor.rb +1 -1
  58. data/lib/mongo/cluster/reapers/cursor_reaper.rb +2 -6
  59. data/lib/mongo/cluster/reapers/socket_reaper.rb +2 -2
  60. data/lib/mongo/cluster/sdam_flow.rb +42 -15
  61. data/lib/mongo/cluster/topology/base.rb +1 -1
  62. data/lib/mongo/cluster/topology/load_balanced.rb +1 -1
  63. data/lib/mongo/cluster/topology/no_replica_set_options.rb +1 -1
  64. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +1 -1
  65. data/lib/mongo/cluster/topology/replica_set_with_primary.rb +1 -1
  66. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  67. data/lib/mongo/cluster/topology/single.rb +1 -1
  68. data/lib/mongo/cluster/topology/unknown.rb +1 -1
  69. data/lib/mongo/cluster/topology.rb +1 -1
  70. data/lib/mongo/cluster.rb +29 -12
  71. data/lib/mongo/cluster_time.rb +1 -1
  72. data/lib/mongo/collection/helpers.rb +1 -1
  73. data/lib/mongo/collection/queryable_encryption.rb +83 -43
  74. data/lib/mongo/collection/view/aggregation.rb +1 -1
  75. data/lib/mongo/collection/view/builder/aggregation.rb +1 -1
  76. data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
  77. data/lib/mongo/collection/view/builder.rb +1 -1
  78. data/lib/mongo/collection/view/change_stream/retryable.rb +1 -1
  79. data/lib/mongo/collection/view/change_stream.rb +3 -3
  80. data/lib/mongo/collection/view/explainable.rb +1 -1
  81. data/lib/mongo/collection/view/immutable.rb +1 -1
  82. data/lib/mongo/collection/view/iterable.rb +1 -1
  83. data/lib/mongo/collection/view/map_reduce.rb +1 -1
  84. data/lib/mongo/collection/view/readable.rb +11 -12
  85. data/lib/mongo/collection/view/writable.rb +1 -1
  86. data/lib/mongo/collection/view.rb +1 -1
  87. data/lib/mongo/collection.rb +26 -11
  88. data/lib/mongo/condition_variable.rb +58 -0
  89. data/lib/mongo/config/options.rb +1 -0
  90. data/lib/mongo/config/validators/option.rb +1 -0
  91. data/lib/mongo/config.rb +1 -0
  92. data/lib/mongo/crypt/auto_decryption_context.rb +1 -1
  93. data/lib/mongo/crypt/auto_encrypter.rb +5 -3
  94. data/lib/mongo/crypt/auto_encryption_context.rb +1 -1
  95. data/lib/mongo/crypt/binary.rb +1 -1
  96. data/lib/mongo/crypt/binding.rb +224 -30
  97. data/lib/mongo/crypt/context.rb +67 -4
  98. data/lib/mongo/crypt/data_key_context.rb +1 -1
  99. data/lib/mongo/crypt/encryption_io.rb +2 -2
  100. data/lib/mongo/crypt/explicit_decryption_context.rb +1 -1
  101. data/lib/mongo/crypt/explicit_encrypter.rb +120 -34
  102. data/lib/mongo/crypt/explicit_encryption_context.rb +58 -27
  103. data/lib/mongo/crypt/explicit_encryption_expression_context.rb +30 -0
  104. data/lib/mongo/crypt/handle.rb +10 -2
  105. data/lib/mongo/crypt/hooks.rb +1 -1
  106. data/lib/mongo/crypt/kms/aws/credentials.rb +83 -0
  107. data/lib/mongo/crypt/kms/aws/master_document.rb +78 -0
  108. data/lib/mongo/crypt/kms/aws.rb +3 -119
  109. data/lib/mongo/crypt/kms/azure/access_token.rb +54 -0
  110. data/lib/mongo/crypt/kms/azure/credentials.rb +103 -0
  111. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +122 -0
  112. data/lib/mongo/crypt/kms/azure/master_document.rb +79 -0
  113. data/lib/mongo/crypt/kms/azure.rb +5 -128
  114. data/lib/mongo/crypt/kms/credentials.rb +17 -2
  115. data/lib/mongo/crypt/kms/gcp/credentials.rb +127 -0
  116. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +58 -0
  117. data/lib/mongo/crypt/kms/gcp/master_document.rb +99 -0
  118. data/lib/mongo/crypt/kms/gcp.rb +4 -172
  119. data/lib/mongo/crypt/kms/kmip/credentials.rb +68 -0
  120. data/lib/mongo/crypt/kms/kmip/master_document.rb +74 -0
  121. data/lib/mongo/crypt/kms/kmip.rb +3 -100
  122. data/lib/mongo/crypt/kms/local/credentials.rb +65 -0
  123. data/lib/mongo/crypt/kms/local/master_document.rb +43 -0
  124. data/lib/mongo/crypt/kms/local.rb +3 -66
  125. data/lib/mongo/crypt/kms/master_key_document.rb +1 -1
  126. data/lib/mongo/crypt/kms.rb +7 -1
  127. data/lib/mongo/crypt/kms_context.rb +1 -1
  128. data/lib/mongo/crypt/rewrap_many_data_key_context.rb +1 -1
  129. data/lib/mongo/crypt/rewrap_many_data_key_result.rb +1 -1
  130. data/lib/mongo/crypt/status.rb +1 -1
  131. data/lib/mongo/crypt.rb +13 -1
  132. data/lib/mongo/cursor/kill_spec.rb +1 -1
  133. data/lib/mongo/cursor.rb +40 -6
  134. data/lib/mongo/database/view.rb +41 -4
  135. data/lib/mongo/database.rb +2 -2
  136. data/lib/mongo/dbref.rb +1 -1
  137. data/lib/mongo/distinguishing_semaphore.rb +2 -2
  138. data/lib/mongo/error/auth_error.rb +1 -1
  139. data/lib/mongo/error/bad_load_balancer_target.rb +1 -1
  140. data/lib/mongo/error/bulk_write_error.rb +1 -1
  141. data/lib/mongo/error/change_stream_resumable.rb +1 -1
  142. data/lib/mongo/error/client_closed.rb +24 -0
  143. data/lib/mongo/error/closed_stream.rb +1 -1
  144. data/lib/mongo/error/connection_check_out_timeout.rb +1 -1
  145. data/lib/mongo/error/connection_perished.rb +3 -1
  146. data/lib/mongo/error/connection_unavailable.rb +27 -0
  147. data/lib/mongo/error/credential_check_error.rb +1 -1
  148. data/lib/mongo/error/crypt_error.rb +1 -1
  149. data/lib/mongo/error/extra_file_chunk.rb +1 -1
  150. data/lib/mongo/error/failed_string_prep_validation.rb +1 -1
  151. data/lib/mongo/error/file_not_found.rb +1 -1
  152. data/lib/mongo/error/handshake_error.rb +1 -1
  153. data/lib/mongo/error/insufficient_iteration_count.rb +1 -1
  154. data/lib/mongo/error/internal_driver_error.rb +1 -1
  155. data/lib/mongo/error/invalid_address.rb +1 -1
  156. data/lib/mongo/error/invalid_application_name.rb +1 -1
  157. data/lib/mongo/error/invalid_bulk_operation.rb +1 -1
  158. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -1
  159. data/lib/mongo/error/invalid_collection_name.rb +1 -1
  160. data/lib/mongo/error/invalid_config_option.rb +1 -0
  161. data/lib/mongo/error/invalid_cursor_operation.rb +1 -1
  162. data/lib/mongo/error/invalid_database_name.rb +1 -1
  163. data/lib/mongo/error/invalid_document.rb +1 -1
  164. data/lib/mongo/error/invalid_file.rb +1 -1
  165. data/lib/mongo/error/invalid_file_revision.rb +1 -1
  166. data/lib/mongo/error/invalid_min_pool_size.rb +1 -1
  167. data/lib/mongo/error/invalid_nonce.rb +1 -1
  168. data/lib/mongo/error/invalid_read_concern.rb +1 -1
  169. data/lib/mongo/error/invalid_read_option.rb +1 -1
  170. data/lib/mongo/error/invalid_replacement_document.rb +1 -1
  171. data/lib/mongo/error/invalid_server_auth_host.rb +1 -1
  172. data/lib/mongo/error/invalid_server_auth_response.rb +1 -1
  173. data/lib/mongo/error/invalid_server_preference.rb +1 -1
  174. data/lib/mongo/error/invalid_session.rb +1 -1
  175. data/lib/mongo/error/invalid_signature.rb +1 -1
  176. data/lib/mongo/error/invalid_transaction_operation.rb +1 -1
  177. data/lib/mongo/error/invalid_txt_record.rb +1 -1
  178. data/lib/mongo/error/invalid_update_document.rb +1 -1
  179. data/lib/mongo/error/invalid_uri.rb +1 -1
  180. data/lib/mongo/error/invalid_write_concern.rb +1 -1
  181. data/lib/mongo/error/kms_error.rb +1 -1
  182. data/lib/mongo/error/labelable.rb +1 -1
  183. data/lib/mongo/error/lint_error.rb +1 -1
  184. data/lib/mongo/error/max_bson_size.rb +1 -1
  185. data/lib/mongo/error/max_message_size.rb +1 -1
  186. data/lib/mongo/error/mismatched_domain.rb +1 -1
  187. data/lib/mongo/error/missing_connection.rb +4 -2
  188. data/lib/mongo/error/missing_file_chunk.rb +1 -1
  189. data/lib/mongo/error/missing_password.rb +1 -1
  190. data/lib/mongo/error/missing_resume_token.rb +1 -1
  191. data/lib/mongo/error/missing_scram_server_signature.rb +1 -1
  192. data/lib/mongo/error/missing_service_id.rb +1 -1
  193. data/lib/mongo/error/mongocryptd_spawn_error.rb +1 -1
  194. data/lib/mongo/error/multi_index_drop.rb +1 -1
  195. data/lib/mongo/error/need_primary_server.rb +1 -1
  196. data/lib/mongo/error/no_server_available.rb +1 -1
  197. data/lib/mongo/error/no_service_connection_available.rb +1 -1
  198. data/lib/mongo/error/no_srv_records.rb +1 -1
  199. data/lib/mongo/error/notable.rb +8 -1
  200. data/lib/mongo/error/operation_failure.rb +1 -1
  201. data/lib/mongo/error/parser.rb +1 -1
  202. data/lib/mongo/error/pool_cleared_error.rb +40 -0
  203. data/lib/mongo/error/pool_closed_error.rb +4 -17
  204. data/lib/mongo/error/pool_error.rb +45 -0
  205. data/lib/mongo/error/pool_paused_error.rb +40 -0
  206. data/lib/mongo/error/raise_original_error.rb +1 -1
  207. data/lib/mongo/error/read_write_retryable.rb +1 -1
  208. data/lib/mongo/error/sdam_error_detection.rb +1 -1
  209. data/lib/mongo/error/server_api_conflict.rb +1 -1
  210. data/lib/mongo/error/server_api_not_supported.rb +1 -1
  211. data/lib/mongo/error/server_certificate_revoked.rb +1 -1
  212. data/lib/mongo/error/server_not_usable.rb +36 -0
  213. data/lib/mongo/error/session_ended.rb +1 -1
  214. data/lib/mongo/error/session_not_materialized.rb +1 -1
  215. data/lib/mongo/error/sessions_not_supported.rb +1 -1
  216. data/lib/mongo/error/snapshot_session_invalid_server_version.rb +1 -1
  217. data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +1 -1
  218. data/lib/mongo/error/socket_error.rb +1 -1
  219. data/lib/mongo/error/socket_timeout_error.rb +1 -1
  220. data/lib/mongo/error/unchangeable_collection_option.rb +1 -1
  221. data/lib/mongo/error/unexpected_chunk_length.rb +1 -1
  222. data/lib/mongo/error/unexpected_response.rb +1 -1
  223. data/lib/mongo/error/unknown_payload_type.rb +1 -1
  224. data/lib/mongo/error/unmet_dependency.rb +1 -1
  225. data/lib/mongo/error/unsupported_array_filters.rb +1 -1
  226. data/lib/mongo/error/unsupported_collation.rb +1 -1
  227. data/lib/mongo/error/unsupported_features.rb +1 -1
  228. data/lib/mongo/error/unsupported_message_type.rb +1 -1
  229. data/lib/mongo/error/unsupported_option.rb +1 -1
  230. data/lib/mongo/error/write_retryable.rb +1 -1
  231. data/lib/mongo/error.rb +7 -1
  232. data/lib/mongo/event/base.rb +1 -1
  233. data/lib/mongo/event/listeners.rb +1 -1
  234. data/lib/mongo/event/publisher.rb +1 -1
  235. data/lib/mongo/event/subscriber.rb +1 -1
  236. data/lib/mongo/event.rb +1 -1
  237. data/lib/mongo/grid/file/chunk.rb +3 -2
  238. data/lib/mongo/grid/file/info.rb +3 -2
  239. data/lib/mongo/grid/file.rb +1 -1
  240. data/lib/mongo/grid/fs_bucket.rb +1 -1
  241. data/lib/mongo/grid/stream/read.rb +1 -1
  242. data/lib/mongo/grid/stream/write.rb +1 -1
  243. data/lib/mongo/grid/stream.rb +1 -1
  244. data/lib/mongo/grid.rb +1 -1
  245. data/lib/mongo/id.rb +1 -1
  246. data/lib/mongo/index/view.rb +1 -1
  247. data/lib/mongo/index.rb +1 -1
  248. data/lib/mongo/lint.rb +1 -1
  249. data/lib/mongo/loggable.rb +3 -3
  250. data/lib/mongo/logger.rb +1 -1
  251. data/lib/mongo/monitoring/cmap_log_subscriber.rb +1 -1
  252. data/lib/mongo/monitoring/command_log_subscriber.rb +1 -1
  253. data/lib/mongo/monitoring/event/cmap/base.rb +1 -1
  254. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -1
  255. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +1 -1
  256. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +1 -1
  257. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +1 -1
  258. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +1 -1
  259. data/lib/mongo/monitoring/event/cmap/connection_created.rb +1 -1
  260. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +1 -1
  261. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +9 -2
  262. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +1 -1
  263. data/lib/mongo/monitoring/event/cmap/pool_created.rb +1 -1
  264. data/lib/mongo/monitoring/event/cmap/pool_ready.rb +67 -0
  265. data/lib/mongo/monitoring/event/cmap.rb +2 -1
  266. data/lib/mongo/monitoring/event/command_failed.rb +1 -1
  267. data/lib/mongo/monitoring/event/command_started.rb +1 -1
  268. data/lib/mongo/monitoring/event/command_succeeded.rb +1 -1
  269. data/lib/mongo/monitoring/event/secure.rb +1 -1
  270. data/lib/mongo/monitoring/event/server_closed.rb +1 -1
  271. data/lib/mongo/monitoring/event/server_description_changed.rb +1 -1
  272. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +1 -1
  273. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +1 -1
  274. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +1 -1
  275. data/lib/mongo/monitoring/event/server_opening.rb +1 -1
  276. data/lib/mongo/monitoring/event/topology_changed.rb +1 -1
  277. data/lib/mongo/monitoring/event/topology_closed.rb +1 -1
  278. data/lib/mongo/monitoring/event/topology_opening.rb +1 -1
  279. data/lib/mongo/monitoring/event.rb +1 -1
  280. data/lib/mongo/monitoring/publishable.rb +1 -1
  281. data/lib/mongo/monitoring/sdam_log_subscriber.rb +1 -1
  282. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +1 -1
  283. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +1 -1
  284. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +1 -1
  285. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +1 -1
  286. data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +1 -1
  287. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +1 -1
  288. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +1 -1
  289. data/lib/mongo/monitoring.rb +1 -1
  290. data/lib/mongo/operation/aggregate/op_msg.rb +1 -1
  291. data/lib/mongo/operation/aggregate/result.rb +1 -1
  292. data/lib/mongo/operation/aggregate.rb +1 -1
  293. data/lib/mongo/operation/collections_info/result.rb +1 -1
  294. data/lib/mongo/operation/collections_info.rb +1 -1
  295. data/lib/mongo/operation/command/op_msg.rb +1 -1
  296. data/lib/mongo/operation/command.rb +1 -1
  297. data/lib/mongo/operation/context.rb +1 -1
  298. data/lib/mongo/operation/count/op_msg.rb +1 -1
  299. data/lib/mongo/operation/count.rb +1 -1
  300. data/lib/mongo/operation/create/op_msg.rb +1 -1
  301. data/lib/mongo/operation/create.rb +1 -1
  302. data/lib/mongo/operation/create_index/op_msg.rb +1 -1
  303. data/lib/mongo/operation/create_index.rb +1 -1
  304. data/lib/mongo/operation/create_user/op_msg.rb +1 -1
  305. data/lib/mongo/operation/create_user.rb +1 -1
  306. data/lib/mongo/operation/delete/bulk_result.rb +1 -1
  307. data/lib/mongo/operation/delete/op_msg.rb +1 -1
  308. data/lib/mongo/operation/delete/result.rb +1 -1
  309. data/lib/mongo/operation/delete.rb +1 -1
  310. data/lib/mongo/operation/distinct/op_msg.rb +1 -1
  311. data/lib/mongo/operation/distinct.rb +1 -1
  312. data/lib/mongo/operation/drop/op_msg.rb +1 -1
  313. data/lib/mongo/operation/drop.rb +1 -1
  314. data/lib/mongo/operation/drop_database/op_msg.rb +1 -1
  315. data/lib/mongo/operation/drop_database.rb +1 -1
  316. data/lib/mongo/operation/drop_index/op_msg.rb +1 -1
  317. data/lib/mongo/operation/drop_index.rb +1 -1
  318. data/lib/mongo/operation/explain/op_msg.rb +1 -1
  319. data/lib/mongo/operation/explain/result.rb +1 -1
  320. data/lib/mongo/operation/explain.rb +1 -1
  321. data/lib/mongo/operation/find/builder/command.rb +1 -1
  322. data/lib/mongo/operation/find/builder/flags.rb +1 -1
  323. data/lib/mongo/operation/find/builder/modifiers.rb +1 -1
  324. data/lib/mongo/operation/find/builder.rb +1 -1
  325. data/lib/mongo/operation/find/op_msg.rb +1 -1
  326. data/lib/mongo/operation/find/result.rb +1 -1
  327. data/lib/mongo/operation/find.rb +1 -1
  328. data/lib/mongo/operation/get_more/command_builder.rb +1 -1
  329. data/lib/mongo/operation/get_more/op_msg.rb +1 -1
  330. data/lib/mongo/operation/get_more/result.rb +1 -1
  331. data/lib/mongo/operation/get_more.rb +1 -1
  332. data/lib/mongo/operation/indexes/op_msg.rb +1 -1
  333. data/lib/mongo/operation/indexes/result.rb +1 -1
  334. data/lib/mongo/operation/indexes.rb +1 -1
  335. data/lib/mongo/operation/insert/bulk_result.rb +1 -1
  336. data/lib/mongo/operation/insert/op_msg.rb +1 -1
  337. data/lib/mongo/operation/insert/result.rb +1 -1
  338. data/lib/mongo/operation/insert.rb +1 -1
  339. data/lib/mongo/operation/kill_cursors/command_builder.rb +1 -1
  340. data/lib/mongo/operation/kill_cursors/op_msg.rb +1 -1
  341. data/lib/mongo/operation/kill_cursors.rb +1 -1
  342. data/lib/mongo/operation/list_collections/op_msg.rb +1 -1
  343. data/lib/mongo/operation/list_collections/result.rb +1 -1
  344. data/lib/mongo/operation/list_collections.rb +1 -1
  345. data/lib/mongo/operation/map_reduce/op_msg.rb +1 -1
  346. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  347. data/lib/mongo/operation/map_reduce.rb +1 -1
  348. data/lib/mongo/operation/op_msg_base.rb +1 -1
  349. data/lib/mongo/operation/parallel_scan/op_msg.rb +1 -1
  350. data/lib/mongo/operation/parallel_scan/result.rb +1 -1
  351. data/lib/mongo/operation/parallel_scan.rb +1 -1
  352. data/lib/mongo/operation/remove_user/op_msg.rb +1 -1
  353. data/lib/mongo/operation/remove_user.rb +1 -1
  354. data/lib/mongo/operation/result.rb +1 -1
  355. data/lib/mongo/operation/shared/bypass_document_validation.rb +1 -1
  356. data/lib/mongo/operation/shared/causal_consistency_supported.rb +1 -1
  357. data/lib/mongo/operation/shared/executable.rb +1 -1
  358. data/lib/mongo/operation/shared/executable_no_validate.rb +1 -1
  359. data/lib/mongo/operation/shared/executable_transaction_label.rb +1 -1
  360. data/lib/mongo/operation/shared/idable.rb +1 -1
  361. data/lib/mongo/operation/shared/limited.rb +1 -1
  362. data/lib/mongo/operation/shared/object_id_generator.rb +1 -1
  363. data/lib/mongo/operation/shared/op_msg_executable.rb +1 -1
  364. data/lib/mongo/operation/shared/polymorphic_lookup.rb +1 -1
  365. data/lib/mongo/operation/shared/polymorphic_result.rb +1 -1
  366. data/lib/mongo/operation/shared/read_preference_supported.rb +1 -1
  367. data/lib/mongo/operation/shared/response_handling.rb +1 -1
  368. data/lib/mongo/operation/shared/result/aggregatable.rb +1 -1
  369. data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +1 -1
  370. data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
  371. data/lib/mongo/operation/shared/specifiable.rb +1 -1
  372. data/lib/mongo/operation/shared/validatable.rb +1 -1
  373. data/lib/mongo/operation/shared/write.rb +1 -1
  374. data/lib/mongo/operation/shared/write_concern_supported.rb +1 -1
  375. data/lib/mongo/operation/update/bulk_result.rb +1 -1
  376. data/lib/mongo/operation/update/op_msg.rb +1 -1
  377. data/lib/mongo/operation/update/result.rb +1 -1
  378. data/lib/mongo/operation/update.rb +1 -1
  379. data/lib/mongo/operation/update_user/op_msg.rb +1 -1
  380. data/lib/mongo/operation/update_user.rb +1 -1
  381. data/lib/mongo/operation/users_info/op_msg.rb +1 -1
  382. data/lib/mongo/operation/users_info/result.rb +1 -1
  383. data/lib/mongo/operation/users_info.rb +1 -1
  384. data/lib/mongo/operation/write_command/op_msg.rb +1 -1
  385. data/lib/mongo/operation/write_command.rb +1 -1
  386. data/lib/mongo/operation.rb +1 -1
  387. data/lib/mongo/options/mapper.rb +1 -1
  388. data/lib/mongo/options/redacted.rb +1 -1
  389. data/lib/mongo/options.rb +1 -1
  390. data/lib/mongo/protocol/bit_vector.rb +4 -2
  391. data/lib/mongo/protocol/caching_hash.rb +4 -21
  392. data/lib/mongo/protocol/compressed.rb +1 -1
  393. data/lib/mongo/protocol/get_more.rb +1 -1
  394. data/lib/mongo/protocol/kill_cursors.rb +1 -1
  395. data/lib/mongo/protocol/message.rb +5 -9
  396. data/lib/mongo/protocol/msg.rb +2 -1
  397. data/lib/mongo/protocol/query.rb +1 -1
  398. data/lib/mongo/protocol/registry.rb +1 -1
  399. data/lib/mongo/protocol/reply.rb +1 -1
  400. data/lib/mongo/protocol/serializers.rb +25 -18
  401. data/lib/mongo/protocol.rb +1 -1
  402. data/lib/mongo/query_cache.rb +1 -1
  403. data/lib/mongo/retryable/base_worker.rb +91 -0
  404. data/lib/mongo/retryable/read_worker.rb +296 -0
  405. data/lib/mongo/retryable/write_worker.rb +364 -0
  406. data/lib/mongo/retryable.rb +31 -502
  407. data/lib/mongo/semaphore.rb +2 -2
  408. data/lib/mongo/server/app_metadata/environment.rb +259 -0
  409. data/lib/mongo/server/app_metadata/platform.rb +114 -0
  410. data/lib/mongo/server/app_metadata/truncator.rb +142 -0
  411. data/lib/mongo/server/app_metadata.rb +75 -108
  412. data/lib/mongo/server/connection.rb +61 -20
  413. data/lib/mongo/server/connection_base.rb +1 -1
  414. data/lib/mongo/server/connection_common.rb +1 -1
  415. data/lib/mongo/server/connection_pool/generation_manager.rb +56 -12
  416. data/lib/mongo/server/connection_pool/populator.rb +33 -31
  417. data/lib/mongo/server/connection_pool.rb +670 -263
  418. data/lib/mongo/server/description/features.rb +2 -2
  419. data/lib/mongo/server/description/load_balancer.rb +1 -1
  420. data/lib/mongo/server/description.rb +7 -6
  421. data/lib/mongo/server/monitor/app_metadata.rb +1 -1
  422. data/lib/mongo/server/monitor/connection.rb +1 -1
  423. data/lib/mongo/server/monitor.rb +11 -7
  424. data/lib/mongo/server/pending_connection.rb +1 -1
  425. data/lib/mongo/server/push_monitor/connection.rb +1 -1
  426. data/lib/mongo/server/push_monitor.rb +1 -1
  427. data/lib/mongo/server/round_trip_time_averager.rb +1 -1
  428. data/lib/mongo/server.rb +96 -30
  429. data/lib/mongo/server_selector/base.rb +24 -3
  430. data/lib/mongo/server_selector/nearest.rb +1 -1
  431. data/lib/mongo/server_selector/primary.rb +1 -1
  432. data/lib/mongo/server_selector/primary_preferred.rb +1 -1
  433. data/lib/mongo/server_selector/secondary.rb +1 -1
  434. data/lib/mongo/server_selector/secondary_preferred.rb +1 -1
  435. data/lib/mongo/server_selector.rb +1 -1
  436. data/lib/mongo/session/server_session.rb +1 -1
  437. data/lib/mongo/session/session_pool.rb +1 -1
  438. data/lib/mongo/session.rb +1 -1
  439. data/lib/mongo/socket/ocsp_cache.rb +1 -1
  440. data/lib/mongo/socket/ocsp_verifier.rb +1 -1
  441. data/lib/mongo/socket/ssl.rb +1 -1
  442. data/lib/mongo/socket/tcp.rb +1 -1
  443. data/lib/mongo/socket/unix.rb +1 -1
  444. data/lib/mongo/socket.rb +29 -2
  445. data/lib/mongo/srv/monitor.rb +1 -3
  446. data/lib/mongo/srv/resolver.rb +1 -1
  447. data/lib/mongo/srv/result.rb +1 -1
  448. data/lib/mongo/srv.rb +1 -1
  449. data/lib/mongo/timeout.rb +2 -2
  450. data/lib/mongo/topology_version.rb +1 -1
  451. data/lib/mongo/uri/options_mapper.rb +321 -81
  452. data/lib/mongo/uri/srv_protocol.rb +1 -1
  453. data/lib/mongo/uri.rb +41 -13
  454. data/lib/mongo/utils.rb +1 -1
  455. data/lib/mongo/version.rb +2 -2
  456. data/lib/mongo/write_concern/acknowledged.rb +1 -1
  457. data/lib/mongo/write_concern/base.rb +1 -1
  458. data/lib/mongo/write_concern/unacknowledged.rb +1 -1
  459. data/lib/mongo/write_concern.rb +1 -1
  460. data/lib/mongo.rb +2 -1
  461. data/mongo.gemspec +5 -2
  462. data/spec/atlas/atlas_connectivity_spec.rb +1 -1
  463. data/spec/atlas/operations_spec.rb +3 -8
  464. data/spec/integration/auth_spec.rb +1 -1
  465. data/spec/integration/awaited_ismaster_spec.rb +1 -1
  466. data/spec/integration/aws_auth_credentials_cache_spec.rb +51 -0
  467. data/spec/integration/aws_auth_request_spec.rb +2 -2
  468. data/spec/integration/aws_credentials_retriever_spec.rb +32 -2
  469. data/spec/integration/aws_lambda_examples_spec.rb +1 -1
  470. data/spec/integration/bson_symbol_spec.rb +1 -1
  471. data/spec/integration/bulk_insert_spec.rb +1 -1
  472. data/spec/integration/bulk_write_error_message_spec.rb +1 -0
  473. data/spec/integration/bulk_write_spec.rb +1 -1
  474. data/spec/integration/change_stream_examples_spec.rb +1 -1
  475. data/spec/integration/change_stream_spec.rb +6 -1
  476. data/spec/integration/check_clean_slate_spec.rb +1 -1
  477. data/spec/integration/client_authentication_options_spec.rb +1 -1
  478. data/spec/integration/client_connectivity_spec.rb +1 -1
  479. data/spec/integration/client_construction_aws_auth_spec.rb +12 -3
  480. data/spec/integration/client_construction_spec.rb +23 -1
  481. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +1 -1
  482. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +1 -1
  483. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +1 -1
  484. data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +1 -1
  485. data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +10 -5
  486. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +38 -2
  487. data/spec/integration/client_side_encryption/automatic_data_encryption_keys_prose_spec.rb +153 -0
  488. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +1 -1
  489. data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +1 -1
  490. data/spec/integration/client_side_encryption/client_close_spec.rb +1 -1
  491. data/spec/integration/client_side_encryption/corpus_spec.rb +1 -1
  492. data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +3 -3
  493. data/spec/integration/client_side_encryption/data_key_spec.rb +1 -1
  494. data/spec/integration/client_side_encryption/decryption_events_prose_spec.rb +59 -58
  495. data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +1 -1
  496. data/spec/integration/client_side_encryption/explicit_queryable_encryption_spec.rb +36 -33
  497. data/spec/integration/client_side_encryption/external_key_vault_spec.rb +1 -1
  498. data/spec/integration/client_side_encryption/kms_tls_options_spec.rb +3 -3
  499. data/spec/integration/client_side_encryption/kms_tls_spec.rb +1 -1
  500. data/spec/integration/client_side_encryption/mongocryptd_prose_spec.rb +105 -0
  501. data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +49 -0
  502. data/spec/integration/client_side_encryption/on_demand_azure_credentials_spec.rb +46 -0
  503. data/spec/integration/client_side_encryption/on_demand_gcp_credentials_spec.rb +47 -0
  504. data/spec/integration/client_side_encryption/queryable_encryption_examples_spec.rb +14 -11
  505. data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +536 -0
  506. data/spec/integration/client_side_encryption/rewrap_prose_spec.rb +114 -0
  507. data/spec/integration/client_side_encryption/unique_index_on_key_alt_names_prose_spec.rb +20 -16
  508. data/spec/integration/client_side_encryption/views_spec.rb +1 -1
  509. data/spec/integration/client_spec.rb +8 -3
  510. data/spec/integration/client_update_spec.rb +7 -3
  511. data/spec/integration/collection_indexes_prose_spec.rb +1 -1
  512. data/spec/integration/command_monitoring_spec.rb +1 -1
  513. data/spec/integration/command_spec.rb +1 -1
  514. data/spec/integration/connect_single_rs_name_spec.rb +1 -1
  515. data/spec/integration/connection/faas_env_spec.rb +62 -0
  516. data/spec/integration/connection_pool_populator_spec.rb +27 -7
  517. data/spec/integration/connection_spec.rb +1 -1
  518. data/spec/integration/crud_spec.rb +1 -1
  519. data/spec/integration/cursor_pinning_spec.rb +6 -2
  520. data/spec/integration/cursor_reaping_spec.rb +1 -1
  521. data/spec/integration/docs_examples_spec.rb +1 -1
  522. data/spec/integration/error_detection_spec.rb +1 -1
  523. data/spec/integration/fork_reconnect_spec.rb +2 -2
  524. data/spec/integration/get_more_spec.rb +1 -1
  525. data/spec/integration/grid_fs_bucket_spec.rb +1 -1
  526. data/spec/integration/heartbeat_events_spec.rb +1 -1
  527. data/spec/integration/map_reduce_spec.rb +5 -1
  528. data/spec/integration/mmapv1_spec.rb +1 -1
  529. data/spec/integration/mongos_pinning_spec.rb +1 -1
  530. data/spec/integration/ocsp_connectivity_spec.rb +1 -1
  531. data/spec/integration/ocsp_verifier_cache_spec.rb +1 -1
  532. data/spec/integration/ocsp_verifier_spec.rb +2 -2
  533. data/spec/integration/operation_failure_code_spec.rb +1 -1
  534. data/spec/integration/operation_failure_message_spec.rb +1 -0
  535. data/spec/integration/query_cache_spec.rb +90 -3
  536. data/spec/integration/query_cache_transactions_spec.rb +1 -1
  537. data/spec/integration/read_concern_spec.rb +1 -1
  538. data/spec/integration/read_preference_spec.rb +1 -1
  539. data/spec/integration/reconnect_spec.rb +4 -1
  540. data/spec/integration/retryable_errors_spec.rb +1 -1
  541. data/spec/integration/retryable_reads_errors_spec.rb +110 -0
  542. data/spec/integration/retryable_writes/retryable_writes_36_and_older_spec.rb +1 -1
  543. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -1
  544. data/spec/integration/retryable_writes/shared/adds_diagnostics.rb +1 -1
  545. data/spec/integration/retryable_writes/shared/does_not_support_retries.rb +1 -1
  546. data/spec/integration/retryable_writes/shared/only_supports_legacy_retries.rb +1 -1
  547. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +1 -1
  548. data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +1 -1
  549. data/spec/integration/retryable_writes/shared/performs_no_retries.rb +1 -1
  550. data/spec/integration/retryable_writes/shared/supports_legacy_retries.rb +1 -1
  551. data/spec/integration/retryable_writes/shared/supports_modern_retries.rb +1 -1
  552. data/spec/integration/retryable_writes/shared/supports_retries.rb +1 -1
  553. data/spec/integration/retryable_writes_errors_spec.rb +160 -2
  554. data/spec/integration/sdam_error_handling_spec.rb +65 -4
  555. data/spec/integration/sdam_events_spec.rb +1 -1
  556. data/spec/integration/sdam_prose_spec.rb +3 -3
  557. data/spec/integration/secondary_reads_spec.rb +1 -0
  558. data/spec/integration/server_description_spec.rb +1 -1
  559. data/spec/integration/server_monitor_spec.rb +1 -1
  560. data/spec/integration/server_selection_spec.rb +1 -1
  561. data/spec/integration/server_selector_spec.rb +5 -3
  562. data/spec/integration/server_spec.rb +23 -26
  563. data/spec/integration/shell_examples_spec.rb +1 -1
  564. data/spec/integration/size_limit_spec.rb +1 -1
  565. data/spec/integration/snappy_compression_spec.rb +1 -1
  566. data/spec/integration/snapshot_query_examples_spec.rb +9 -7
  567. data/spec/integration/srv_monitoring_spec.rb +2 -1
  568. data/spec/integration/srv_spec.rb +3 -3
  569. data/spec/integration/ssl_uri_options_spec.rb +1 -1
  570. data/spec/integration/step_down_spec.rb +5 -3
  571. data/spec/integration/time_zone_querying_spec.rb +1 -1
  572. data/spec/integration/transaction_pinning_spec.rb +18 -4
  573. data/spec/integration/transactions_api_examples_spec.rb +1 -1
  574. data/spec/integration/transactions_examples_spec.rb +1 -1
  575. data/spec/integration/truncated_utf8_spec.rb +1 -1
  576. data/spec/integration/versioned_api_examples_spec.rb +2 -2
  577. data/spec/integration/x509_auth_spec.rb +1 -1
  578. data/spec/integration/zlib_compression_spec.rb +1 -1
  579. data/spec/integration/zstd_compression_spec.rb +1 -1
  580. data/spec/kerberos/kerberos_spec.rb +1 -1
  581. data/spec/lite_spec_helper.rb +10 -1
  582. data/spec/mongo/address/ipv4_spec.rb +1 -1
  583. data/spec/mongo/address/ipv6_spec.rb +1 -1
  584. data/spec/mongo/address/unix_spec.rb +1 -1
  585. data/spec/mongo/address/validator_spec.rb +1 -1
  586. data/spec/mongo/address_spec.rb +8 -2
  587. data/spec/mongo/auth/aws/credential_cache_spec.rb +63 -0
  588. data/spec/mongo/auth/aws/credentials_retriever_spec.rb +90 -0
  589. data/spec/mongo/auth/aws/credentials_spec.rb +46 -0
  590. data/spec/mongo/auth/aws/request_region_spec.rb +1 -1
  591. data/spec/mongo/auth/aws/request_spec.rb +1 -1
  592. data/spec/mongo/auth/cr_spec.rb +2 -22
  593. data/spec/mongo/auth/gssapi/conversation_spec.rb +1 -1
  594. data/spec/mongo/auth/invalid_mechanism_spec.rb +1 -1
  595. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  596. data/spec/mongo/auth/ldap_spec.rb +1 -1
  597. data/spec/mongo/auth/scram/conversation_spec.rb +1 -1
  598. data/spec/mongo/auth/scram256/conversation_spec.rb +1 -1
  599. data/spec/mongo/auth/scram_negotiation_spec.rb +1 -1
  600. data/spec/mongo/auth/scram_spec.rb +1 -1
  601. data/spec/mongo/auth/stringprep/profiles/sasl_spec.rb +1 -1
  602. data/spec/mongo/auth/stringprep_spec.rb +1 -1
  603. data/spec/mongo/auth/user/view_spec.rb +96 -1
  604. data/spec/mongo/auth/user_spec.rb +1 -1
  605. data/spec/mongo/auth/x509/conversation_spec.rb +1 -1
  606. data/spec/mongo/auth/x509_spec.rb +1 -1
  607. data/spec/mongo/auth_spec.rb +1 -1
  608. data/spec/mongo/bson_spec.rb +1 -1
  609. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +1 -1
  610. data/spec/mongo/bulk_write/result_spec.rb +1 -1
  611. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +1 -1
  612. data/spec/mongo/bulk_write_spec.rb +1 -1
  613. data/spec/mongo/caching_cursor_spec.rb +1 -1
  614. data/spec/mongo/client_construction_spec.rb +572 -694
  615. data/spec/mongo/client_encryption_spec.rb +1 -1
  616. data/spec/mongo/client_spec.rb +172 -231
  617. data/spec/mongo/cluster/cursor_reaper_spec.rb +1 -1
  618. data/spec/mongo/cluster/periodic_executor_spec.rb +1 -1
  619. data/spec/mongo/cluster/socket_reaper_spec.rb +1 -1
  620. data/spec/mongo/cluster/topology/replica_set_spec.rb +1 -1
  621. data/spec/mongo/cluster/topology/sharded_spec.rb +1 -1
  622. data/spec/mongo/cluster/topology/single_spec.rb +1 -1
  623. data/spec/mongo/cluster/topology/unknown_spec.rb +1 -1
  624. data/spec/mongo/cluster/topology_spec.rb +1 -1
  625. data/spec/mongo/cluster_spec.rb +156 -154
  626. data/spec/mongo/cluster_time_spec.rb +1 -1
  627. data/spec/mongo/collection/view/aggregation_spec.rb +1 -1
  628. data/spec/mongo/collection/view/builder/find_command_spec.rb +1 -1
  629. data/spec/mongo/collection/view/builder/op_query_spec.rb +1 -1
  630. data/spec/mongo/collection/view/change_stream_resume_spec.rb +1 -1
  631. data/spec/mongo/collection/view/change_stream_spec.rb +1 -1
  632. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  633. data/spec/mongo/collection/view/immutable_spec.rb +1 -1
  634. data/spec/mongo/collection/view/iterable_spec.rb +1 -1
  635. data/spec/mongo/collection/view/map_reduce_spec.rb +11 -1
  636. data/spec/mongo/collection/view/readable_spec.rb +139 -1
  637. data/spec/mongo/collection/view/writable_spec.rb +1 -1
  638. data/spec/mongo/collection/view_spec.rb +1 -1
  639. data/spec/mongo/collection_crud_spec.rb +1 -1
  640. data/spec/mongo/collection_ddl_spec.rb +112 -66
  641. data/spec/mongo/collection_spec.rb +3 -3
  642. data/spec/mongo/condition_variable_spec.rb +104 -0
  643. data/spec/mongo/config/options_spec.rb +1 -0
  644. data/spec/mongo/config_spec.rb +2 -1
  645. data/spec/mongo/crypt/auto_decryption_context_spec.rb +1 -1
  646. data/spec/mongo/crypt/auto_encrypter_spec.rb +8 -1
  647. data/spec/mongo/crypt/auto_encryption_context_spec.rb +1 -1
  648. data/spec/mongo/crypt/binary_spec.rb +1 -1
  649. data/spec/mongo/crypt/binding/binary_spec.rb +1 -1
  650. data/spec/mongo/crypt/binding/context_spec.rb +1 -1
  651. data/spec/mongo/crypt/binding/helpers_spec.rb +1 -1
  652. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +1 -1
  653. data/spec/mongo/crypt/binding/status_spec.rb +1 -1
  654. data/spec/mongo/crypt/binding/version_spec.rb +19 -5
  655. data/spec/mongo/crypt/binding_unloaded_spec.rb +1 -1
  656. data/spec/mongo/crypt/data_key_context_spec.rb +1 -1
  657. data/spec/mongo/crypt/encryption_io_spec.rb +1 -1
  658. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +1 -1
  659. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +3 -3
  660. data/spec/mongo/crypt/handle_spec.rb +19 -4
  661. data/spec/mongo/crypt/helpers/mongo_crypt_spec_helper.rb +1 -1
  662. data/spec/mongo/crypt/hooks_spec.rb +2 -2
  663. data/spec/mongo/crypt/kms/azure/credentials_retriever_spec.rb +86 -0
  664. data/spec/mongo/crypt/kms/credentials_spec.rb +17 -1
  665. data/spec/mongo/crypt/kms_spec.rb +1 -1
  666. data/spec/mongo/crypt/status_spec.rb +1 -1
  667. data/spec/mongo/crypt_spec.rb +21 -0
  668. data/spec/mongo/cursor/builder/get_more_command_spec.rb +1 -1
  669. data/spec/mongo/cursor/builder/op_get_more_spec.rb +1 -1
  670. data/spec/mongo/cursor_spec.rb +58 -11
  671. data/spec/mongo/database_spec.rb +1 -1
  672. data/spec/mongo/distinguishing_semaphore_spec.rb +7 -7
  673. data/spec/mongo/error/bulk_write_error_spec.rb +1 -1
  674. data/spec/mongo/error/crypt_error_spec.rb +1 -1
  675. data/spec/mongo/error/max_bson_size_spec.rb +1 -1
  676. data/spec/mongo/error/no_server_available_spec.rb +1 -1
  677. data/spec/mongo/error/notable_spec.rb +1 -1
  678. data/spec/mongo/error/operation_failure_heavy_spec.rb +1 -1
  679. data/spec/mongo/error/operation_failure_spec.rb +1 -1
  680. data/spec/mongo/error/parser_spec.rb +1 -1
  681. data/spec/mongo/error/unsupported_option_spec.rb +1 -1
  682. data/spec/mongo/event/publisher_spec.rb +1 -1
  683. data/spec/mongo/event/subscriber_spec.rb +1 -1
  684. data/spec/mongo/grid/file/chunk_spec.rb +1 -1
  685. data/spec/mongo/grid/file/info_spec.rb +1 -1
  686. data/spec/mongo/grid/file_spec.rb +1 -1
  687. data/spec/mongo/grid/fs_bucket_spec.rb +1 -1
  688. data/spec/mongo/grid/stream/read_spec.rb +1 -1
  689. data/spec/mongo/grid/stream/write_spec.rb +1 -1
  690. data/spec/mongo/grid/stream_spec.rb +1 -1
  691. data/spec/mongo/id_spec.rb +2 -2
  692. data/spec/mongo/index/view_spec.rb +4 -4
  693. data/spec/mongo/lint_spec.rb +2 -2
  694. data/spec/mongo/logger_spec.rb +1 -1
  695. data/spec/mongo/monitoring/command_log_subscriber_spec.rb +1 -1
  696. data/spec/mongo/monitoring/event/cmap/connection_check_out_failed_spec.rb +2 -2
  697. data/spec/mongo/monitoring/event/cmap/connection_check_out_started_spec.rb +2 -2
  698. data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +2 -2
  699. data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +2 -2
  700. data/spec/mongo/monitoring/event/cmap/connection_closed_spec.rb +2 -2
  701. data/spec/mongo/monitoring/event/cmap/connection_created_spec.rb +2 -2
  702. data/spec/mongo/monitoring/event/cmap/connection_ready_spec.rb +2 -2
  703. data/spec/mongo/monitoring/event/cmap/pool_cleared_spec.rb +2 -2
  704. data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +2 -2
  705. data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +2 -2
  706. data/spec/mongo/monitoring/event/command_failed_spec.rb +1 -1
  707. data/spec/mongo/monitoring/event/command_started_spec.rb +1 -1
  708. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +1 -1
  709. data/spec/mongo/monitoring/event/secure_spec.rb +1 -1
  710. data/spec/mongo/monitoring/event/server_closed_spec.rb +1 -1
  711. data/spec/mongo/monitoring/event/server_description_changed_spec.rb +1 -1
  712. data/spec/mongo/monitoring/event/server_heartbeat_failed_spec.rb +1 -1
  713. data/spec/mongo/monitoring/event/server_heartbeat_started_spec.rb +1 -1
  714. data/spec/mongo/monitoring/event/server_heartbeat_succeeded_spec.rb +1 -1
  715. data/spec/mongo/monitoring/event/server_opening_spec.rb +1 -1
  716. data/spec/mongo/monitoring/event/topology_changed_spec.rb +1 -1
  717. data/spec/mongo/monitoring/event/topology_closed_spec.rb +1 -1
  718. data/spec/mongo/monitoring/event/topology_opening_spec.rb +1 -1
  719. data/spec/mongo/monitoring_spec.rb +1 -1
  720. data/spec/mongo/operation/aggregate/result_spec.rb +1 -1
  721. data/spec/mongo/operation/aggregate_spec.rb +1 -1
  722. data/spec/mongo/operation/collections_info_spec.rb +1 -1
  723. data/spec/mongo/operation/command_spec.rb +1 -1
  724. data/spec/mongo/operation/create/op_msg_spec.rb +1 -1
  725. data/spec/mongo/operation/create_index_spec.rb +1 -1
  726. data/spec/mongo/operation/create_user_spec.rb +1 -1
  727. data/spec/mongo/operation/delete/bulk_spec.rb +1 -1
  728. data/spec/mongo/operation/delete/op_msg_spec.rb +1 -1
  729. data/spec/mongo/operation/delete_spec.rb +1 -1
  730. data/spec/mongo/operation/drop_index_spec.rb +1 -1
  731. data/spec/mongo/operation/find/builder/flags_spec.rb +1 -1
  732. data/spec/mongo/operation/find/builder/modifiers_spec.rb +1 -1
  733. data/spec/mongo/operation/indexes_spec.rb +1 -1
  734. data/spec/mongo/operation/insert/bulk_spec.rb +1 -1
  735. data/spec/mongo/operation/insert/op_msg_spec.rb +1 -1
  736. data/spec/mongo/operation/insert_spec.rb +1 -1
  737. data/spec/mongo/operation/limited_spec.rb +1 -1
  738. data/spec/mongo/operation/map_reduce_spec.rb +1 -1
  739. data/spec/mongo/operation/read_preference_legacy_spec.rb +1 -1
  740. data/spec/mongo/operation/read_preference_op_msg_spec.rb +1 -1
  741. data/spec/mongo/operation/remove_user_spec.rb +1 -1
  742. data/spec/mongo/operation/result_spec.rb +1 -1
  743. data/spec/mongo/operation/specifiable_spec.rb +1 -1
  744. data/spec/mongo/operation/update/bulk_spec.rb +1 -1
  745. data/spec/mongo/operation/update/op_msg_spec.rb +1 -1
  746. data/spec/mongo/operation/update_spec.rb +1 -1
  747. data/spec/mongo/operation/update_user_spec.rb +1 -1
  748. data/spec/mongo/options/redacted_spec.rb +2 -2
  749. data/spec/mongo/protocol/caching_hash_spec.rb +1 -46
  750. data/spec/mongo/protocol/compressed_spec.rb +1 -1
  751. data/spec/mongo/protocol/get_more_spec.rb +1 -1
  752. data/spec/mongo/protocol/kill_cursors_spec.rb +1 -1
  753. data/spec/mongo/protocol/msg_spec.rb +4 -5
  754. data/spec/mongo/protocol/query_spec.rb +1 -1
  755. data/spec/mongo/protocol/registry_spec.rb +1 -1
  756. data/spec/mongo/protocol/reply_spec.rb +1 -1
  757. data/spec/mongo/query_cache_middleware_spec.rb +1 -1
  758. data/spec/mongo/query_cache_spec.rb +1 -1
  759. data/spec/mongo/retryable_spec.rb +5 -3
  760. data/spec/mongo/semaphore_spec.rb +7 -7
  761. data/spec/mongo/server/app_metadata/environment_spec.rb +209 -0
  762. data/spec/mongo/server/app_metadata/truncator_spec.rb +158 -0
  763. data/spec/mongo/server/app_metadata_spec.rb +44 -66
  764. data/spec/mongo/server/connection_auth_spec.rb +1 -1
  765. data/spec/mongo/server/connection_common_spec.rb +1 -1
  766. data/spec/mongo/server/connection_pool/populator_spec.rb +17 -3
  767. data/spec/mongo/server/connection_pool_spec.rb +447 -10
  768. data/spec/mongo/server/connection_spec.rb +17 -4
  769. data/spec/mongo/server/description/features_spec.rb +1 -1
  770. data/spec/mongo/server/description_query_methods_spec.rb +1 -1
  771. data/spec/mongo/server/description_spec.rb +1 -1
  772. data/spec/mongo/server/monitor/app_metadata_spec.rb +1 -1
  773. data/spec/mongo/server/monitor/connection_spec.rb +3 -3
  774. data/spec/mongo/server/monitor_spec.rb +6 -5
  775. data/spec/mongo/server/push_monitor_spec.rb +1 -1
  776. data/spec/mongo/server/round_trip_time_averager_spec.rb +1 -1
  777. data/spec/mongo/server_selector/nearest_spec.rb +1 -1
  778. data/spec/mongo/server_selector/primary_preferred_spec.rb +1 -1
  779. data/spec/mongo/server_selector/primary_spec.rb +1 -1
  780. data/spec/mongo/server_selector/secondary_preferred_spec.rb +1 -1
  781. data/spec/mongo/server_selector/secondary_spec.rb +1 -1
  782. data/spec/mongo/server_selector_spec.rb +1 -1
  783. data/spec/mongo/server_spec.rb +32 -5
  784. data/spec/mongo/session/server_session_spec.rb +1 -1
  785. data/spec/mongo/session/session_pool_spec.rb +1 -1
  786. data/spec/mongo/session_spec.rb +1 -1
  787. data/spec/mongo/session_transaction_spec.rb +2 -2
  788. data/spec/mongo/socket/ssl_spec.rb +3 -9
  789. data/spec/mongo/socket/tcp_spec.rb +1 -1
  790. data/spec/mongo/socket/unix_spec.rb +1 -1
  791. data/spec/mongo/socket_spec.rb +1 -1
  792. data/spec/mongo/srv/monitor_spec.rb +1 -1
  793. data/spec/mongo/srv/result_spec.rb +1 -1
  794. data/spec/mongo/timeout_spec.rb +1 -1
  795. data/spec/mongo/tls_context_hooks_spec.rb +1 -1
  796. data/spec/mongo/uri/options_mapper_spec.rb +1605 -0
  797. data/spec/mongo/uri/srv_protocol_spec.rb +150 -2
  798. data/spec/mongo/uri_option_parsing_spec.rb +1 -1
  799. data/spec/mongo/uri_spec.rb +143 -2
  800. data/spec/mongo/utils_spec.rb +1 -1
  801. data/spec/mongo/write_concern/acknowledged_spec.rb +1 -1
  802. data/spec/mongo/write_concern/unacknowledged_spec.rb +1 -1
  803. data/spec/mongo/write_concern_spec.rb +1 -1
  804. data/spec/runners/auth.rb +1 -1
  805. data/spec/runners/change_streams/outcome.rb +1 -1
  806. data/spec/runners/change_streams/spec.rb +1 -1
  807. data/spec/runners/change_streams/test.rb +1 -1
  808. data/spec/runners/cmap/verifier.rb +2 -2
  809. data/spec/runners/cmap.rb +188 -45
  810. data/spec/runners/command_monitoring.rb +1 -1
  811. data/spec/runners/connection_string.rb +1 -1
  812. data/spec/runners/crud/context.rb +1 -1
  813. data/spec/runners/crud/operation.rb +2 -2
  814. data/spec/runners/crud/outcome.rb +1 -1
  815. data/spec/runners/crud/requirement.rb +3 -3
  816. data/spec/runners/crud/spec.rb +2 -2
  817. data/spec/runners/crud/test.rb +1 -1
  818. data/spec/runners/crud/test_base.rb +2 -2
  819. data/spec/runners/crud/verifier.rb +3 -3
  820. data/spec/runners/crud.rb +1 -1
  821. data/spec/runners/gridfs.rb +1 -1
  822. data/spec/runners/read_write_concern_document.rb +1 -1
  823. data/spec/runners/sdam/verifier.rb +1 -1
  824. data/spec/runners/sdam.rb +1 -1
  825. data/spec/runners/server_selection.rb +1 -1
  826. data/spec/runners/server_selection_rtt.rb +1 -1
  827. data/spec/runners/transactions/operation.rb +15 -9
  828. data/spec/runners/transactions/spec.rb +1 -1
  829. data/spec/runners/transactions/test.rb +44 -3
  830. data/spec/runners/transactions.rb +1 -1
  831. data/spec/runners/unified/assertions.rb +94 -77
  832. data/spec/runners/unified/change_stream_operations.rb +14 -3
  833. data/spec/runners/unified/client_side_encryption_operations.rb +1 -1
  834. data/spec/runners/unified/crud_operations.rb +11 -2
  835. data/spec/runners/unified/ddl_operations.rb +80 -4
  836. data/spec/runners/unified/entity_map.rb +1 -1
  837. data/spec/runners/unified/error.rb +1 -1
  838. data/spec/runners/unified/event_subscriber.rb +9 -3
  839. data/spec/runners/unified/exceptions.rb +1 -1
  840. data/spec/runners/unified/grid_fs_operations.rb +1 -1
  841. data/spec/runners/unified/support_operations.rb +66 -2
  842. data/spec/runners/unified/test.rb +86 -12
  843. data/spec/runners/unified/test_group.rb +1 -1
  844. data/spec/runners/unified/thread_operations.rb +73 -0
  845. data/spec/runners/unified.rb +9 -6
  846. data/spec/shared/lib/mrss/docker_runner.rb +4 -0
  847. data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
  848. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  849. data/spec/shared/lib/mrss/utils.rb +28 -6
  850. data/spec/shared/share/Dockerfile.erb +24 -19
  851. data/spec/shared/shlib/server.sh +32 -8
  852. data/spec/shared/shlib/set_env.sh +4 -4
  853. data/spec/solo/clean_exit_spec.rb +4 -11
  854. data/spec/spec_helper.rb +1 -1
  855. data/spec/spec_tests/auth_spec.rb +1 -1
  856. data/spec/spec_tests/change_streams_unified_spec.rb +2 -1
  857. data/spec/spec_tests/client_side_encryption_spec.rb +25 -2
  858. data/spec/spec_tests/client_side_encryption_unified_spec.rb +12 -2
  859. data/spec/spec_tests/cmap_spec.rb +29 -15
  860. data/spec/spec_tests/collection_management_spec.rb +1 -1
  861. data/spec/spec_tests/command_monitoring_unified_spec.rb +1 -1
  862. data/spec/spec_tests/connection_string_spec.rb +1 -1
  863. data/spec/spec_tests/crud_spec.rb +1 -1
  864. data/spec/spec_tests/crud_unified_spec.rb +1 -1
  865. data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +41 -0
  866. data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +103 -0
  867. data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +2 -6
  868. data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
  869. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -3
  870. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -3
  871. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +15 -6
  872. data/spec/spec_tests/data/client_side_encryption/awsTemporary.yml +57 -0
  873. data/spec/spec_tests/data/client_side_encryption/{fle2-BypassQueryAnalysis.yml → fle2v2-BypassQueryAnalysis.yml} +18 -30
  874. data/spec/spec_tests/data/client_side_encryption/{fle2-Compact.yml → fle2v2-Compact.yml} +5 -3
  875. data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection-OldServer.yml +61 -0
  876. data/spec/spec_tests/data/client_side_encryption/{fle2-CreateCollection.yml → fle2v2-CreateCollection.yml} +212 -538
  877. data/spec/spec_tests/data/client_side_encryption/{fle2-DecryptExistingData.yml → fle2v2-DecryptExistingData.yml} +4 -2
  878. data/spec/spec_tests/data/client_side_encryption/{fle2-Delete.yml → fle2v2-Delete.yml} +17 -24
  879. data/spec/spec_tests/data/client_side_encryption/{fle2-EncryptedFields-vs-EncryptedFieldsMap.yml → fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml} +5 -6
  880. data/spec/spec_tests/data/client_side_encryption/{fle2-EncryptedFields-vs-jsonSchema.yml → fle2v2-EncryptedFields-vs-jsonSchema.yml} +18 -6
  881. data/spec/spec_tests/data/client_side_encryption/{fle2-EncryptedFieldsMap-defaults.yml → fle2v2-EncryptedFieldsMap-defaults.yml} +6 -5
  882. data/spec/spec_tests/data/client_side_encryption/{fle2-FindOneAndUpdate.yml → fle2v2-FindOneAndUpdate.yml} +31 -44
  883. data/spec/spec_tests/data/client_side_encryption/{fle2-InsertFind-Indexed.yml → fle2v2-InsertFind-Indexed.yml} +16 -6
  884. data/spec/spec_tests/data/client_side_encryption/{fle2-InsertFind-Unindexed.yml → fle2v2-InsertFind-Unindexed.yml} +10 -4
  885. data/spec/spec_tests/data/client_side_encryption/{fle2-MissingKey.yml → fle2v2-MissingKey.yml} +5 -3
  886. data/spec/spec_tests/data/client_side_encryption/{fle2-NoEncryption.yml → fle2v2-NoEncryption.yml} +4 -2
  887. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +241 -0
  888. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +422 -0
  889. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +182 -0
  890. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +239 -0
  891. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +235 -0
  892. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +252 -0
  893. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +1687 -0
  894. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +293 -0
  895. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +905 -0
  896. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +1684 -0
  897. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +1680 -0
  898. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +1697 -0
  899. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +329 -0
  900. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +424 -0
  901. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +226 -0
  902. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +327 -0
  903. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +319 -0
  904. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +336 -0
  905. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +913 -0
  906. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +292 -0
  907. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +518 -0
  908. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +911 -0
  909. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +907 -0
  910. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +924 -0
  911. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +325 -0
  912. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +424 -0
  913. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +224 -0
  914. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +323 -0
  915. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +319 -0
  916. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +338 -0
  917. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +241 -0
  918. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +423 -0
  919. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +182 -0
  920. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +239 -0
  921. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +235 -0
  922. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +254 -0
  923. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +241 -0
  924. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +422 -0
  925. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +182 -0
  926. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +239 -0
  927. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +235 -0
  928. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +254 -0
  929. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +43 -0
  930. data/spec/spec_tests/data/client_side_encryption/{fle2-Update.yml → fle2v2-Update.yml} +33 -44
  931. data/spec/spec_tests/data/client_side_encryption/{fle2-validatorAndPartialFieldExpression.yml → fle2v2-validatorAndPartialFieldExpression.yml} +10 -9
  932. data/spec/spec_tests/data/client_side_encryption/maxWireVersion.yml +1 -1
  933. data/spec/spec_tests/data/client_side_encryption/unified/createDataKey-kms_providers-invalid.yml +1 -1
  934. data/spec/spec_tests/data/cmap/connection-must-have-id.yml +2 -0
  935. data/spec/spec_tests/data/cmap/connection-must-order-ids.yml +2 -0
  936. data/spec/spec_tests/data/cmap/pool-checkin-destroy-closed.yml +2 -0
  937. data/spec/spec_tests/data/cmap/pool-checkin-destroy-stale.yml +2 -0
  938. data/spec/spec_tests/data/cmap/pool-checkin-make-available.yml +3 -1
  939. data/spec/spec_tests/data/cmap/pool-checkin.yml +5 -0
  940. data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +2 -0
  941. data/spec/spec_tests/data/cmap/pool-checkout-custom-maxConnecting-is-enforced.yml +50 -0
  942. data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +2 -0
  943. data/spec/spec_tests/data/cmap/pool-checkout-maxConnecting-is-enforced.yml +81 -0
  944. data/spec/spec_tests/data/cmap/pool-checkout-maxConnecting-timeout.yml +71 -0
  945. data/spec/spec_tests/data/cmap/pool-checkout-minPoolSize-connection-maxConnecting.yml +66 -0
  946. data/spec/spec_tests/data/cmap/pool-checkout-multiple.yml +2 -0
  947. data/spec/spec_tests/data/cmap/pool-checkout-no-idle.yml +6 -0
  948. data/spec/spec_tests/data/cmap/pool-checkout-no-stale.yml +8 -0
  949. data/spec/spec_tests/data/cmap/pool-checkout-returned-connection-maxConnecting.yml +88 -0
  950. data/spec/spec_tests/data/cmap/pool-clear-interrupt-immediately.yml +49 -0
  951. data/spec/spec_tests/data/cmap/pool-clear-interrupting-pending-connections.yml +43 -0
  952. data/spec/spec_tests/data/cmap/pool-clear-min-size.yml +41 -0
  953. data/spec/spec_tests/data/cmap/pool-clear-paused.yml +18 -0
  954. data/spec/spec_tests/data/cmap/pool-clear-ready.yml +39 -0
  955. data/spec/spec_tests/data/cmap/pool-clear-schedule-run-interruptInUseConnections-false.yml +48 -0
  956. data/spec/spec_tests/data/cmap/pool-close-destroy-conns.yml +2 -0
  957. data/spec/spec_tests/data/cmap/pool-create-max-size.yml +2 -0
  958. data/spec/spec_tests/data/cmap/pool-create-min-size-error.yml +43 -0
  959. data/spec/spec_tests/data/cmap/pool-create-min-size.yml +9 -0
  960. data/spec/spec_tests/data/cmap/pool-ready-ready.yml +22 -0
  961. data/spec/spec_tests/data/cmap/pool-ready.yml +30 -0
  962. data/spec/spec_tests/data/cmap/wait-queue-fairness.yml +2 -0
  963. data/spec/spec_tests/data/cmap/wait-queue-timeout.yml +6 -1
  964. data/spec/spec_tests/data/collection_management/modifyCollection-errorResponse.yml +59 -0
  965. data/spec/spec_tests/data/collection_management/timeseries-collection.yml +35 -0
  966. data/spec/spec_tests/data/command_monitoring_unified/redacted-commands.yml +8 -0
  967. data/spec/spec_tests/data/command_monitoring_unified/writeConcernError.yml +80 -0
  968. data/spec/spec_tests/data/crud_unified/aggregate-merge-errorResponse.yml +42 -0
  969. data/spec/spec_tests/data/crud_unified/bulkWrite-errorResponse.yml +50 -0
  970. data/spec/spec_tests/data/crud_unified/deleteOne-errorResponse.yml +46 -0
  971. data/spec/spec_tests/data/crud_unified/estimatedDocumentCount.yml +44 -0
  972. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-errorResponse.yml +69 -0
  973. data/spec/spec_tests/data/crud_unified/insertOne-errorResponse.yml +46 -0
  974. data/spec/spec_tests/data/crud_unified/updateOne-errorResponse.yml +47 -0
  975. data/spec/spec_tests/data/retryable_reads/unified/handshakeError.yml +1266 -53
  976. data/spec/spec_tests/data/retryable_writes/unified/bulkWrite-serverErrors.yml +1 -1
  977. data/spec/spec_tests/data/retryable_writes/unified/handshakeError.yml +706 -58
  978. data/spec/spec_tests/data/retryable_writes/unified/insertOne-noWritesPerformedError.yml +54 -0
  979. data/spec/spec_tests/data/retryable_writes/unified/insertOne-serverErrors.yml +1 -1
  980. data/spec/spec_tests/data/sdam/rs/electionId_precedence_setVersion.yml +62 -0
  981. data/spec/spec_tests/data/sdam/rs/null_election_id-pre-6.0.yml +175 -0
  982. data/spec/spec_tests/data/sdam/rs/null_election_id.yml +20 -18
  983. data/spec/spec_tests/data/sdam/rs/secondary_ignore_ok_0-pre-6.0.yml +87 -0
  984. data/spec/spec_tests/data/sdam/rs/secondary_ignore_ok_0.yml +1 -1
  985. data/spec/spec_tests/data/sdam/rs/set_version_can_rollback.yml +101 -0
  986. data/spec/spec_tests/data/sdam/rs/setversion_equal_max_without_electionid.yml +78 -0
  987. data/spec/spec_tests/data/sdam/rs/setversion_greaterthan_max_without_electionid.yml +79 -0
  988. data/spec/spec_tests/data/sdam/rs/setversion_without_electionid-pre-6.0.yml +79 -0
  989. data/spec/spec_tests/data/sdam/rs/setversion_without_electionid.yml +9 -10
  990. data/spec/spec_tests/data/sdam/rs/use_setversion_without_electionid-pre-6.0.yml +117 -0
  991. data/spec/spec_tests/data/sdam/rs/use_setversion_without_electionid.yml +23 -21
  992. data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +1 -1
  993. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_no_primary.yml +38 -39
  994. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary.yml +38 -39
  995. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_removal.yml +1 -1
  996. data/spec/spec_tests/data/sdam_monitoring/required_replica_set.yml +1 -1
  997. data/spec/spec_tests/data/sdam_monitoring/standalone.yml +1 -1
  998. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +2 -2
  999. data/spec/spec_tests/data/sdam_unified/auth-error.yml +130 -0
  1000. data/spec/spec_tests/data/sdam_unified/auth-misc-command-error.yml +132 -0
  1001. data/spec/spec_tests/data/sdam_unified/auth-network-error.yml +132 -0
  1002. data/spec/spec_tests/data/sdam_unified/auth-network-timeout-error.yml +138 -0
  1003. data/spec/spec_tests/data/sdam_unified/auth-shutdown-error.yml +133 -0
  1004. data/spec/spec_tests/data/sdam_unified/cancel-server-check.yml +143 -0
  1005. data/spec/spec_tests/data/sdam_unified/connectTimeoutMS.yml +130 -0
  1006. data/spec/spec_tests/data/sdam_unified/find-network-error.yml +135 -0
  1007. data/spec/spec_tests/data/sdam_unified/find-network-timeout-error.yml +119 -0
  1008. data/spec/spec_tests/data/sdam_unified/find-shutdown-error.yml +163 -0
  1009. data/spec/spec_tests/data/sdam_unified/hello-command-error.yml +233 -0
  1010. data/spec/spec_tests/data/sdam_unified/hello-network-error.yml +228 -0
  1011. data/spec/spec_tests/data/sdam_unified/hello-timeout.yml +318 -0
  1012. data/spec/spec_tests/data/sdam_unified/insert-network-error.yml +137 -0
  1013. data/spec/spec_tests/data/sdam_unified/insert-shutdown-error.yml +162 -0
  1014. data/spec/spec_tests/data/sdam_unified/interruptInUse-pool-clear.yml +340 -0
  1015. data/spec/spec_tests/data/sdam_unified/minPoolSize-error.yml +125 -0
  1016. data/spec/spec_tests/data/sdam_unified/pool-cleared-error.yml +239 -0
  1017. data/spec/spec_tests/data/sdam_unified/rediscover-quickly-after-step-down.yml +144 -0
  1018. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-directConnection.yml +6 -5
  1019. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-replicaSet-errors.yml +2 -2
  1020. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-txt.yml +5 -4
  1021. data/spec/spec_tests/data/seed_list_discovery/load-balanced/srvMaxHosts-conflicts_with_loadBalanced-true-txt.yml +1 -1
  1022. data/spec/spec_tests/data/seed_list_discovery/load-balanced/srvMaxHosts-zero-txt.yml +4 -3
  1023. data/spec/spec_tests/data/seed_list_discovery/load-balanced/srvMaxHosts-zero.yml +4 -3
  1024. data/spec/spec_tests/data/sessions_unified/implicit-sessions-default-causal-consistency.yml +119 -0
  1025. data/spec/spec_tests/data/sessions_unified/snapshot-sessions-unsupported-ops.yml +1 -1
  1026. data/spec/spec_tests/data/sessions_unified/snapshot-sessions.yml +1 -1
  1027. data/spec/spec_tests/data/transactions_unified/mongos-unpin.yml +1 -1
  1028. data/spec/spec_tests/data/unified/valid-fail/entity-findCursor-malformed.yml +31 -0
  1029. data/spec/spec_tests/data/unified/valid-fail/entity-findCursor.yml +31 -0
  1030. data/spec/spec_tests/data/unified/valid-fail/ignoreResultAndError-malformed.yml +34 -0
  1031. data/spec/spec_tests/data/unified/valid-fail/ignoreResultAndError.yml +35 -0
  1032. data/spec/spec_tests/data/unified/valid-pass/assertNumberConnectionsCheckedOut.yml +17 -0
  1033. data/spec/spec_tests/data/unified/valid-pass/entity-client-cmap-events.yml +40 -0
  1034. data/spec/spec_tests/data/unified/valid-pass/entity-client-storeEventsAsEntities.yml +37 -0
  1035. data/spec/spec_tests/data/unified/valid-pass/expectedError-errorResponse.yml +39 -0
  1036. data/spec/spec_tests/data/unified/valid-pass/expectedEventsForClient-eventType.yml +66 -0
  1037. data/spec/spec_tests/data/unified/valid-pass/ignoreResultAndError.yml +34 -0
  1038. data/spec/spec_tests/data/unified/valid-pass/observeSensitiveCommands.yml +255 -0
  1039. data/spec/spec_tests/data/unified/valid-pass/poc-change-streams.yml +18 -0
  1040. data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +18 -12
  1041. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-reads.yml +3 -3
  1042. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +2 -2
  1043. data/spec/spec_tests/data/versioned_api/crud-api-version-1-strict.yml +1 -1
  1044. data/spec/spec_tests/data/versioned_api/crud-api-version-1.yml +1 -1
  1045. data/spec/spec_tests/data/versioned_api/transaction-handling.yml +4 -4
  1046. data/spec/spec_tests/gridfs_spec.rb +1 -1
  1047. data/spec/spec_tests/gridfs_unified_spec.rb +1 -1
  1048. data/spec/spec_tests/load_balancers_spec.rb +1 -1
  1049. data/spec/spec_tests/max_staleness_spec.rb +1 -1
  1050. data/spec/spec_tests/read_write_concern_connection_string_spec.rb +1 -1
  1051. data/spec/spec_tests/read_write_concern_document_spec.rb +1 -1
  1052. data/spec/spec_tests/read_write_concern_operaton_spec.rb +1 -1
  1053. data/spec/spec_tests/retryable_reads_spec.rb +3 -1
  1054. data/spec/spec_tests/retryable_reads_unified_spec.rb +1 -1
  1055. data/spec/spec_tests/retryable_writes_spec.rb +1 -1
  1056. data/spec/spec_tests/retryable_writes_unified_spec.rb +1 -1
  1057. data/spec/spec_tests/sdam_monitoring_spec.rb +1 -1
  1058. data/spec/spec_tests/sdam_spec.rb +5 -1
  1059. data/spec/spec_tests/sdam_unified_spec.rb +13 -0
  1060. data/spec/spec_tests/seed_list_discovery_spec.rb +1 -1
  1061. data/spec/spec_tests/server_selection_rtt_spec.rb +1 -1
  1062. data/spec/spec_tests/server_selection_spec.rb +1 -1
  1063. data/spec/spec_tests/sessions_unified_spec.rb +1 -1
  1064. data/spec/spec_tests/transactions_api_spec.rb +1 -1
  1065. data/spec/spec_tests/transactions_spec.rb +1 -1
  1066. data/spec/spec_tests/transactions_unified_spec.rb +1 -1
  1067. data/spec/spec_tests/unified_spec.rb +1 -6
  1068. data/spec/spec_tests/uri_options_spec.rb +1 -1
  1069. data/spec/spec_tests/versioned_api_spec.rb +1 -1
  1070. data/spec/stress/cleanup_spec.rb +1 -1
  1071. data/spec/stress/connection_pool_stress_spec.rb +1 -62
  1072. data/spec/stress/connection_pool_timing_spec.rb +9 -34
  1073. data/spec/stress/fork_reconnect_stress_spec.rb +7 -8
  1074. data/spec/stress/push_monitor_close_spec.rb +1 -1
  1075. data/spec/support/authorization.rb +1 -1
  1076. data/spec/support/aws_utils/base.rb +1 -1
  1077. data/spec/support/aws_utils/inspector.rb +1 -1
  1078. data/spec/support/aws_utils/orchestrator.rb +20 -8
  1079. data/spec/support/aws_utils/provisioner.rb +1 -1
  1080. data/spec/support/aws_utils.rb +4 -3
  1081. data/spec/support/background_thread_registry.rb +1 -1
  1082. data/spec/support/certificates/atlas-ocsp-ca.crt +67 -67
  1083. data/spec/support/certificates/atlas-ocsp.crt +103 -103
  1084. data/spec/support/certificates/retrieve-atlas-cert +2 -0
  1085. data/spec/support/client_registry.rb +6 -2
  1086. data/spec/support/client_registry_macros.rb +1 -1
  1087. data/spec/support/cluster_tools.rb +13 -8
  1088. data/spec/support/common_shortcuts.rb +30 -5
  1089. data/spec/support/constraints.rb +15 -1
  1090. data/spec/support/crypt/{encryptedFields.json → encrypted_fields/encryptedFields.json} +0 -1
  1091. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +30 -0
  1092. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +21 -0
  1093. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +29 -0
  1094. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +21 -0
  1095. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +30 -0
  1096. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +27 -0
  1097. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +27 -0
  1098. data/spec/support/crypt.rb +13 -3
  1099. data/spec/support/dns.rb +1 -1
  1100. data/spec/support/json_ext_formatter.rb +1 -1
  1101. data/spec/support/keyword_struct.rb +1 -1
  1102. data/spec/support/local_resource_registry.rb +1 -1
  1103. data/spec/support/macros.rb +1 -0
  1104. data/spec/support/matchers.rb +5 -5
  1105. data/spec/support/mongos_macros.rb +7 -0
  1106. data/spec/support/monitoring_ext.rb +1 -1
  1107. data/spec/support/primary_socket.rb +1 -1
  1108. data/spec/support/sdam_formatter_integration.rb +1 -1
  1109. data/spec/support/shared/app_metadata.rb +15 -3
  1110. data/spec/support/shared/auth_context.rb +1 -0
  1111. data/spec/support/shared/protocol.rb +1 -1
  1112. data/spec/support/shared/scram_conversation.rb +1 -1
  1113. data/spec/support/shared/server_selector.rb +1 -1
  1114. data/spec/support/shared/session.rb +1 -1
  1115. data/spec/support/spec_config.rb +40 -3
  1116. data/spec/support/spec_setup.rb +1 -1
  1117. data/spec/support/using_hash.rb +11 -2
  1118. data/spec/support/utils.rb +277 -249
  1119. data.tar.gz.sig +0 -0
  1120. metadata +1456 -1173
  1121. metadata.gz.sig +0 -0
  1122. data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +0 -96
  1123. data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +0 -88
  1124. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +0 -85
  1125. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +0 -118
  1126. data/spec/spec_tests/data/sdam_integration/hello-command-error.yml +0 -152
  1127. data/spec/spec_tests/data/sdam_integration/hello-network-error.yml +0 -148
  1128. data/spec/spec_tests/data/sdam_integration/hello-timeout.yml +0 -219
  1129. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +0 -88
  1130. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +0 -117
  1131. data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +0 -98
  1132. data/spec/spec_tests/data/unified/invalid/expectedEventsForClient-ignoreExtraEvents-type.yml +0 -15
  1133. data/spec/spec_tests/sdam_integration_spec.rb +0 -16
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # encoding: utf-8
2
+ # rubocop:todo all
3
3
 
4
4
  # Copyright (C) 2014-2020 MongoDB Inc.
5
5
  #
@@ -75,6 +75,15 @@ module Mongo
75
75
  # are given, their values must be identical.
76
76
  # @option options [ Float ] :max_idle_time The time, in seconds,
77
77
  # after which idle connections should be closed by the pool.
78
+ # @option options [ true, false ] :populator_io For internal driver
79
+ # use only. Set to false to prevent the populator threads from being
80
+ # created and started in the server's connection pool. It is intended
81
+ # for use in tests that also turn off monitoring_io, unless the populator
82
+ # is explicitly needed. If monitoring_io is off, but the populator_io
83
+ # is on, the populator needs to be manually closed at the end of the
84
+ # test, since a cluster without monitoring is considered not connected,
85
+ # and thus will not clean up the connection pool populator threads on
86
+ # close.
78
87
  # Note: Additionally, options for connections created by this pool should
79
88
  # be included in the options passed here, and they will be forwarded to
80
89
  # any connections created by the pool.
@@ -112,6 +121,7 @@ module Mongo
112
121
  @options = options.freeze
113
122
 
114
123
  @generation_manager = GenerationManager.new(server: server)
124
+ @ready = false
115
125
  @closed = false
116
126
 
117
127
  # A connection owned by this pool should be either in the
@@ -120,6 +130,7 @@ module Mongo
120
130
  @available_connections = available_connections = []
121
131
  @checked_out_connections = Set.new
122
132
  @pending_connections = Set.new
133
+ @interrupt_connections = []
123
134
 
124
135
  # Mutex used for synchronizing access to @available_connections and
125
136
  # @checked_out_connections. The pool object is thread-safe, thus
@@ -127,30 +138,42 @@ module Mongo
127
138
  # must do so under this lock.
128
139
  @lock = Mutex.new
129
140
 
130
- # Condition variable broadcast when a connection is added to
131
- # @available_connections, to wake up any threads waiting for an
132
- # available connection when pool is at max size
133
- @available_semaphore = Semaphore.new
134
-
135
141
  # Background thread reponsible for maintaining the size of
136
142
  # the pool to at least min_size
137
143
  @populator = Populator.new(self, options)
138
144
  @populate_semaphore = Semaphore.new
139
145
 
146
+ # Condition variable to enforce the first check in check_out: max_pool_size.
147
+ # This condition variable should be signaled when the number of
148
+ # unavailable connections decreases (pending + pending_connections +
149
+ # available_connections).
150
+ @size_cv = Mongo::ConditionVariable.new(@lock)
151
+ # This represents the number of threads that have made it past the size_cv
152
+ # gate but have not acquired a connection to add to the pending_connections
153
+ # set.
154
+ @connection_requests = 0
155
+
156
+ # Condition variable to enforce the second check in check_out: max_connecting.
157
+ # Thei condition variable should be signaled when the number of pending
158
+ # connections decreases.
159
+ @max_connecting_cv = Mongo::ConditionVariable.new(@lock)
160
+ @max_connecting = options.fetch(:max_connecting, 2)
161
+
140
162
  ObjectSpace.define_finalizer(self, self.class.finalize(@available_connections, @pending_connections, @populator))
141
163
 
142
164
  publish_cmap_event(
143
165
  Monitoring::Event::Cmap::PoolCreated.new(@server.address, options, self)
144
166
  )
145
-
146
- @populator.run! if min_size > 0
147
167
  end
148
168
 
149
169
  # @return [ Hash ] options The pool options.
150
170
  attr_reader :options
151
171
 
152
172
  # @api private
153
- def_delegators :@server, :address
173
+ attr_reader :server
174
+
175
+ # @api private
176
+ def_delegators :server, :address
154
177
 
155
178
  # Get the maximum size of the connection pool.
156
179
  #
@@ -196,7 +219,20 @@ module Mongo
196
219
  # being used by the queue.
197
220
  #
198
221
  # @api private
199
- def_delegator :generation_manager, :generation
222
+ def_delegators :generation_manager, :generation, :generation_unlocked
223
+
224
+ # A connection pool is paused if it is not closed and it is not ready.
225
+ #
226
+ # @return [ true | false ] whether the connection pool is paused.
227
+ #
228
+ # @raise [ Error::PoolClosedError ] If the pool has been closed.
229
+ def paused?
230
+ raise_if_closed!
231
+
232
+ @lock.synchronize do
233
+ !@ready
234
+ end
235
+ end
200
236
 
201
237
  # Size of the connection pool.
202
238
  #
@@ -222,6 +258,14 @@ module Mongo
222
258
  end
223
259
  private :unsynchronized_size
224
260
 
261
+ # @return [ Integer ] The number of unavailable connections in the pool.
262
+ # Used to calculate whether we have hit max_pool_size.
263
+ #
264
+ # @api private
265
+ def unavailable_connections
266
+ @checked_out_connections.length + @pending_connections.length + @connection_requests
267
+ end
268
+
225
269
  # Number of available connections in the pool.
226
270
  #
227
271
  # @return [ Integer ] Number of available connections.
@@ -244,14 +288,30 @@ module Mongo
244
288
  !!@closed
245
289
  end
246
290
 
291
+ # Whether the pool is ready.
292
+ #
293
+ # @return [ true | false ] Whether the pool is ready.
294
+ def ready?
295
+ @lock.synchronize do
296
+ @ready
297
+ end
298
+ end
299
+
247
300
  # @note This method is experimental and subject to change.
248
301
  #
249
302
  # @api experimental
250
303
  # @since 2.11.0
251
304
  def summary
252
305
  @lock.synchronize do
306
+ state = if closed?
307
+ 'closed'
308
+ elsif !@ready
309
+ 'paused'
310
+ else
311
+ 'ready'
312
+ end
253
313
  "#<ConnectionPool size=#{unsynchronized_size} (#{min_size}-#{max_size}) " +
254
- "used=#{@checked_out_connections.length} avail=#{@available_connections.length} pending=#{@pending_connections.length}>"
314
+ "used=#{@checked_out_connections.length} avail=#{@available_connections.length} pending=#{@pending_connections.length} #{state}>"
255
315
  end
256
316
  end
257
317
 
@@ -261,6 +321,9 @@ module Mongo
261
321
  # @api private
262
322
  attr_reader :populator
263
323
 
324
+ # @api private
325
+ attr_reader :max_connecting
326
+
264
327
  # Checks a connection out of the pool.
265
328
  #
266
329
  # If there are active connections in the pool, the most recently used
@@ -286,157 +349,10 @@ module Mongo
286
349
  Monitoring::Event::Cmap::ConnectionCheckOutStarted.new(@server.address)
287
350
  )
288
351
 
289
- if closed?
290
- publish_cmap_event(
291
- Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
292
- @server.address,
293
- Monitoring::Event::Cmap::ConnectionCheckOutFailed::POOL_CLOSED
294
- ),
295
- )
296
- raise Error::PoolClosedError.new(@server.address, self)
297
- end
298
-
299
- deadline = Utils.monotonic_time + wait_timeout
300
- pid = Process.pid
301
- connection = nil
302
- # It seems that synchronize sets up its own loop, thus a simple break
303
- # is insufficient to break the outer loop
304
- catch(:done) do
305
- loop do
306
- # Lock must be taken on each iteration, rather for the method
307
- # overall, otherwise other threads will not be able to check in
308
- # a connection while this thread is waiting for one.
309
- @lock.synchronize do
310
- until @available_connections.empty?
311
- connection = next_available_connection(
312
- connection_global_id: connection_global_id
313
- )
314
-
315
- if connection.nil?
316
- if connection_global_id
317
- # A particular connection is requested, but it is not available.
318
- # If it is nether available not checked out, we should stop here.
319
- @checked_out_connections.detect do |conn|
320
- conn.connection_global_id == connection_global_id
321
- end.tap do |conn|
322
- if conn.nil?
323
- publish_cmap_event(
324
- Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
325
- @server.address,
326
- Monitoring::Event::Cmap::ConnectionCheckOutFailed::CONNECTION_ERROR
327
- ),
328
- )
329
- raise Error::MissingConnection.new
330
- end
331
- end
332
- else
333
- break
334
- end
335
- end
336
-
337
- if connection.pid != pid
338
- log_warn("Detected PID change - Mongo client should have been reconnected (old pid #{connection.pid}, new pid #{pid}")
339
- connection.disconnect!(reason: :stale)
340
- @populate_semaphore.signal
341
- next
342
- end
343
-
344
- if !connection.pinned?
345
- # If connection is marked as pinned, it is used by a transaction
346
- # or a series of cursor operations in a load balanced setup.
347
- # In this case connection should not be disconnected until
348
- # unpinned.
349
- if connection.generation != generation(
350
- service_id: connection.service_id
351
- )
352
- # Stale connections should be disconnected in the clear
353
- # method, but if any don't, check again here
354
- connection.disconnect!(reason: :stale)
355
- @populate_semaphore.signal
356
- next
357
- end
358
-
359
- if max_idle_time && connection.last_checkin &&
360
- Time.now - connection.last_checkin > max_idle_time
361
- then
362
- connection.disconnect!(reason: :idle)
363
- @populate_semaphore.signal
364
- next
365
- end
366
- end
367
-
368
- @pending_connections << connection
369
- throw(:done)
370
- end
371
-
372
- if @server.load_balancer? && connection_global_id
373
- # We need a particular connection, and if it is not available
374
- # we can wait for an in-progress operation to return
375
- # such a connection to the pool.
376
- else
377
- # If we are below pool capacity, create a new connection.
378
- #
379
- # Ruby does not allow a thread to lock a mutex which it already
380
- # holds.
381
- if max_size == 0 || unsynchronized_size < max_size
382
- connection = create_connection
383
- @pending_connections << connection
384
- throw(:done)
385
- end
386
- end
387
- end
388
-
389
- wait = deadline - Utils.monotonic_time
390
- if wait <= 0
391
- publish_cmap_event(
392
- Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
393
- @server.address,
394
- Monitoring::Event::Cmap::ConnectionCheckOutFailed::TIMEOUT,
395
- ),
396
- )
397
-
398
- msg = @lock.synchronize do
399
- connection_global_id_msg = if connection_global_id
400
- " for connection #{connection_global_id}"
401
- else
402
- ''
403
- end
404
-
405
- "Timed out attempting to check out a connection " +
406
- "from pool for #{@server.address}#{connection_global_id_msg} after #{wait_timeout} sec. " +
407
- "Connections in pool: #{@available_connections.length} available, " +
408
- "#{@checked_out_connections.length} checked out, " +
409
- "#{@pending_connections.length} pending " +
410
- "(max size: #{max_size})"
411
- end
412
- raise Error::ConnectionCheckOutTimeout.new(msg, address: @server.address)
413
- end
414
- @available_semaphore.wait(wait)
415
- end
416
- end
417
-
418
- begin
419
- connect_connection(connection)
420
- rescue Exception
421
- # Handshake or authentication failed
422
- @lock.synchronize do
423
- @pending_connections.delete(connection)
424
- end
425
- @populate_semaphore.signal
426
-
427
- publish_cmap_event(
428
- Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
429
- @server.address,
430
- Monitoring::Event::Cmap::ConnectionCheckOutFailed::CONNECTION_ERROR
431
- ),
432
- )
433
- raise
434
- end
352
+ raise_if_pool_closed!
353
+ raise_if_pool_paused_locked!
435
354
 
436
- @lock.synchronize do
437
- @checked_out_connections << connection
438
- @pending_connections.delete(connection)
439
- end
355
+ connection = retrieve_and_connect_connection(connection_global_id)
440
356
 
441
357
  publish_cmap_event(
442
358
  Monitoring::Event::Cmap::ConnectionCheckedOut.new(@server.address, connection.id, self),
@@ -464,69 +380,114 @@ module Mongo
464
380
  check_invariants
465
381
 
466
382
  @lock.synchronize do
467
- unless connection.connection_pool == self
468
- raise ArgumentError, "Trying to check in a connection which was not checked out by this pool: #{connection} checked out from pool #{connection.connection_pool} (for #{self})"
469
- end
383
+ do_check_in(connection)
384
+ end
385
+ ensure
386
+ check_invariants
387
+ end
470
388
 
471
- unless @checked_out_connections.include?(connection)
472
- raise ArgumentError, "Trying to check in a connection which is not currently checked out by this pool: #{connection} (for #{self})"
473
- end
389
+ # Executes the check in after having already acquired the lock.
390
+ #
391
+ # @param [ Mongo::Server::Connection ] connection The connection.
392
+ def do_check_in(connection)
393
+ # When a connection is interrupted it is checked back into the pool
394
+ # and closed. The operation that was using the connection before it was
395
+ # interrupted will attempt to check it back into the pool, and we
396
+ # should ignore it since its already been closed and removed from the pool.
397
+ return if connection.closed? && connection.interrupted?
398
+
399
+ unless connection.connection_pool == self
400
+ raise ArgumentError, "Trying to check in a connection which was not checked out by this pool: #{connection} checked out from pool #{connection.connection_pool} (for #{self})"
401
+ end
402
+
403
+ unless @checked_out_connections.include?(connection)
404
+ raise ArgumentError, "Trying to check in a connection which is not currently checked out by this pool: #{connection} (for #{self})"
405
+ end
474
406
 
475
- # Note: if an event handler raises, resource will not be signaled.
476
- # This means threads waiting for a connection to free up when
477
- # the pool is at max size may time out.
478
- # Threads that begin waiting after this method completes (with
479
- # the exception) should be fine.
407
+ # Note: if an event handler raises, resource will not be signaled.
408
+ # This means threads waiting for a connection to free up when
409
+ # the pool is at max size may time out.
410
+ # Threads that begin waiting after this method completes (with
411
+ # the exception) should be fine.
480
412
 
481
- @checked_out_connections.delete(connection)
482
- publish_cmap_event(
483
- Monitoring::Event::Cmap::ConnectionCheckedIn.new(@server.address, connection.id, self)
484
- )
413
+ @checked_out_connections.delete(connection)
414
+ @size_cv.signal
485
415
 
486
- if connection.error?
487
- connection.disconnect!(reason: :error)
488
- return
489
- end
416
+ publish_cmap_event(
417
+ Monitoring::Event::Cmap::ConnectionCheckedIn.new(@server.address, connection.id, self)
418
+ )
490
419
 
491
- if closed?
492
- connection.disconnect!(reason: :pool_closed)
493
- return
494
- end
420
+ if connection.interrupted?
421
+ connection.disconnect!(reason: :stale)
422
+ return
423
+ end
495
424
 
496
- if connection.closed?
497
- # Connection was closed - for example, because it experienced
498
- # a network error. Nothing else needs to be done here.
499
- @populate_semaphore.signal
500
- elsif connection.generation != generation(service_id: connection.service_id) && !connection.pinned?
501
- # If connection is marked as pinned, it is used by a transaction
502
- # or a series of cursor operations in a load balanced setup.
503
- # In this case connection should not be disconnected until
504
- # unpinned.
505
- connection.disconnect!(reason: :stale)
506
- @populate_semaphore.signal
507
- else
508
- connection.record_checkin!
509
- @available_connections << connection
425
+ if connection.error?
426
+ connection.disconnect!(reason: :error)
427
+ return
428
+ end
510
429
 
511
- # Wake up only one thread waiting for an available connection,
512
- # since only one connection was checked in.
513
- @available_semaphore.signal
514
- end
430
+ if closed?
431
+ connection.disconnect!(reason: :pool_closed)
432
+ return
433
+ end
434
+
435
+ if connection.closed?
436
+ # Connection was closed - for example, because it experienced
437
+ # a network error. Nothing else needs to be done here.
438
+ @populate_semaphore.signal
439
+ elsif connection.generation != generation(service_id: connection.service_id) && !connection.pinned?
440
+ # If connection is marked as pinned, it is used by a transaction
441
+ # or a series of cursor operations in a load balanced setup.
442
+ # In this case connection should not be disconnected until
443
+ # unpinned.
444
+ connection.disconnect!(reason: :stale)
445
+ @populate_semaphore.signal
446
+ else
447
+ connection.record_checkin!
448
+ @available_connections << connection
449
+
450
+ @max_connecting_cv.signal
451
+ end
452
+ end
453
+
454
+ # Mark the connection pool as paused.
455
+ def pause
456
+ raise_if_closed!
457
+
458
+ check_invariants
459
+
460
+ @lock.synchronize do
461
+ do_pause
515
462
  end
516
463
  ensure
517
464
  check_invariants
518
465
  end
519
466
 
467
+ # Mark the connection pool as paused without acquiring the lock.
468
+ #
469
+ # @api private
470
+ def do_pause
471
+ if Lint.enabled? && !@server.unknown?
472
+ raise Error::LintError, "Attempting to pause pool for server #{@server.summary} which is known"
473
+ end
474
+
475
+ return if !@ready
476
+
477
+ @ready = false
478
+ end
479
+
520
480
  # Closes all idle connections in the pool and schedules currently checked
521
481
  # out connections to be closed when they are checked back into the pool.
522
- # The pool remains operational and can create new connections when
523
- # requested.
482
+ # The pool is paused, it will not create new connections in background
483
+ # and it will fail checkout requests until marked ready.
524
484
  #
525
485
  # @option options [ true | false ] :lazy If true, do not close any of
526
486
  # the idle connections and instead let them be closed during a
527
- # subsequent check out operation.
528
- # @option options [ true | false ] :stop_populator Whether to stop
529
- # the populator background thread. For internal driver use only.
487
+ # subsequent check out operation. Defaults to false.
488
+ # @option options [ true | false ] :interrupt_in_use_connections If true,
489
+ # close all checked out connections immediately. If it is false, do not
490
+ # close any of the checked out connections. Defaults to true.
530
491
  # @option options [ Object ] :service_id Clear connections with
531
492
  # the specified service id only.
532
493
  #
@@ -536,56 +497,112 @@ module Mongo
536
497
  def clear(options = nil)
537
498
  raise_if_closed!
538
499
 
539
- check_invariants
540
-
541
- if options && options[:stop_populator]
542
- stop_populator
500
+ if Lint.enabled? && !@server.unknown?
501
+ raise Error::LintError, "Attempting to clear pool for server #{@server.summary} which is known"
543
502
  end
544
503
 
504
+ do_clear(options)
505
+ end
506
+
507
+ # Disconnects the pool.
508
+ #
509
+ # Does everything that +clear+ does, except if the pool is closed
510
+ # this method does nothing but +clear+ would raise PoolClosedError.
511
+ #
512
+ # @since 2.1.0
513
+ # @api private
514
+ def disconnect!(options = nil)
515
+ do_clear(options)
516
+ rescue Error::PoolClosedError
517
+ # The "disconnected" state is between closed and paused.
518
+ # When we are trying to disconnect the pool, permit the pool to be
519
+ # already closed.
520
+ end
521
+
522
+ def do_clear(options = nil)
523
+ check_invariants
524
+
545
525
  service_id = options && options[:service_id]
546
526
 
547
527
  @lock.synchronize do
528
+ # Generation must be bumped before emitting pool cleared event.
548
529
  @generation_manager.bump(service_id: service_id)
549
530
 
550
- publish_cmap_event(
551
- Monitoring::Event::Cmap::PoolCleared.new(
552
- @server.address,
553
- service_id: service_id
554
- )
555
- )
556
-
557
531
  unless options && options[:lazy]
558
- if @server.load_balancer? && service_id
559
- loop do
560
- conn = @available_connections.detect do |conn|
561
- conn.service_id == service_id
562
- end
563
- if conn
564
- @available_connections.delete(conn)
565
- conn.disconnect!(reason: :stale)
566
- @populate_semaphore.signal
567
- else
568
- break
569
- end
570
- end
571
- else
572
- until @available_connections.empty?
573
- connection = @available_connections.pop
574
- connection.disconnect!(reason: :stale)
575
- @populate_semaphore.signal
576
- end
577
- end
532
+ close_available_connections(service_id)
533
+ end
534
+
535
+ if options && options[:interrupt_in_use_connections]
536
+ schedule_for_interruption(@checked_out_connections, service_id)
537
+ schedule_for_interruption(@pending_connections, service_id)
538
+ end
539
+
540
+ if @ready
541
+ publish_cmap_event(
542
+ Monitoring::Event::Cmap::PoolCleared.new(
543
+ @server.address,
544
+ service_id: service_id,
545
+ interrupt_in_use_connections: options&.[](:interrupt_in_use_connections)
546
+ )
547
+ )
548
+ # Only pause the connection pool if the server was marked unknown,
549
+ # otherwise, allow the retry to be attempted with a ready pool.
550
+ do_pause if !@server.load_balancer? && @server.unknown?
578
551
  end
552
+
553
+ # Broadcast here to cause all of the threads waiting on the max
554
+ # connecting to break out of the wait loop and error.
555
+ @max_connecting_cv.broadcast
556
+ # Broadcast here to cause all of the threads waiting on the pool size
557
+ # to break out of the wait loop and error.
558
+ @size_cv.broadcast
579
559
  end
580
560
 
561
+ # "Schedule the background thread" after clearing. This is responsible
562
+ # for cleaning up stale threads, and interrupting in use connections.
563
+ @populate_semaphore.signal
581
564
  true
582
565
  ensure
583
566
  check_invariants
584
567
  end
585
568
 
586
- # @since 2.1.0
587
- # @deprecated
588
- alias :disconnect! :clear
569
+ # Instructs the pool to create and return connections.
570
+ def ready
571
+ raise_if_closed!
572
+
573
+ # TODO: Add this back in RUBY-3174.
574
+ # if Lint.enabled?
575
+ # unless @server.connected?
576
+ # raise Error::LintError, "Attempting to ready a pool for server #{@server.summary} which is disconnected"
577
+ # end
578
+ # end
579
+
580
+ @lock.synchronize do
581
+ return if @ready
582
+
583
+ @ready = true
584
+ end
585
+
586
+ # Note that the CMAP spec demands serialization of CMAP events for a
587
+ # pool. In order to implement this, event publication must be done into
588
+ # a queue which is synchronized, instead of subscribers being invoked
589
+ # from the trigger method like this one here inline. On MRI, assuming
590
+ # the threads yield to others when they stop having work to do, it is
591
+ # likely that the events would in practice always be published in the
592
+ # required order. JRuby, being truly concurrent with OS threads,
593
+ # would not offers such a guarantee.
594
+ publish_cmap_event(
595
+ Monitoring::Event::Cmap::PoolReady.new(@server.address, options, self)
596
+ )
597
+
598
+ if options.fetch(:populator_io, true)
599
+ if @populator.running?
600
+ @populate_semaphore.signal
601
+ else
602
+ @populator.run!
603
+ end
604
+ end
605
+ end
589
606
 
590
607
  # Marks the pool closed, closes all idle connections in the pool and
591
608
  # schedules currently checked out connections to be closed when they are
@@ -595,6 +612,8 @@ module Mongo
595
612
  #
596
613
  # @option options [ true | false ] :force Also close all checked out
597
614
  # connections.
615
+ # @option options [ true | false ] :stay_ready For internal driver use
616
+ # only. Whether or not to mark the pool as closed.
598
617
  #
599
618
  # @return [ true ] Always true.
600
619
  #
@@ -620,9 +639,15 @@ module Mongo
620
639
  end
621
640
  end
622
641
 
623
- # mark pool as closed before releasing lock so
624
- # no connections can be created, checked in, or checked out
625
- @closed = true
642
+ unless options && options[:stay_ready]
643
+ # mark pool as closed before releasing lock so
644
+ # no connections can be created, checked in, or checked out
645
+ @closed = true
646
+ @ready = false
647
+ end
648
+
649
+ @max_connecting_cv.broadcast
650
+ @size_cv.broadcast
626
651
  end
627
652
 
628
653
  publish_cmap_event(
@@ -644,6 +669,9 @@ module Mongo
644
669
  if closed?
645
670
  "#<Mongo::Server::ConnectionPool:0x#{object_id} min_size=#{min_size} max_size=#{max_size} " +
646
671
  "wait_timeout=#{wait_timeout} closed>"
672
+ elsif !ready?
673
+ "#<Mongo::Server::ConnectionPool:0x#{object_id} min_size=#{min_size} max_size=#{max_size} " +
674
+ "wait_timeout=#{wait_timeout} paused>"
647
675
  else
648
676
  "#<Mongo::Server::ConnectionPool:0x#{object_id} min_size=#{min_size} max_size=#{max_size} " +
649
677
  "wait_timeout=#{wait_timeout} current_size=#{size} available=#{available_count}>"
@@ -665,6 +693,8 @@ module Mongo
665
693
 
666
694
  connection = check_out(connection_global_id: connection_global_id)
667
695
  yield(connection)
696
+ rescue Error::SocketError, Error::SocketTimeoutError, Error::ConnectionPerished => e
697
+ maybe_raise_pool_cleared!(connection, e)
668
698
  ensure
669
699
  if connection
670
700
  check_in(connection)
@@ -713,17 +743,17 @@ module Mongo
713
743
  # connections waiting to be connected, connections which have not yet
714
744
  # been moved to available_connections, or connections moved to available_connections
715
745
  # but not deleted from pending_connections. These should be cleaned up.
716
- until @pending_connections.empty?
717
- connection = @pending_connections.take(1).first
718
- connection.disconnect!
719
- @pending_connections.delete(connection)
720
- end
746
+ clear_pending_connections
721
747
  end
722
748
  end
723
749
 
724
- # Creates and adds a connection to the pool, if the pool's size is below
725
- # min_size. Retries once if a socket-related error is encountered during
726
- # this process and raises if a second error or a non socket-related error occurs.
750
+ # This method does three things:
751
+ # 1. Creates and adds a connection to the pool, if the pool's size is
752
+ # below min_size. Retries once if a socket-related error is
753
+ # encountered during this process and raises if a second error or a
754
+ # non socket-related error occurs.
755
+ # 2. Removes stale connections from the connection pool.
756
+ # 3. Interrupts connections marked for interruption.
727
757
  #
728
758
  # Used by the pool populator background thread.
729
759
  #
@@ -745,11 +775,6 @@ module Mongo
745
775
  end
746
776
 
747
777
  return create_and_add_connection
748
- rescue Error::AuthError, Error
749
- # wake up one thread waiting for connections, since one could not
750
- # be created here, and can instead be created in flow
751
- @available_semaphore.signal
752
- raise
753
778
  end
754
779
 
755
780
  # Finalize the connection pool for garbage collection.
@@ -782,7 +807,9 @@ module Mongo
782
807
  # Returns the next available connection, optionally with given
783
808
  # global id. If no suitable connections are available,
784
809
  # returns nil.
785
- def next_available_connection(connection_global_id: nil)
810
+ def next_available_connection(connection_global_id)
811
+ raise_unless_locked!
812
+
786
813
  if @server.load_balancer? && connection_global_id
787
814
  conn = @available_connections.detect do |conn|
788
815
  conn.global_id == connection_global_id
@@ -797,18 +824,21 @@ module Mongo
797
824
  end
798
825
 
799
826
  def create_connection
827
+ r, _ = @generation_manager.pipe_fds(service_id: server.description.service_id)
800
828
  opts = options.merge(
801
829
  connection_pool: self,
830
+ pipe: r
802
831
  # Do not pass app metadata - this will be retrieved by the connection
803
832
  # based on the auth needs.
804
833
  )
805
834
  unless @server.load_balancer?
806
835
  opts[:generation] = generation
807
836
  end
808
- connection = Connection.new(@server, opts)
837
+ Connection.new(@server, opts)
809
838
  end
810
839
 
811
- # Create a connection, connect it, and add it to the pool.
840
+ # Create a connection, connect it, and add it to the pool. Also
841
+ # check for stale and interruptable connections and deal with them.
812
842
  #
813
843
  # @return [ true | false ] True if a connection was created and
814
844
  # added to the pool, false otherwise
@@ -817,10 +847,15 @@ module Mongo
817
847
  connection = nil
818
848
 
819
849
  @lock.synchronize do
820
- if !closed? && unsynchronized_size < min_size
850
+ if !closed? && @ready &&
851
+ (unsynchronized_size + @connection_requests) < min_size &&
852
+ @pending_connections.length < @max_connecting
853
+ then
821
854
  connection = create_connection
822
855
  @pending_connections << connection
823
856
  else
857
+ return true if remove_interrupted_connections
858
+ return true if remove_stale_connection
824
859
  return false
825
860
  end
826
861
  end
@@ -830,6 +865,8 @@ module Mongo
830
865
  rescue Exception
831
866
  @lock.synchronize do
832
867
  @pending_connections.delete(connection)
868
+ @max_connecting_cv.signal
869
+ @size_cv.signal
833
870
  end
834
871
  raise
835
872
  end
@@ -837,14 +874,65 @@ module Mongo
837
874
  @lock.synchronize do
838
875
  @available_connections << connection
839
876
  @pending_connections.delete(connection)
877
+ @max_connecting_cv.signal
878
+ @size_cv.signal
879
+ end
880
+
881
+ true
882
+ end
883
+
884
+ # Removes and disconnects all stale available connections.
885
+ def remove_stale_connection
886
+ if conn = @available_connections.detect(&method(:connection_stale_unlocked?))
887
+ conn.disconnect!(reason: :stale)
888
+ @available_connections.delete(conn)
889
+ return true
890
+ end
891
+ end
892
+
893
+ # Interrupt connections scheduled for interruption.
894
+ def remove_interrupted_connections
895
+ return false if @interrupt_connections.empty?
896
+
897
+ gens = Set.new
898
+ while conn = @interrupt_connections.pop
899
+ if @checked_out_connections.include?(conn)
900
+ # If the connection has been checked out, mark it as interrupted and it will
901
+ # be disconnected on check in.
902
+ conn.interrupted!
903
+ do_check_in(conn)
904
+ elsif @pending_connections.include?(conn)
905
+ # If the connection is pending, disconnect with the interrupted flag.
906
+ conn.disconnect!(reason: :stale, interrupted: true)
907
+ @pending_connections.delete(conn)
908
+ end
909
+ gens << [ conn.generation, conn.service_id ]
910
+ end
840
911
 
841
- # wake up one thread waiting for connections, since one was created
842
- @available_semaphore.signal
912
+ # Close the write side of the pipe. Pending connections might be
913
+ # hanging on the Kernel#select call, so in order to interrupt that,
914
+ # we also listen for the read side of the pipe in Kernel#select and
915
+ # close the write side of the pipe here, which will cause select to
916
+ # wake up and raise an IOError now that the socket is closed.
917
+ # The read side of the pipe will be scheduled for closing on the next
918
+ # generation bump.
919
+ gens.each do |gen, service_id|
920
+ @generation_manager.remove_pipe_fds(gen, service_id: service_id)
843
921
  end
844
922
 
845
923
  true
846
924
  end
847
925
 
926
+ # Checks whether a connection is stale.
927
+ #
928
+ # @param [ Mongo::Server::Connection ] connection The connection to check.
929
+ #
930
+ # @return [ true | false ] Whether the connection is stale.
931
+ def connection_stale_unlocked?(connection)
932
+ connection.generation != generation_unlocked(service_id: connection.service_id) &&
933
+ !connection.pinned?
934
+ end
935
+
848
936
  # Asserts that the pool has not been closed.
849
937
  #
850
938
  # @raise [ Error::PoolClosedError ] If the pool has been closed.
@@ -856,6 +944,25 @@ module Mongo
856
944
  end
857
945
  end
858
946
 
947
+ # If the connection was interrupted, raise a pool cleared error. If it
948
+ # wasn't interrupted raise the original error.
949
+ #
950
+ # @param [ Connection ] The connection.
951
+ # @param [ Mongo::Error ] The original error.
952
+ #
953
+ # @raise [ Mongo::Error | Mongo::Error::PoolClearedError ] A PoolClearedError
954
+ # if the connection was interrupted, the original error if not.
955
+ def maybe_raise_pool_cleared!(connection, e)
956
+ if connection&.interrupted?
957
+ err = Error::PoolClearedError.new(connection.server.address, connection.server.pool_internal).tap do |err|
958
+ e.labels.each { |l| err.add_label(l) }
959
+ end
960
+ raise err
961
+ else
962
+ raise e
963
+ end
964
+ end
965
+
859
966
  # Attempts to connect (handshake and auth) the connection. If an error is
860
967
  # encountered, closes the connection and raises the error.
861
968
  def connect_connection(connection)
@@ -895,6 +1002,306 @@ module Mongo
895
1002
  end
896
1003
  end
897
1004
  end
1005
+
1006
+ # Close the available connections.
1007
+ #
1008
+ # @param [ Array<Connection> ] connections A list of connections.
1009
+ # @param [ Object ] service_id The service id.
1010
+ def close_available_connections(service_id)
1011
+ if @server.load_balancer? && service_id
1012
+ loop do
1013
+ conn = @available_connections.detect do |conn|
1014
+ conn.service_id == service_id &&
1015
+ conn.generation < @generation_manager.generation(service_id: service_id)
1016
+ end
1017
+ if conn
1018
+ @available_connections.delete(conn)
1019
+ conn.disconnect!(reason: :stale, interrupted: true)
1020
+ @populate_semaphore.signal
1021
+ else
1022
+ break
1023
+ end
1024
+ end
1025
+ else
1026
+ @available_connections.delete_if do |conn|
1027
+ if conn.generation < @generation_manager.generation(service_id: service_id)
1028
+ conn.disconnect!(reason: :stale, interrupted: true)
1029
+ @populate_semaphore.signal
1030
+ true
1031
+ end
1032
+ end
1033
+ end
1034
+ end
1035
+
1036
+ # Schedule connections of previous generations for interruption.
1037
+ #
1038
+ # @param [ Array<Connection> ] connections A list of connections.
1039
+ # @param [ Object ] service_id The service id.
1040
+ def schedule_for_interruption(connections, service_id)
1041
+ @interrupt_connections += connections.select do |conn|
1042
+ (!server.load_balancer? || conn.service_id == service_id) &&
1043
+ conn.generation < @generation_manager.generation(service_id: service_id)
1044
+ end
1045
+ end
1046
+
1047
+ # Clear and disconnect the pending connections.
1048
+ def clear_pending_connections
1049
+ until @pending_connections.empty?
1050
+ connection = @pending_connections.take(1).first
1051
+ connection.disconnect!
1052
+ @pending_connections.delete(connection)
1053
+ end
1054
+ end
1055
+
1056
+ # The lock should be acquired when calling this method.
1057
+ def raise_check_out_timeout!(connection_global_id)
1058
+ raise_unless_locked!
1059
+
1060
+ publish_cmap_event(
1061
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
1062
+ @server.address,
1063
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed::TIMEOUT,
1064
+ ),
1065
+ )
1066
+
1067
+ connection_global_id_msg = if connection_global_id
1068
+ " for connection #{connection_global_id}"
1069
+ else
1070
+ ''
1071
+ end
1072
+
1073
+ msg = "Timed out attempting to check out a connection " +
1074
+ "from pool for #{@server.address}#{connection_global_id_msg} after #{wait_timeout} sec. " +
1075
+ "Connections in pool: #{@available_connections.length} available, " +
1076
+ "#{@checked_out_connections.length} checked out, " +
1077
+ "#{@pending_connections.length + @connection_requests} pending " +
1078
+ "(max size: #{max_size})"
1079
+ raise Error::ConnectionCheckOutTimeout.new(msg, address: @server.address)
1080
+ end
1081
+
1082
+ def raise_check_out_timeout_locked!(connection_global_id)
1083
+ @lock.synchronize do
1084
+ raise_check_out_timeout!(connection_global_id)
1085
+ end
1086
+ end
1087
+
1088
+ def raise_if_pool_closed!
1089
+ if closed?
1090
+ publish_cmap_event(
1091
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
1092
+ @server.address,
1093
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed::POOL_CLOSED
1094
+ ),
1095
+ )
1096
+ raise Error::PoolClosedError.new(@server.address, self)
1097
+ end
1098
+ end
1099
+
1100
+ def raise_if_pool_paused!
1101
+ raise_unless_locked!
1102
+
1103
+ if !@ready
1104
+ publish_cmap_event(
1105
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
1106
+ @server.address,
1107
+ # CMAP spec decided to conflate pool paused with all the other
1108
+ # possible non-timeout errors.
1109
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed::CONNECTION_ERROR,
1110
+ ),
1111
+ )
1112
+ raise Error::PoolPausedError.new(@server.address, self)
1113
+ end
1114
+ end
1115
+
1116
+ def raise_if_pool_paused_locked!
1117
+ @lock.synchronize do
1118
+ raise_if_pool_paused!
1119
+ end
1120
+ end
1121
+
1122
+ # The lock should be acquired when calling this method.
1123
+ def raise_if_not_ready!
1124
+ raise_unless_locked!
1125
+ raise_if_pool_closed!
1126
+ raise_if_pool_paused!
1127
+ end
1128
+
1129
+ def raise_unless_locked!
1130
+ unless @lock.owned?
1131
+ raise ArgumentError, "the lock must be owned when calling this method"
1132
+ end
1133
+ end
1134
+
1135
+ def valid_available_connection?(connection, pid, connection_global_id)
1136
+ if connection.pid != pid
1137
+ log_warn("Detected PID change - Mongo client should have been reconnected (old pid #{connection.pid}, new pid #{pid}")
1138
+ connection.disconnect!(reason: :stale)
1139
+ @populate_semaphore.signal
1140
+ return false
1141
+ end
1142
+
1143
+ if !connection.pinned?
1144
+ # If connection is marked as pinned, it is used by a transaction
1145
+ # or a series of cursor operations in a load balanced setup.
1146
+ # In this case connection should not be disconnected until
1147
+ # unpinned.
1148
+ if connection.generation != generation(
1149
+ service_id: connection.service_id
1150
+ )
1151
+ # Stale connections should be disconnected in the clear
1152
+ # method, but if any don't, check again here
1153
+ connection.disconnect!(reason: :stale)
1154
+ @populate_semaphore.signal
1155
+ return false
1156
+ end
1157
+
1158
+ if max_idle_time && connection.last_checkin &&
1159
+ Time.now - connection.last_checkin > max_idle_time
1160
+ then
1161
+ connection.disconnect!(reason: :idle)
1162
+ @populate_semaphore.signal
1163
+ return false
1164
+ end
1165
+ end
1166
+ true
1167
+ end
1168
+
1169
+ # Retrieves a connection if one is available, otherwise we create a new
1170
+ # one. If no connection exists and the pool is at max size, wait until
1171
+ # a connection is checked back into the pool.
1172
+ #
1173
+ # @param [ Float ] deadline The deadline to get the connection.
1174
+ # @param [ Integer ] pid The current process id.
1175
+ # @param [ Integer ] connection_global_id The global id for the
1176
+ # connection to check out.
1177
+ #
1178
+ # @return [ Mongo::Server::Connection ] The checked out connection.
1179
+ #
1180
+ # @raise [ Error::PoolClosedError ] If the pool has been closed.
1181
+ # @raise [ Timeout::Error ] If the connection pool is at maximum size
1182
+ # and remains so for longer than the wait timeout.
1183
+ def get_connection(deadline, pid, connection_global_id)
1184
+ if connection = next_available_connection(connection_global_id)
1185
+ unless valid_available_connection?(connection, pid, connection_global_id)
1186
+ return nil
1187
+ end
1188
+
1189
+ # If the connection is connected, it's not considered a
1190
+ # "pending connection". The pending_connections list represents
1191
+ # the set of connections that are awaiting connection.
1192
+ unless connection.connected?
1193
+ @connection_requests -= 1
1194
+ @pending_connections << connection
1195
+ end
1196
+ return connection
1197
+ elsif connection_global_id && @server.load_balancer?
1198
+ # A particular connection is requested, but it is not available.
1199
+ # If it is nether available not checked out, we should stop here.
1200
+ @checked_out_connections.detect do |conn|
1201
+ conn.global_id == connection_global_id
1202
+ end.tap do |conn|
1203
+ if conn.nil?
1204
+ publish_cmap_event(
1205
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
1206
+ @server.address,
1207
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed::CONNECTION_ERROR
1208
+ ),
1209
+ )
1210
+ raise Error::MissingConnection.new
1211
+ end
1212
+ end
1213
+ # We need a particular connection, and if it is not available
1214
+ # we can wait for an in-progress operation to return
1215
+ # such a connection to the pool.
1216
+ nil
1217
+ else
1218
+ connection = create_connection
1219
+ @connection_requests -= 1
1220
+ @pending_connections << connection
1221
+ return connection
1222
+ end
1223
+ end
1224
+
1225
+ # Retrieves a connection and connects it.
1226
+ #
1227
+ # @param [ Integer ] connection_global_id The global id for the
1228
+ # connection to check out.
1229
+ #
1230
+ # @return [ Mongo::Server::Connection ] The checked out connection.
1231
+ #
1232
+ # @raise [ Error::PoolClosedError ] If the pool has been closed.
1233
+ # @raise [ Timeout::Error ] If the connection pool is at maximum size
1234
+ # and remains so for longer than the wait timeout.
1235
+ def retrieve_and_connect_connection(connection_global_id)
1236
+ deadline = Utils.monotonic_time + wait_timeout
1237
+ connection = nil
1238
+
1239
+ @lock.synchronize do
1240
+
1241
+ # The first gate to checking out a connection. Make sure the number of
1242
+ # unavailable connections is less than the max pool size.
1243
+ until max_size == 0 || unavailable_connections < max_size
1244
+ wait = deadline - Utils.monotonic_time
1245
+ raise_check_out_timeout!(connection_global_id) if wait <= 0
1246
+ @size_cv.wait(wait)
1247
+ raise_if_not_ready!
1248
+ end
1249
+ @connection_requests += 1
1250
+
1251
+ while connection.nil?
1252
+ # The second gate to checking out a connection. Make sure 1) there
1253
+ # exists an available connection and 2) we are under max_connecting.
1254
+ until @available_connections.any? || @pending_connections.length < @max_connecting
1255
+ wait = deadline - Utils.monotonic_time
1256
+ raise_check_out_timeout!(connection_global_id) if wait <= 0
1257
+ @max_connecting_cv.wait(wait)
1258
+ raise_if_not_ready!
1259
+ end
1260
+
1261
+ connection = get_connection(deadline, Process.pid, connection_global_id)
1262
+ wait = deadline - Utils.monotonic_time
1263
+ raise_check_out_timeout!(connection_global_id) if connection.nil? && wait <= 0
1264
+ end
1265
+ end
1266
+
1267
+ begin
1268
+ connect_connection(connection)
1269
+ rescue Exception
1270
+ # Handshake or authentication failed
1271
+ @lock.synchronize do
1272
+ if @pending_connections.include?(connection)
1273
+ @pending_connections.delete(connection)
1274
+ else
1275
+ @connection_requests -= 1
1276
+ end
1277
+ @max_connecting_cv.signal
1278
+ @size_cv.signal
1279
+ end
1280
+ @populate_semaphore.signal
1281
+
1282
+ publish_cmap_event(
1283
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
1284
+ @server.address,
1285
+ Monitoring::Event::Cmap::ConnectionCheckOutFailed::CONNECTION_ERROR
1286
+ ),
1287
+ )
1288
+ raise
1289
+ end
1290
+
1291
+ @lock.synchronize do
1292
+ @checked_out_connections << connection
1293
+ if @pending_connections.include?(connection)
1294
+ @pending_connections.delete(connection)
1295
+ else
1296
+ @connection_requests -= 1
1297
+ end
1298
+ @max_connecting_cv.signal
1299
+ # no need to signal size_cv here since the number of unavailable
1300
+ # connections is unchanged.
1301
+ end
1302
+
1303
+ connection
1304
+ end
898
1305
  end
899
1306
  end
900
1307
  end