mongo 2.12.1 → 2.13.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 (856) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CONTRIBUTING.md +8 -36
  5. data/LICENSE +1 -1
  6. data/README.md +54 -54
  7. data/Rakefile +16 -10
  8. data/lib/mongo.rb +8 -3
  9. data/lib/mongo/active_support.rb +1 -1
  10. data/lib/mongo/address.rb +78 -37
  11. data/lib/mongo/address/ipv4.rb +32 -5
  12. data/lib/mongo/address/ipv6.rb +32 -5
  13. data/lib/mongo/address/unix.rb +3 -3
  14. data/lib/mongo/address/validator.rb +1 -1
  15. data/lib/mongo/auth.rb +36 -13
  16. data/lib/mongo/auth/aws.rb +37 -0
  17. data/lib/mongo/auth/aws/conversation.rb +128 -0
  18. data/lib/mongo/auth/aws/credentials_retriever.rb +219 -0
  19. data/lib/mongo/auth/aws/request.rb +283 -0
  20. data/lib/mongo/auth/base.rb +129 -0
  21. data/lib/mongo/auth/conversation_base.rb +52 -0
  22. data/lib/mongo/auth/cr.rb +9 -36
  23. data/lib/mongo/auth/cr/conversation.rb +24 -69
  24. data/lib/mongo/auth/credential_cache.rb +1 -1
  25. data/lib/mongo/auth/gssapi.rb +38 -0
  26. data/lib/mongo/auth/gssapi/conversation.rb +108 -0
  27. data/lib/mongo/auth/ldap.rb +9 -34
  28. data/lib/mongo/auth/ldap/conversation.rb +3 -43
  29. data/lib/mongo/auth/roles.rb +1 -1
  30. data/lib/mongo/auth/sasl_conversation_base.rb +111 -0
  31. data/lib/mongo/auth/scram.rb +39 -51
  32. data/lib/mongo/auth/scram/conversation.rb +12 -506
  33. data/lib/mongo/auth/scram256.rb +31 -0
  34. data/lib/mongo/auth/scram256/conversation.rb +63 -0
  35. data/lib/mongo/auth/scram_conversation_base.rb +402 -0
  36. data/lib/mongo/auth/stringprep.rb +5 -4
  37. data/lib/mongo/auth/stringprep/profiles/sasl.rb +2 -1
  38. data/lib/mongo/auth/stringprep/tables.rb +2 -1
  39. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +1 -0
  40. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +1 -0
  41. data/lib/mongo/auth/user.rb +2 -2
  42. data/lib/mongo/auth/user/view.rb +1 -1
  43. data/lib/mongo/auth/x509.rb +14 -32
  44. data/lib/mongo/auth/x509/conversation.rb +15 -42
  45. data/lib/mongo/background_thread.rb +11 -2
  46. data/lib/mongo/bson.rb +1 -1
  47. data/lib/mongo/bulk_write.rb +62 -26
  48. data/lib/mongo/bulk_write/combineable.rb +20 -8
  49. data/lib/mongo/bulk_write/ordered_combiner.rb +1 -1
  50. data/lib/mongo/bulk_write/result.rb +1 -1
  51. data/lib/mongo/bulk_write/result_combiner.rb +1 -1
  52. data/lib/mongo/bulk_write/transformable.rb +9 -10
  53. data/lib/mongo/bulk_write/unordered_combiner.rb +1 -1
  54. data/lib/mongo/bulk_write/validatable.rb +5 -1
  55. data/lib/mongo/client.rb +214 -31
  56. data/lib/mongo/client_encryption.rb +1 -1
  57. data/lib/mongo/cluster.rb +177 -69
  58. data/lib/mongo/cluster/periodic_executor.rb +1 -1
  59. data/lib/mongo/cluster/reapers/cursor_reaper.rb +1 -1
  60. data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -1
  61. data/lib/mongo/cluster/sdam_flow.rb +36 -17
  62. data/lib/mongo/cluster/topology.rb +19 -2
  63. data/lib/mongo/cluster/topology/base.rb +1 -1
  64. data/lib/mongo/cluster/topology/no_replica_set_options.rb +1 -1
  65. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +4 -3
  66. data/lib/mongo/cluster/topology/replica_set_with_primary.rb +1 -1
  67. data/lib/mongo/cluster/topology/sharded.rb +2 -2
  68. data/lib/mongo/cluster/topology/single.rb +2 -2
  69. data/lib/mongo/cluster/topology/unknown.rb +1 -1
  70. data/lib/mongo/cluster_time.rb +1 -1
  71. data/lib/mongo/collection.rb +39 -15
  72. data/lib/mongo/collection/view.rb +6 -2
  73. data/lib/mongo/collection/view/aggregation.rb +6 -3
  74. data/lib/mongo/collection/view/builder.rb +1 -1
  75. data/lib/mongo/collection/view/builder/aggregation.rb +1 -1
  76. data/lib/mongo/collection/view/builder/find_command.rb +9 -1
  77. data/lib/mongo/collection/view/builder/flags.rb +1 -1
  78. data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
  79. data/lib/mongo/collection/view/builder/modifiers.rb +1 -1
  80. data/lib/mongo/collection/view/builder/op_query.rb +1 -1
  81. data/lib/mongo/collection/view/change_stream.rb +3 -6
  82. data/lib/mongo/collection/view/change_stream/retryable.rb +1 -1
  83. data/lib/mongo/collection/view/explainable.rb +1 -1
  84. data/lib/mongo/collection/view/immutable.rb +1 -1
  85. data/lib/mongo/collection/view/iterable.rb +8 -2
  86. data/lib/mongo/collection/view/map_reduce.rb +7 -4
  87. data/lib/mongo/collection/view/readable.rb +13 -3
  88. data/lib/mongo/collection/view/writable.rb +93 -13
  89. data/lib/mongo/crypt.rb +1 -1
  90. data/lib/mongo/crypt/auto_decryption_context.rb +1 -1
  91. data/lib/mongo/crypt/auto_encrypter.rb +1 -1
  92. data/lib/mongo/crypt/auto_encryption_context.rb +1 -1
  93. data/lib/mongo/crypt/binary.rb +1 -1
  94. data/lib/mongo/crypt/binding.rb +1 -1
  95. data/lib/mongo/crypt/context.rb +1 -1
  96. data/lib/mongo/crypt/data_key_context.rb +1 -1
  97. data/lib/mongo/crypt/encryption_io.rb +41 -24
  98. data/lib/mongo/crypt/explicit_decryption_context.rb +1 -1
  99. data/lib/mongo/crypt/explicit_encrypter.rb +1 -1
  100. data/lib/mongo/crypt/explicit_encryption_context.rb +1 -1
  101. data/lib/mongo/crypt/handle.rb +1 -1
  102. data/lib/mongo/crypt/hooks.rb +1 -1
  103. data/lib/mongo/crypt/kms_context.rb +1 -1
  104. data/lib/mongo/crypt/status.rb +1 -1
  105. data/lib/mongo/cursor.rb +3 -3
  106. data/lib/mongo/cursor/builder.rb +1 -1
  107. data/lib/mongo/cursor/builder/get_more_command.rb +1 -1
  108. data/lib/mongo/cursor/builder/kill_cursors_command.rb +1 -1
  109. data/lib/mongo/cursor/builder/op_get_more.rb +1 -1
  110. data/lib/mongo/cursor/builder/op_kill_cursors.rb +1 -1
  111. data/lib/mongo/database.rb +35 -5
  112. data/lib/mongo/database/view.rb +21 -6
  113. data/lib/mongo/dbref.rb +1 -1
  114. data/lib/mongo/distinguishing_semaphore.rb +55 -0
  115. data/lib/mongo/error.rb +28 -2
  116. data/lib/mongo/error/auth_error.rb +1 -1
  117. data/lib/mongo/error/bulk_write_error.rb +1 -1
  118. data/lib/mongo/error/change_stream_resumable.rb +1 -1
  119. data/lib/mongo/error/closed_stream.rb +1 -1
  120. data/lib/mongo/error/connection_check_out_timeout.rb +1 -1
  121. data/lib/mongo/error/connection_perished.rb +23 -0
  122. data/lib/mongo/error/credential_check_error.rb +26 -0
  123. data/lib/mongo/error/extra_file_chunk.rb +1 -1
  124. data/lib/mongo/error/file_not_found.rb +1 -1
  125. data/lib/mongo/error/handshake_error.rb +1 -1
  126. data/lib/mongo/error/insufficient_iteration_count.rb +1 -1
  127. data/lib/mongo/error/invalid_address.rb +1 -1
  128. data/lib/mongo/error/invalid_application_name.rb +1 -1
  129. data/lib/mongo/error/invalid_bulk_operation.rb +1 -1
  130. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -1
  131. data/lib/mongo/error/invalid_collection_name.rb +1 -1
  132. data/lib/mongo/error/invalid_cursor_operation.rb +1 -1
  133. data/lib/mongo/error/invalid_database_name.rb +1 -1
  134. data/lib/mongo/error/invalid_document.rb +1 -1
  135. data/lib/mongo/error/invalid_file.rb +1 -1
  136. data/lib/mongo/error/invalid_file_revision.rb +1 -1
  137. data/lib/mongo/error/invalid_min_pool_size.rb +1 -1
  138. data/lib/mongo/error/invalid_nonce.rb +2 -2
  139. data/lib/mongo/error/invalid_read_option.rb +1 -1
  140. data/lib/mongo/error/invalid_replacement_document.rb +1 -1
  141. data/lib/mongo/error/invalid_server_auth_host.rb +22 -0
  142. data/lib/mongo/error/invalid_server_auth_response.rb +23 -0
  143. data/lib/mongo/error/invalid_server_preference.rb +6 -1
  144. data/lib/mongo/error/invalid_session.rb +3 -2
  145. data/lib/mongo/error/invalid_signature.rb +1 -1
  146. data/lib/mongo/error/invalid_transaction_operation.rb +1 -1
  147. data/lib/mongo/error/invalid_txt_record.rb +1 -1
  148. data/lib/mongo/error/invalid_update_document.rb +1 -1
  149. data/lib/mongo/error/invalid_uri.rb +1 -1
  150. data/lib/mongo/error/invalid_write_concern.rb +1 -1
  151. data/lib/mongo/error/lint_error.rb +1 -1
  152. data/lib/mongo/error/max_bson_size.rb +1 -1
  153. data/lib/mongo/error/max_message_size.rb +1 -1
  154. data/lib/mongo/error/mismatched_domain.rb +1 -1
  155. data/lib/mongo/error/missing_file_chunk.rb +1 -1
  156. data/lib/mongo/error/missing_password.rb +1 -1
  157. data/lib/mongo/error/missing_resume_token.rb +1 -1
  158. data/lib/mongo/error/missing_scram_server_signature.rb +27 -0
  159. data/lib/mongo/error/multi_index_drop.rb +1 -1
  160. data/lib/mongo/error/need_primary_server.rb +1 -1
  161. data/lib/mongo/error/no_server_available.rb +1 -1
  162. data/lib/mongo/error/no_srv_records.rb +1 -1
  163. data/lib/mongo/error/notable.rb +18 -3
  164. data/lib/mongo/error/operation_failure.rb +63 -44
  165. data/lib/mongo/error/parser.rb +16 -5
  166. data/lib/mongo/error/pool_closed_error.rb +1 -1
  167. data/lib/mongo/error/raise_original_error.rb +29 -0
  168. data/lib/mongo/error/session_ended.rb +1 -1
  169. data/lib/mongo/error/sessions_not_supported.rb +35 -0
  170. data/lib/mongo/error/socket_error.rb +1 -1
  171. data/lib/mongo/error/socket_timeout_error.rb +1 -1
  172. data/lib/mongo/error/unchangeable_collection_option.rb +1 -1
  173. data/lib/mongo/error/unexpected_chunk_length.rb +1 -1
  174. data/lib/mongo/error/unexpected_response.rb +1 -1
  175. data/lib/mongo/error/unknown_payload_type.rb +1 -1
  176. data/lib/mongo/error/unsupported_array_filters.rb +7 -2
  177. data/lib/mongo/error/unsupported_collation.rb +7 -2
  178. data/lib/mongo/error/unsupported_features.rb +1 -1
  179. data/lib/mongo/error/unsupported_message_type.rb +1 -1
  180. data/lib/mongo/error/unsupported_option.rb +99 -0
  181. data/lib/mongo/error/write_retryable.rb +1 -1
  182. data/lib/mongo/event.rb +1 -1
  183. data/lib/mongo/event/base.rb +7 -1
  184. data/lib/mongo/event/listeners.rb +1 -1
  185. data/lib/mongo/event/publisher.rb +1 -1
  186. data/lib/mongo/event/subscriber.rb +1 -1
  187. data/lib/mongo/grid.rb +1 -1
  188. data/lib/mongo/grid/file.rb +6 -1
  189. data/lib/mongo/grid/file/chunk.rb +3 -1
  190. data/lib/mongo/grid/file/info.rb +1 -1
  191. data/lib/mongo/grid/fs_bucket.rb +22 -15
  192. data/lib/mongo/grid/stream.rb +1 -1
  193. data/lib/mongo/grid/stream/read.rb +1 -1
  194. data/lib/mongo/grid/stream/write.rb +10 -4
  195. data/lib/mongo/id.rb +1 -1
  196. data/lib/mongo/index.rb +2 -1
  197. data/lib/mongo/index/view.rb +61 -11
  198. data/lib/mongo/lint.rb +10 -0
  199. data/lib/mongo/loggable.rb +1 -1
  200. data/lib/mongo/logger.rb +1 -1
  201. data/lib/mongo/monitoring.rb +39 -1
  202. data/lib/mongo/monitoring/cmap_log_subscriber.rb +1 -1
  203. data/lib/mongo/monitoring/command_log_subscriber.rb +20 -5
  204. data/lib/mongo/monitoring/event.rb +1 -1
  205. data/lib/mongo/monitoring/event/cmap.rb +1 -1
  206. data/lib/mongo/monitoring/event/cmap/base.rb +1 -1
  207. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -1
  208. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +1 -1
  209. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +1 -1
  210. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +1 -1
  211. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +1 -1
  212. data/lib/mongo/monitoring/event/cmap/connection_created.rb +1 -1
  213. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +1 -1
  214. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +1 -1
  215. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +1 -1
  216. data/lib/mongo/monitoring/event/cmap/pool_created.rb +1 -1
  217. data/lib/mongo/monitoring/event/command_failed.rb +12 -1
  218. data/lib/mongo/monitoring/event/command_started.rb +44 -3
  219. data/lib/mongo/monitoring/event/command_succeeded.rb +12 -1
  220. data/lib/mongo/monitoring/event/secure.rb +8 -2
  221. data/lib/mongo/monitoring/event/server_closed.rb +2 -2
  222. data/lib/mongo/monitoring/event/server_description_changed.rb +28 -5
  223. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +10 -3
  224. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +10 -3
  225. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +10 -3
  226. data/lib/mongo/monitoring/event/server_opening.rb +2 -2
  227. data/lib/mongo/monitoring/event/topology_changed.rb +2 -2
  228. data/lib/mongo/monitoring/event/topology_closed.rb +2 -2
  229. data/lib/mongo/monitoring/event/topology_opening.rb +2 -2
  230. data/lib/mongo/monitoring/publishable.rb +9 -9
  231. data/lib/mongo/monitoring/sdam_log_subscriber.rb +1 -1
  232. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +1 -1
  233. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +10 -2
  234. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +1 -1
  235. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +2 -2
  236. data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +1 -1
  237. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +1 -1
  238. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +1 -1
  239. data/lib/mongo/operation.rb +1 -0
  240. data/lib/mongo/operation/aggregate.rb +1 -1
  241. data/lib/mongo/operation/aggregate/command.rb +5 -5
  242. data/lib/mongo/operation/aggregate/op_msg.rb +1 -1
  243. data/lib/mongo/operation/aggregate/result.rb +1 -1
  244. data/lib/mongo/operation/collections_info.rb +3 -36
  245. data/lib/mongo/operation/collections_info/command.rb +40 -0
  246. data/lib/mongo/operation/collections_info/result.rb +1 -1
  247. data/lib/mongo/operation/command.rb +1 -1
  248. data/lib/mongo/operation/command/command.rb +3 -3
  249. data/lib/mongo/operation/command/op_msg.rb +1 -1
  250. data/lib/mongo/operation/count.rb +1 -1
  251. data/lib/mongo/operation/count/command.rb +3 -3
  252. data/lib/mongo/operation/count/op_msg.rb +1 -1
  253. data/lib/mongo/operation/create.rb +1 -1
  254. data/lib/mongo/operation/create/command.rb +3 -3
  255. data/lib/mongo/operation/create/op_msg.rb +1 -1
  256. data/lib/mongo/operation/create_index.rb +1 -1
  257. data/lib/mongo/operation/create_index/command.rb +4 -4
  258. data/lib/mongo/operation/create_index/op_msg.rb +6 -3
  259. data/lib/mongo/operation/create_user.rb +1 -1
  260. data/lib/mongo/operation/create_user/command.rb +4 -4
  261. data/lib/mongo/operation/create_user/op_msg.rb +2 -2
  262. data/lib/mongo/operation/delete.rb +1 -1
  263. data/lib/mongo/operation/delete/bulk_result.rb +1 -1
  264. data/lib/mongo/operation/delete/command.rb +4 -4
  265. data/lib/mongo/operation/delete/legacy.rb +2 -2
  266. data/lib/mongo/operation/delete/op_msg.rb +4 -4
  267. data/lib/mongo/operation/delete/result.rb +2 -2
  268. data/lib/mongo/operation/distinct.rb +1 -1
  269. data/lib/mongo/operation/distinct/command.rb +3 -3
  270. data/lib/mongo/operation/distinct/op_msg.rb +1 -1
  271. data/lib/mongo/operation/drop.rb +1 -1
  272. data/lib/mongo/operation/drop/command.rb +3 -3
  273. data/lib/mongo/operation/drop/op_msg.rb +1 -1
  274. data/lib/mongo/operation/drop_database.rb +1 -1
  275. data/lib/mongo/operation/drop_database/command.rb +3 -3
  276. data/lib/mongo/operation/drop_database/op_msg.rb +1 -1
  277. data/lib/mongo/operation/drop_index.rb +1 -1
  278. data/lib/mongo/operation/drop_index/command.rb +4 -4
  279. data/lib/mongo/operation/drop_index/op_msg.rb +2 -2
  280. data/lib/mongo/operation/explain.rb +1 -1
  281. data/lib/mongo/operation/explain/command.rb +3 -3
  282. data/lib/mongo/operation/explain/legacy.rb +3 -3
  283. data/lib/mongo/operation/explain/op_msg.rb +1 -1
  284. data/lib/mongo/operation/explain/result.rb +1 -1
  285. data/lib/mongo/operation/find.rb +1 -1
  286. data/lib/mongo/operation/find/command.rb +3 -3
  287. data/lib/mongo/operation/find/legacy.rb +3 -3
  288. data/lib/mongo/operation/find/legacy/result.rb +1 -1
  289. data/lib/mongo/operation/find/op_msg.rb +2 -12
  290. data/lib/mongo/operation/find/result.rb +1 -1
  291. data/lib/mongo/operation/get_more.rb +1 -1
  292. data/lib/mongo/operation/get_more/command.rb +3 -3
  293. data/lib/mongo/operation/get_more/legacy.rb +2 -2
  294. data/lib/mongo/operation/get_more/op_msg.rb +2 -12
  295. data/lib/mongo/operation/get_more/result.rb +1 -1
  296. data/lib/mongo/operation/indexes.rb +1 -1
  297. data/lib/mongo/operation/indexes/command.rb +3 -3
  298. data/lib/mongo/operation/indexes/legacy.rb +4 -4
  299. data/lib/mongo/operation/indexes/op_msg.rb +1 -1
  300. data/lib/mongo/operation/indexes/result.rb +1 -1
  301. data/lib/mongo/operation/insert.rb +3 -2
  302. data/lib/mongo/operation/insert/bulk_result.rb +6 -2
  303. data/lib/mongo/operation/insert/command.rb +7 -7
  304. data/lib/mongo/operation/insert/legacy.rb +9 -5
  305. data/lib/mongo/operation/insert/op_msg.rb +6 -6
  306. data/lib/mongo/operation/insert/result.rb +7 -4
  307. data/lib/mongo/operation/kill_cursors.rb +1 -1
  308. data/lib/mongo/operation/kill_cursors/command.rb +3 -3
  309. data/lib/mongo/operation/kill_cursors/legacy.rb +2 -2
  310. data/lib/mongo/operation/kill_cursors/op_msg.rb +1 -1
  311. data/lib/mongo/operation/list_collections.rb +1 -1
  312. data/lib/mongo/operation/list_collections/command.rb +4 -4
  313. data/lib/mongo/operation/list_collections/op_msg.rb +2 -2
  314. data/lib/mongo/operation/list_collections/result.rb +1 -1
  315. data/lib/mongo/operation/map_reduce.rb +1 -1
  316. data/lib/mongo/operation/map_reduce/command.rb +3 -3
  317. data/lib/mongo/operation/map_reduce/op_msg.rb +1 -1
  318. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  319. data/lib/mongo/operation/op_msg_base.rb +3 -3
  320. data/lib/mongo/operation/parallel_scan.rb +1 -1
  321. data/lib/mongo/operation/parallel_scan/command.rb +5 -5
  322. data/lib/mongo/operation/parallel_scan/op_msg.rb +2 -2
  323. data/lib/mongo/operation/parallel_scan/result.rb +1 -1
  324. data/lib/mongo/operation/remove_user.rb +1 -1
  325. data/lib/mongo/operation/remove_user/command.rb +4 -4
  326. data/lib/mongo/operation/remove_user/op_msg.rb +2 -2
  327. data/lib/mongo/operation/result.rb +28 -4
  328. data/lib/mongo/operation/shared/bypass_document_validation.rb +10 -4
  329. data/lib/mongo/operation/shared/causal_consistency_supported.rb +3 -3
  330. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +56 -0
  331. data/lib/mongo/operation/shared/executable.rb +46 -28
  332. data/lib/mongo/operation/shared/executable_no_validate.rb +3 -3
  333. data/lib/mongo/operation/shared/executable_transaction_label.rb +1 -1
  334. data/lib/mongo/operation/shared/idable.rb +1 -1
  335. data/lib/mongo/operation/shared/limited.rb +10 -2
  336. data/lib/mongo/operation/shared/object_id_generator.rb +1 -1
  337. data/lib/mongo/operation/shared/op_msg_or_command.rb +7 -5
  338. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +8 -6
  339. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +8 -6
  340. data/lib/mongo/operation/shared/polymorphic_lookup.rb +1 -1
  341. data/lib/mongo/operation/shared/polymorphic_result.rb +1 -1
  342. data/lib/mongo/operation/shared/read_preference_supported.rb +19 -16
  343. data/lib/mongo/operation/shared/response_handling.rb +83 -8
  344. data/lib/mongo/operation/shared/result/aggregatable.rb +1 -1
  345. data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +1 -1
  346. data/lib/mongo/operation/shared/sessions_supported.rb +50 -27
  347. data/lib/mongo/operation/shared/specifiable.rb +32 -20
  348. data/lib/mongo/operation/shared/write.rb +25 -19
  349. data/lib/mongo/operation/shared/write_concern_supported.rb +6 -6
  350. data/lib/mongo/operation/update.rb +1 -1
  351. data/lib/mongo/operation/update/bulk_result.rb +1 -1
  352. data/lib/mongo/operation/update/command.rb +4 -4
  353. data/lib/mongo/operation/update/legacy.rb +2 -2
  354. data/lib/mongo/operation/update/legacy/result.rb +1 -1
  355. data/lib/mongo/operation/update/op_msg.rb +4 -4
  356. data/lib/mongo/operation/update/result.rb +2 -2
  357. data/lib/mongo/operation/update_user.rb +1 -1
  358. data/lib/mongo/operation/update_user/command.rb +4 -4
  359. data/lib/mongo/operation/update_user/op_msg.rb +2 -2
  360. data/lib/mongo/operation/users_info.rb +1 -1
  361. data/lib/mongo/operation/users_info/command.rb +4 -4
  362. data/lib/mongo/operation/users_info/op_msg.rb +2 -2
  363. data/lib/mongo/operation/users_info/result.rb +1 -1
  364. data/lib/mongo/options.rb +1 -1
  365. data/lib/mongo/options/mapper.rb +1 -1
  366. data/lib/mongo/options/redacted.rb +1 -1
  367. data/lib/mongo/protocol/bit_vector.rb +1 -1
  368. data/lib/mongo/protocol/compressed.rb +1 -1
  369. data/lib/mongo/protocol/delete.rb +1 -1
  370. data/lib/mongo/protocol/get_more.rb +1 -1
  371. data/lib/mongo/protocol/insert.rb +1 -1
  372. data/lib/mongo/protocol/kill_cursors.rb +1 -1
  373. data/lib/mongo/protocol/message.rb +37 -9
  374. data/lib/mongo/protocol/msg.rb +37 -4
  375. data/lib/mongo/protocol/query.rb +1 -1
  376. data/lib/mongo/protocol/registry.rb +1 -1
  377. data/lib/mongo/protocol/reply.rb +1 -1
  378. data/lib/mongo/protocol/serializers.rb +6 -3
  379. data/lib/mongo/protocol/update.rb +1 -1
  380. data/lib/mongo/retryable.rb +23 -10
  381. data/lib/mongo/semaphore.rb +1 -1
  382. data/lib/mongo/server.rb +40 -8
  383. data/lib/mongo/server/app_metadata.rb +44 -7
  384. data/lib/mongo/server/connection.rb +37 -133
  385. data/lib/mongo/server/connection_base.rb +56 -15
  386. data/lib/mongo/server/connection_common.rb +75 -1
  387. data/lib/mongo/server/connection_pool.rb +20 -1
  388. data/lib/mongo/server/connection_pool/populator.rb +1 -1
  389. data/lib/mongo/server/context.rb +1 -1
  390. data/lib/mongo/server/description.rb +49 -2
  391. data/lib/mongo/server/description/features.rb +12 -3
  392. data/lib/mongo/server/monitor.rb +145 -69
  393. data/lib/mongo/server/monitor/app_metadata.rb +1 -1
  394. data/lib/mongo/server/monitor/connection.rb +110 -80
  395. data/lib/mongo/server/pending_connection.rb +215 -3
  396. data/lib/mongo/server/push_monitor.rb +173 -0
  397. data/{spec/runners/transactions/context.rb → lib/mongo/server/push_monitor/connection.rb} +9 -14
  398. data/lib/mongo/server/round_trip_time_averager.rb +12 -3
  399. data/lib/mongo/server_selector.rb +2 -2
  400. data/lib/mongo/server_selector/{selectable.rb → base.rb} +159 -86
  401. data/lib/mongo/server_selector/nearest.rb +26 -21
  402. data/lib/mongo/server_selector/primary.rb +24 -28
  403. data/lib/mongo/server_selector/primary_preferred.rb +32 -25
  404. data/lib/mongo/server_selector/secondary.rb +26 -21
  405. data/lib/mongo/server_selector/secondary_preferred.rb +29 -34
  406. data/lib/mongo/session.rb +14 -1
  407. data/lib/mongo/session/server_session.rb +1 -1
  408. data/lib/mongo/session/session_pool.rb +1 -1
  409. data/lib/mongo/socket.rb +121 -41
  410. data/lib/mongo/socket/ssl.rb +98 -35
  411. data/lib/mongo/socket/tcp.rb +39 -31
  412. data/lib/mongo/socket/unix.rb +14 -6
  413. data/lib/mongo/srv.rb +1 -1
  414. data/lib/mongo/srv/monitor.rb +1 -1
  415. data/lib/mongo/srv/resolver.rb +1 -1
  416. data/lib/mongo/srv/result.rb +1 -1
  417. data/lib/mongo/timeout.rb +9 -9
  418. data/lib/mongo/topology_version.rb +89 -0
  419. data/lib/mongo/uri.rb +61 -47
  420. data/lib/mongo/uri/srv_protocol.rb +9 -1
  421. data/lib/mongo/utils.rb +62 -0
  422. data/lib/mongo/version.rb +2 -2
  423. data/lib/mongo/write_concern.rb +1 -1
  424. data/lib/mongo/write_concern/acknowledged.rb +1 -1
  425. data/lib/mongo/write_concern/base.rb +1 -1
  426. data/lib/mongo/write_concern/unacknowledged.rb +1 -1
  427. data/mongo.gemspec +1 -1
  428. data/spec/NOTES.aws-auth.md +291 -0
  429. data/spec/README.aws-auth.md +318 -0
  430. data/spec/README.md +64 -17
  431. data/spec/integration/auth_spec.rb +29 -9
  432. data/spec/integration/awaited_ismaster_spec.rb +28 -0
  433. data/spec/integration/aws_auth_request_spec.rb +74 -0
  434. data/spec/integration/aws_credentials_retriever_spec.rb +103 -0
  435. data/spec/integration/bulk_write_spec.rb +19 -0
  436. data/spec/integration/change_stream_examples_spec.rb +6 -2
  437. data/spec/integration/change_stream_spec.rb +123 -51
  438. data/spec/integration/check_clean_slate_spec.rb +16 -0
  439. data/spec/integration/client_construction_aws_auth_spec.rb +191 -0
  440. data/spec/integration/client_construction_spec.rb +2 -1
  441. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +3 -3
  442. data/spec/integration/collection_indexes_prose_spec.rb +55 -0
  443. data/spec/integration/command_monitoring_spec.rb +30 -6
  444. data/spec/integration/command_spec.rb +11 -9
  445. data/spec/integration/connect_single_rs_name_spec.rb +10 -5
  446. data/spec/integration/connection_spec.rb +7 -3
  447. data/spec/integration/crud_spec.rb +32 -4
  448. data/spec/integration/cursor_reaping_spec.rb +14 -10
  449. data/spec/integration/docs_examples_spec.rb +6 -0
  450. data/spec/integration/fork_reconnect_spec.rb +143 -0
  451. data/spec/integration/get_more_spec.rb +10 -3
  452. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  453. data/spec/integration/heartbeat_events_spec.rb +5 -24
  454. data/spec/integration/read_concern_spec.rb +1 -1
  455. data/spec/integration/read_preference_spec.rb +41 -11
  456. data/spec/integration/reconnect_spec.rb +2 -3
  457. data/spec/integration/retryable_errors_spec.rb +33 -14
  458. data/spec/integration/{retryable_writes_spec.rb → retryable_writes/retryable_writes_36_and_older_spec.rb} +55 -51
  459. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +401 -0
  460. data/spec/integration/retryable_writes/shared/adds_diagnostics.rb +15 -0
  461. data/spec/integration/retryable_writes/shared/does_not_support_retries.rb +24 -0
  462. data/spec/integration/retryable_writes/shared/only_supports_legacy_retries.rb +25 -0
  463. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +215 -0
  464. data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +232 -0
  465. data/spec/integration/retryable_writes/shared/performs_no_retries.rb +110 -0
  466. data/spec/integration/retryable_writes/shared/supports_legacy_retries.rb +19 -0
  467. data/spec/integration/retryable_writes/shared/supports_modern_retries.rb +25 -0
  468. data/spec/integration/retryable_writes/shared/supports_retries.rb +16 -0
  469. data/spec/integration/sdam_error_handling_spec.rb +142 -22
  470. data/spec/integration/sdam_events_spec.rb +77 -5
  471. data/spec/integration/sdam_prose_spec.rb +64 -0
  472. data/spec/integration/server_monitor_spec.rb +25 -1
  473. data/spec/integration/server_spec.rb +42 -26
  474. data/spec/integration/size_limit_spec.rb +26 -9
  475. data/spec/integration/ssl_uri_options_spec.rb +2 -2
  476. data/spec/integration/step_down_spec.rb +15 -15
  477. data/spec/integration/transactions_api_examples_spec.rb +59 -0
  478. data/spec/integration/transactions_examples_spec.rb +5 -2
  479. data/spec/integration/x509_auth_spec.rb +109 -0
  480. data/spec/integration/zlib_compression_spec.rb +25 -0
  481. data/spec/kerberos/kerberos_spec.rb +10 -6
  482. data/spec/lite_spec_helper.rb +31 -22
  483. data/spec/mongo/address/ipv4_spec.rb +1 -1
  484. data/spec/mongo/address_spec.rb +2 -2
  485. data/spec/mongo/auth/aws/request_region_spec.rb +42 -0
  486. data/spec/mongo/auth/aws/request_spec.rb +76 -0
  487. data/spec/mongo/auth/cr_spec.rb +7 -7
  488. data/spec/mongo/auth/gssapi/conversation_spec.rb +121 -0
  489. data/spec/mongo/auth/invalid_mechanism_spec.rb +1 -1
  490. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  491. data/spec/mongo/auth/ldap_spec.rb +3 -3
  492. data/spec/mongo/auth/scram/conversation_spec.rb +119 -334
  493. data/spec/mongo/auth/scram256/conversation_spec.rb +171 -0
  494. data/spec/mongo/auth/{scram/negotiation_spec.rb → scram_negotiation_spec.rb} +13 -8
  495. data/spec/mongo/auth/scram_spec.rb +29 -69
  496. data/spec/mongo/auth/user_spec.rb +1 -1
  497. data/spec/mongo/auth/x509/conversation_spec.rb +1 -1
  498. data/spec/mongo/auth/x509_spec.rb +8 -8
  499. data/spec/mongo/auth_spec.rb +4 -4
  500. data/spec/mongo/bulk_write_spec.rb +206 -2
  501. data/spec/mongo/client_construction_spec.rb +609 -86
  502. data/spec/mongo/client_spec.rb +59 -5
  503. data/spec/mongo/cluster/topology/replica_set_spec.rb +52 -9
  504. data/spec/mongo/cluster/topology/single_spec.rb +4 -2
  505. data/spec/mongo/cluster_spec.rb +37 -36
  506. data/spec/mongo/collection/view/aggregation_spec.rb +6 -2
  507. data/spec/mongo/collection/view/builder/find_command_spec.rb +17 -6
  508. data/spec/mongo/collection/view/change_stream_resume_spec.rb +392 -0
  509. data/spec/mongo/collection/view/change_stream_spec.rb +0 -318
  510. data/spec/mongo/collection/view/iterable_spec.rb +38 -0
  511. data/spec/mongo/collection/view/map_reduce_spec.rb +6 -2
  512. data/spec/mongo/collection/view/readable_spec.rb +15 -1
  513. data/spec/mongo/collection/view/writable_spec.rb +208 -1
  514. data/spec/mongo/collection_spec.rb +531 -43
  515. data/spec/mongo/cursor/builder/get_more_command_spec.rb +6 -1
  516. data/spec/mongo/cursor/builder/op_get_more_spec.rb +6 -1
  517. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +6 -1
  518. data/spec/mongo/cursor_spec.rb +9 -1
  519. data/spec/mongo/database_spec.rb +251 -10
  520. data/spec/mongo/distinguishing_semaphore_spec.rb +63 -0
  521. data/spec/mongo/error/operation_failure_heavy_spec.rb +58 -0
  522. data/spec/mongo/error/operation_failure_spec.rb +167 -69
  523. data/spec/mongo/error/unsupported_option_spec.rb +54 -0
  524. data/spec/mongo/grid/fs_bucket_spec.rb +18 -0
  525. data/spec/mongo/grid/stream/write_spec.rb +32 -0
  526. data/spec/mongo/index/view_spec.rb +312 -0
  527. data/spec/mongo/monitoring/event/server_description_changed_spec.rb +1 -4
  528. data/spec/mongo/operation/aggregate/result_spec.rb +6 -1
  529. data/spec/mongo/operation/delete/bulk_spec.rb +18 -6
  530. data/spec/mongo/operation/delete/op_msg_spec.rb +22 -14
  531. data/spec/mongo/operation/find/legacy_spec.rb +27 -7
  532. data/spec/mongo/operation/get_more_spec.rb +6 -1
  533. data/spec/mongo/operation/insert/bulk_spec.rb +21 -7
  534. data/spec/mongo/operation/insert/command_spec.rb +4 -0
  535. data/spec/mongo/operation/insert/op_msg_spec.rb +22 -14
  536. data/spec/mongo/operation/limited_spec.rb +5 -3
  537. data/spec/mongo/operation/read_preference_legacy_spec.rb +16 -4
  538. data/spec/mongo/operation/read_preference_op_msg_spec.rb +115 -5
  539. data/spec/mongo/operation/result_spec.rb +6 -1
  540. data/spec/mongo/operation/update/bulk_spec.rb +18 -6
  541. data/spec/mongo/operation/update/command_spec.rb +4 -0
  542. data/spec/mongo/operation/update/op_msg_spec.rb +22 -14
  543. data/spec/mongo/protocol/msg_spec.rb +10 -0
  544. data/spec/mongo/retryable_spec.rb +71 -70
  545. data/spec/mongo/semaphore_spec.rb +51 -0
  546. data/spec/mongo/server/app_metadata_shared.rb +136 -0
  547. data/spec/mongo/server/app_metadata_spec.rb +8 -1
  548. data/spec/mongo/server/connection_auth_spec.rb +33 -14
  549. data/spec/mongo/server/connection_pool_spec.rb +0 -31
  550. data/spec/mongo/server/connection_spec.rb +118 -71
  551. data/spec/mongo/server/monitor/app_metadata_spec.rb +8 -1
  552. data/spec/mongo/server/monitor/connection_spec.rb +1 -82
  553. data/spec/mongo/server/monitor_spec.rb +76 -17
  554. data/spec/mongo/server/round_trip_time_averager_spec.rb +5 -3
  555. data/spec/mongo/server_selector/nearest_spec.rb +24 -23
  556. data/spec/mongo/server_selector/primary_preferred_spec.rb +27 -26
  557. data/spec/mongo/server_selector/primary_spec.rb +27 -9
  558. data/spec/mongo/server_selector/secondary_preferred_spec.rb +40 -23
  559. data/spec/mongo/server_selector/secondary_spec.rb +19 -18
  560. data/spec/mongo/server_selector_spec.rb +4 -5
  561. data/spec/mongo/session/session_pool_spec.rb +7 -3
  562. data/spec/mongo/session_spec.rb +35 -0
  563. data/spec/mongo/socket/ssl_spec.rb +2 -2
  564. data/spec/mongo/socket/tcp_spec.rb +2 -2
  565. data/spec/mongo/socket/unix_spec.rb +2 -2
  566. data/spec/mongo/socket_spec.rb +9 -9
  567. data/spec/mongo/timeout_spec.rb +22 -68
  568. data/spec/mongo/uri_spec.rb +21 -6
  569. data/spec/runners/auth.rb +5 -6
  570. data/spec/runners/change_streams/outcome.rb +42 -0
  571. data/spec/runners/change_streams/spec.rb +57 -0
  572. data/spec/runners/change_streams/test.rb +229 -0
  573. data/spec/runners/cmap.rb +1 -1
  574. data/spec/runners/cmap/verifier.rb +1 -1
  575. data/spec/runners/command_monitoring.rb +4 -35
  576. data/spec/runners/connection_string.rb +3 -2
  577. data/spec/runners/crud.rb +2 -2
  578. data/spec/runners/crud/context.rb +10 -6
  579. data/spec/runners/crud/operation.rb +177 -55
  580. data/spec/runners/crud/outcome.rb +1 -1
  581. data/spec/runners/crud/spec.rb +0 -7
  582. data/spec/runners/crud/test.rb +8 -26
  583. data/spec/runners/crud/test_base.rb +47 -0
  584. data/spec/runners/crud/verifier.rb +21 -3
  585. data/spec/runners/gridfs.rb +1 -1
  586. data/spec/runners/{server_discovery_and_monitoring.rb → sdam.rb} +41 -22
  587. data/spec/runners/sdam/verifier.rb +26 -8
  588. data/spec/runners/server_selection.rb +242 -28
  589. data/spec/runners/transactions.rb +13 -14
  590. data/spec/runners/transactions/operation.rb +155 -25
  591. data/spec/runners/transactions/spec.rb +1 -1
  592. data/spec/runners/transactions/test.rb +103 -65
  593. data/spec/spec_tests/auth_spec.rb +2 -0
  594. data/spec/spec_tests/change_streams_spec.rb +39 -4
  595. data/spec/spec_tests/client_side_encryption_spec.rb +3 -0
  596. data/spec/spec_tests/cmap_spec.rb +5 -0
  597. data/spec/spec_tests/command_monitoring_spec.rb +25 -12
  598. data/spec/spec_tests/connection_string_spec.rb +2 -0
  599. data/spec/spec_tests/crud_spec.rb +3 -1
  600. data/spec/spec_tests/data/auth/connection-string.yml +57 -1
  601. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +27 -1
  602. data/spec/spec_tests/data/change_streams/change-streams-resume-errorLabels.yml +1105 -0
  603. data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +1173 -0
  604. data/spec/spec_tests/data/change_streams/change-streams.yml +5 -4
  605. data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +1 -1
  606. data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +33 -11
  607. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint-clientError.yml +63 -0
  608. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint-serverError.yml +92 -0
  609. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint.yml +103 -0
  610. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint-clientError.yml +90 -0
  611. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint-serverError.yml +147 -0
  612. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint.yml +164 -0
  613. data/spec/spec_tests/data/crud_v2/deleteMany-hint-clientError.yml +43 -0
  614. data/spec/spec_tests/data/crud_v2/deleteMany-hint-serverError.yml +62 -0
  615. data/spec/spec_tests/data/crud_v2/deleteMany-hint.yml +58 -0
  616. data/spec/spec_tests/data/crud_v2/deleteOne-hint-clientError.yml +41 -0
  617. data/spec/spec_tests/data/crud_v2/deleteOne-hint-serverError.yml +60 -0
  618. data/spec/spec_tests/data/crud_v2/deleteOne-hint.yml +57 -0
  619. data/spec/spec_tests/data/crud_v2/find-allowdiskuse-clientError.yml +28 -0
  620. data/spec/spec_tests/data/crud_v2/find-allowdiskuse-serverError.yml +44 -0
  621. data/spec/spec_tests/data/crud_v2/find-allowdiskuse.yml +50 -0
  622. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint-clientError.yml +45 -0
  623. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint-serverError.yml +60 -0
  624. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint.yml +56 -0
  625. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint-clientError.yml +40 -0
  626. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint-serverError.yml +59 -0
  627. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint.yml +55 -0
  628. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint-clientError.yml +40 -0
  629. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint-serverError.yml +58 -0
  630. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint.yml +55 -0
  631. data/spec/spec_tests/data/crud_v2/replaceOne-hint.yml +61 -0
  632. data/spec/spec_tests/data/crud_v2/unacknowledged-bulkWrite-delete-hint-clientError.yml +60 -0
  633. data/spec/spec_tests/data/crud_v2/unacknowledged-bulkWrite-update-hint-clientError.yml +88 -0
  634. data/spec/spec_tests/data/crud_v2/unacknowledged-deleteMany-hint-clientError.yml +40 -0
  635. data/spec/spec_tests/data/crud_v2/unacknowledged-deleteOne-hint-clientError.yml +38 -0
  636. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndDelete-hint-clientError.yml +42 -0
  637. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndReplace-hint-clientError.yml +40 -0
  638. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndUpdate-hint-clientError.yml +40 -0
  639. data/spec/spec_tests/data/crud_v2/unacknowledged-replaceOne-hint-clientError.yml +40 -0
  640. data/spec/spec_tests/data/crud_v2/unacknowledged-updateMany-hint-clientError.yml +43 -0
  641. data/spec/spec_tests/data/crud_v2/unacknowledged-updateOne-hint-clientError.yml +40 -0
  642. data/spec/spec_tests/data/crud_v2/updateMany-hint-clientError.yml +45 -0
  643. data/spec/spec_tests/data/crud_v2/updateMany-hint-serverError.yml +66 -0
  644. data/spec/spec_tests/data/crud_v2/updateMany-hint.yml +65 -0
  645. data/spec/spec_tests/data/crud_v2/updateOne-hint-clientError.yml +43 -0
  646. data/spec/spec_tests/data/crud_v2/updateOne-hint-serverError.yml +62 -0
  647. data/spec/spec_tests/data/crud_v2/updateOne-hint.yml +61 -0
  648. data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +65 -0
  649. data/spec/spec_tests/data/dns_seedlist_discovery/direct-connection-false.yml +10 -0
  650. data/spec/spec_tests/data/dns_seedlist_discovery/direct-connection-true.yml +5 -0
  651. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.yml +15 -0
  652. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +4 -3
  653. data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -0
  654. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-2.6.yml +215 -0
  655. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-3.2.yml +58 -0
  656. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-3.4.yml +95 -0
  657. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-4.2.yml +36 -0
  658. data/spec/spec_tests/data/retryable_writes/bulkWrite-errorLabels.yml +77 -0
  659. data/spec/spec_tests/data/retryable_writes/bulkWrite-serverErrors.yml +37 -0
  660. data/spec/spec_tests/data/retryable_writes/deleteOne-errorLabels.yml +48 -0
  661. data/spec/spec_tests/data/retryable_writes/deleteOne-serverErrors.yml +22 -0
  662. data/spec/spec_tests/data/retryable_writes/findOneAndDelete-errorLabels.yml +49 -0
  663. data/spec/spec_tests/data/retryable_writes/findOneAndDelete-serverErrors.yml +23 -0
  664. data/spec/spec_tests/data/retryable_writes/findOneAndReplace-errorLabels.yml +52 -0
  665. data/spec/spec_tests/data/retryable_writes/findOneAndReplace-serverErrors.yml +25 -0
  666. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-errorLabels.yml +52 -0
  667. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-serverErrors.yml +24 -0
  668. data/spec/spec_tests/data/retryable_writes/insertMany-errorLabels.yml +54 -0
  669. data/spec/spec_tests/data/retryable_writes/insertMany-serverErrors.yml +24 -0
  670. data/spec/spec_tests/data/retryable_writes/insertOne-errorLabels.yml +44 -0
  671. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +69 -0
  672. data/spec/spec_tests/data/retryable_writes/replaceOne-errorLabels.yml +53 -0
  673. data/spec/spec_tests/data/retryable_writes/replaceOne-serverErrors.yml +23 -0
  674. data/spec/spec_tests/data/retryable_writes/updateOne-errorLabels.yml +53 -0
  675. data/spec/spec_tests/data/retryable_writes/updateOne-serverErrors.yml +23 -0
  676. data/spec/spec_tests/data/sdam/errors/error_handling_handshake.yml +54 -0
  677. data/spec/spec_tests/data/sdam/errors/non-stale-network-error.yml +46 -0
  678. data/spec/spec_tests/data/sdam/errors/non-stale-network-timeout-error.yml +37 -0
  679. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-InterruptedAtShutdown.yml +60 -0
  680. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-InterruptedDueToReplStateChange.yml +60 -0
  681. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMaster.yml +60 -0
  682. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMasterNoSlaveOk.yml +60 -0
  683. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMasterOrSecondary.yml +60 -0
  684. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-PrimarySteppedDown.yml +60 -0
  685. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-ShutdownInProgress.yml +60 -0
  686. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-InterruptedAtShutdown.yml +51 -0
  687. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-InterruptedDueToReplStateChange.yml +51 -0
  688. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMaster.yml +51 -0
  689. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMasterNoSlaveOk.yml +51 -0
  690. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMasterOrSecondary.yml +51 -0
  691. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-PrimarySteppedDown.yml +51 -0
  692. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-ShutdownInProgress.yml +51 -0
  693. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-InterruptedAtShutdown.yml +60 -0
  694. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-InterruptedDueToReplStateChange.yml +60 -0
  695. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMaster.yml +60 -0
  696. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMasterNoSlaveOk.yml +60 -0
  697. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMasterOrSecondary.yml +60 -0
  698. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-PrimarySteppedDown.yml +60 -0
  699. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-ShutdownInProgress.yml +60 -0
  700. data/spec/spec_tests/data/sdam/errors/post-42-InterruptedAtShutdown.yml +46 -0
  701. data/spec/spec_tests/data/sdam/errors/post-42-InterruptedDueToReplStateChange.yml +46 -0
  702. data/spec/spec_tests/data/sdam/errors/post-42-NotMaster.yml +46 -0
  703. data/spec/spec_tests/data/sdam/errors/post-42-NotMasterNoSlaveOk.yml +46 -0
  704. data/spec/spec_tests/data/sdam/errors/post-42-NotMasterOrSecondary.yml +46 -0
  705. data/spec/spec_tests/data/sdam/errors/post-42-PrimarySteppedDown.yml +46 -0
  706. data/spec/spec_tests/data/sdam/errors/post-42-ShutdownInProgress.yml +46 -0
  707. data/spec/spec_tests/data/sdam/errors/pre-42-InterruptedAtShutdown.yml +46 -0
  708. data/spec/spec_tests/data/sdam/errors/pre-42-InterruptedDueToReplStateChange.yml +46 -0
  709. data/spec/spec_tests/data/sdam/errors/pre-42-NotMaster.yml +46 -0
  710. data/spec/spec_tests/data/sdam/errors/pre-42-NotMasterNoSlaveOk.yml +46 -0
  711. data/spec/spec_tests/data/sdam/errors/pre-42-NotMasterOrSecondary.yml +46 -0
  712. data/spec/spec_tests/data/sdam/errors/pre-42-PrimarySteppedDown.yml +46 -0
  713. data/spec/spec_tests/data/sdam/errors/pre-42-ShutdownInProgress.yml +46 -0
  714. data/spec/spec_tests/data/sdam/errors/stale-generation-InterruptedAtShutdown.yml +89 -0
  715. data/spec/spec_tests/data/sdam/errors/stale-generation-InterruptedDueToReplStateChange.yml +89 -0
  716. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMaster.yml +89 -0
  717. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMasterNoSlaveOk.yml +89 -0
  718. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMasterOrSecondary.yml +89 -0
  719. data/spec/spec_tests/data/sdam/errors/stale-generation-PrimarySteppedDown.yml +89 -0
  720. data/spec/spec_tests/data/sdam/errors/stale-generation-ShutdownInProgress.yml +89 -0
  721. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-InterruptedAtShutdown.yml +89 -0
  722. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-InterruptedDueToReplStateChange.yml +89 -0
  723. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMaster.yml +89 -0
  724. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMasterNoSlaveOk.yml +89 -0
  725. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMasterOrSecondary.yml +89 -0
  726. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-PrimarySteppedDown.yml +89 -0
  727. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-ShutdownInProgress.yml +89 -0
  728. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-network.yml +80 -0
  729. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-timeout.yml +80 -0
  730. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-InterruptedAtShutdown.yml +89 -0
  731. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-InterruptedDueToReplStateChange.yml +89 -0
  732. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMaster.yml +89 -0
  733. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMasterNoSlaveOk.yml +89 -0
  734. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMasterOrSecondary.yml +89 -0
  735. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-PrimarySteppedDown.yml +89 -0
  736. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-ShutdownInProgress.yml +89 -0
  737. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-network.yml +80 -0
  738. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-timeout.yml +80 -0
  739. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-InterruptedAtShutdown.yml +64 -0
  740. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-InterruptedDueToReplStateChange.yml +64 -0
  741. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMaster.yml +64 -0
  742. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMasterNoSlaveOk.yml +64 -0
  743. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMasterOrSecondary.yml +64 -0
  744. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-PrimarySteppedDown.yml +64 -0
  745. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-ShutdownInProgress.yml +64 -0
  746. data/spec/spec_tests/data/sdam/rs/compatible.yml +2 -0
  747. data/spec/spec_tests/data/sdam/rs/compatible_unknown.yml +2 -0
  748. data/spec/spec_tests/data/sdam/rs/discover_arbiters.yml +2 -2
  749. data/spec/spec_tests/data/sdam/rs/discover_arbiters_replicaset.yml +43 -0
  750. data/spec/spec_tests/data/sdam/rs/discover_ghost.yml +35 -0
  751. data/spec/spec_tests/data/sdam/rs/{ghost_discovered.yml → discover_ghost_replicaset.yml} +1 -1
  752. data/spec/spec_tests/data/sdam/rs/discover_hidden.yml +50 -0
  753. data/spec/spec_tests/data/sdam/rs/discover_hidden_replicaset.yml +50 -0
  754. data/spec/spec_tests/data/sdam/rs/discover_passives.yml +2 -2
  755. data/spec/spec_tests/data/sdam/rs/discover_passives_replicaset.yml +81 -0
  756. data/spec/spec_tests/data/sdam/rs/discover_primary.yml +2 -2
  757. data/spec/spec_tests/data/sdam/rs/discover_primary_replicaset.yml +42 -0
  758. data/spec/spec_tests/data/sdam/rs/discover_rsother.yml +49 -0
  759. data/spec/spec_tests/data/sdam/rs/{rsother_discovered.yml → discover_rsother_replicaset.yml} +1 -1
  760. data/spec/spec_tests/data/sdam/rs/discover_secondary.yml +2 -2
  761. data/spec/spec_tests/data/sdam/rs/discover_secondary_replicaset.yml +43 -0
  762. data/spec/spec_tests/data/sdam/rs/incompatible_arbiter.yml +2 -0
  763. data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +2 -0
  764. data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +2 -0
  765. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me.yml +23 -27
  766. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +79 -55
  767. data/spec/spec_tests/data/sdam/rs/replicaset_rsnp.yml +20 -0
  768. data/spec/spec_tests/data/sdam/rs/secondary_mismatched_me.yml +3 -2
  769. data/spec/spec_tests/data/sdam/rs/too_new.yml +2 -0
  770. data/spec/spec_tests/data/sdam/rs/topology_version_equal.yml +66 -0
  771. data/spec/spec_tests/data/sdam/rs/topology_version_greater.yml +189 -0
  772. data/spec/spec_tests/data/sdam/rs/topology_version_less.yml +62 -0
  773. data/spec/spec_tests/data/sdam/sharded/discover_single_mongos.yml +23 -0
  774. data/spec/spec_tests/data/sdam/single/direct_connection_external_ip.yml +1 -1
  775. data/spec/spec_tests/data/sdam/single/direct_connection_mongos.yml +2 -2
  776. data/spec/spec_tests/data/sdam/single/direct_connection_replicaset.yml +22 -0
  777. data/spec/spec_tests/data/sdam/single/direct_connection_rsarbiter.yml +2 -2
  778. data/spec/spec_tests/data/sdam/single/direct_connection_rsprimary.yml +2 -2
  779. data/spec/spec_tests/data/sdam/single/direct_connection_rssecondary.yml +2 -2
  780. data/spec/spec_tests/data/sdam/single/direct_connection_slave.yml +1 -1
  781. data/spec/spec_tests/data/sdam/single/direct_connection_standalone.yml +2 -2
  782. data/spec/spec_tests/data/sdam/single/{unavailable_seed.yml → direct_connection_unavailable_seed.yml} +2 -2
  783. data/spec/spec_tests/data/sdam/single/direct_connection_wrong_set_name.yml +38 -0
  784. data/spec/spec_tests/data/sdam/single/discover_standalone.yml +34 -0
  785. data/spec/spec_tests/data/sdam/single/discover_unavailable_seed.yml +28 -0
  786. data/spec/spec_tests/data/sdam/single/too_old_then_upgraded.yml +46 -0
  787. data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +96 -0
  788. data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +88 -0
  789. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +83 -0
  790. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +116 -0
  791. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +86 -0
  792. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +115 -0
  793. data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +168 -0
  794. data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +162 -0
  795. data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +229 -0
  796. data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +87 -0
  797. data/spec/spec_tests/data/transactions/create-collection.yml +131 -0
  798. data/spec/spec_tests/data/transactions/create-index.yml +152 -0
  799. data/spec/spec_tests/data/transactions/error-labels.yml +87 -21
  800. data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +1 -0
  801. data/spec/spec_tests/data/transactions/retryable-abort-errorLabels.yml +124 -0
  802. data/spec/spec_tests/data/transactions/retryable-abort.yml +17 -2
  803. data/spec/spec_tests/data/transactions/retryable-commit-errorLabels.yml +132 -0
  804. data/spec/spec_tests/data/transactions/retryable-commit.yml +24 -9
  805. data/spec/spec_tests/data/uri_options/connection-options.yml +43 -0
  806. data/spec/spec_tests/data/uri_options/ruby-auth-options.yml +12 -0
  807. data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +57 -0
  808. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +3 -1
  809. data/spec/spec_tests/gridfs_spec.rb +2 -0
  810. data/spec/spec_tests/max_staleness_spec.rb +5 -141
  811. data/spec/spec_tests/read_write_concern_connection_string_spec.rb +2 -0
  812. data/spec/spec_tests/read_write_concern_operaton_spec.rb +10 -0
  813. data/spec/spec_tests/retryable_reads_spec.rb +4 -2
  814. data/spec/spec_tests/retryable_writes_spec.rb +8 -1
  815. data/spec/spec_tests/sdam_integration_spec.rb +13 -0
  816. data/spec/spec_tests/sdam_monitoring_spec.rb +3 -2
  817. data/spec/spec_tests/sdam_spec.rb +70 -1
  818. data/spec/spec_tests/server_selection_rtt_spec.rb +2 -0
  819. data/spec/spec_tests/server_selection_spec.rb +5 -115
  820. data/spec/spec_tests/transactions_api_spec.rb +5 -0
  821. data/spec/spec_tests/transactions_spec.rb +5 -0
  822. data/spec/spec_tests/uri_options_spec.rb +2 -0
  823. data/spec/stress/cleanup_spec.rb +58 -0
  824. data/spec/stress/connection_pool_stress_spec.rb +11 -13
  825. data/spec/stress/connection_pool_timing_spec.rb +3 -6
  826. data/spec/stress/fork_reconnect_stress_spec.rb +109 -0
  827. data/spec/support/authorization.rb +1 -11
  828. data/spec/support/aws_utils.rb +62 -0
  829. data/spec/support/aws_utils/base.rb +134 -0
  830. data/spec/support/aws_utils/inspector.rb +224 -0
  831. data/spec/support/aws_utils/orchestrator.rb +370 -0
  832. data/spec/support/aws_utils/provisioner.rb +360 -0
  833. data/spec/support/background_thread_registry.rb +6 -2
  834. data/spec/support/child_process_helper.rb +78 -0
  835. data/spec/support/client_registry.rb +6 -24
  836. data/spec/support/cluster_config.rb +5 -0
  837. data/spec/support/common_shortcuts.rb +43 -0
  838. data/spec/support/constraints.rb +27 -7
  839. data/spec/support/crypt.rb +1 -1
  840. data/spec/support/event_subscriber.rb +184 -84
  841. data/spec/support/keyword_struct.rb +26 -0
  842. data/spec/support/lite_constraints.rb +47 -0
  843. data/spec/support/shared/scram_conversation.rb +100 -0
  844. data/spec/support/shared/server_selector.rb +93 -1
  845. data/spec/support/shared/session.rb +29 -21
  846. data/spec/support/spec_config.rb +76 -21
  847. data/spec/support/spec_organizer.rb +129 -0
  848. data/spec/support/spec_setup.rb +9 -5
  849. data/spec/support/utils.rb +161 -24
  850. metadata +1189 -742
  851. metadata.gz.sig +0 -0
  852. data/lib/mongo/server/connectable.rb +0 -107
  853. data/spec/runners/change_streams.rb +0 -262
  854. data/spec/runners/change_streams/operation.rb +0 -89
  855. data/spec/runners/sdam_monitoring.rb +0 -89
  856. data/spec/spec_tests/data/sdam/sharded/ruby_discovered_single_mongos.yml +0 -27
@@ -0,0 +1,173 @@
1
+ # Copyright (C) 2020 MongoDB Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Server
17
+
18
+ # A monitor utilizing server-pushed ismaster requests.
19
+ #
20
+ # When a Monitor handshakes with a 4.4+ server, it creates an instance
21
+ # of PushMonitor. PushMonitor subsequently executes server-pushed ismaster
22
+ # (i.e. awaited & exhausted ismaster) to receive topology changes from the
23
+ # server as quickly as possible. The Monitor still monitors the server
24
+ # for round-trip time calculations and to perform immediate checks as
25
+ # requested by the application.
26
+ #
27
+ # @api private
28
+ class PushMonitor
29
+ extend Forwardable
30
+ include BackgroundThread
31
+
32
+ def initialize(monitor, topology_version, monitoring, **options)
33
+ if topology_version.nil?
34
+ raise ArgumentError, 'Topology version must be provided but it was nil'
35
+ end
36
+ @monitor = monitor
37
+ @topology_version = topology_version
38
+ @monitoring = monitoring
39
+ @options = options
40
+ @lock = Mutex.new
41
+ end
42
+
43
+ # @return [ Monitor ] The monitor to which this push monitor is attached.
44
+ attr_reader :monitor
45
+
46
+ # @return [ TopologyVersion ] Most recently received topology version.
47
+ attr_reader :topology_version
48
+
49
+ # @return [ Monitoring ] monitoring The monitoring.
50
+ attr_reader :monitoring
51
+
52
+ # @return [ Hash ] Push monitor options.
53
+ attr_reader :options
54
+
55
+ # @return [ Server ] The server that is being monitored.
56
+ def_delegator :monitor, :server
57
+
58
+ def start!
59
+ @lock.synchronize do
60
+ super
61
+ end
62
+ end
63
+
64
+ def stop!
65
+ @lock.synchronize do
66
+ @stop_requested = true
67
+ if @connection
68
+ # Interrupt any in-progress exhausted ismaster reads by
69
+ # disconnecting the connection.
70
+ @connection.send(:socket).close
71
+ end
72
+ end
73
+ super.tap do
74
+ @lock.synchronize do
75
+ if @connection
76
+ @connection.disconnect!
77
+ @connection = nil
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ def do_work
84
+ @lock.synchronize do
85
+ return if @stop_requested
86
+ end
87
+
88
+ result = monitoring.publish_heartbeat(server, awaited: true) do
89
+ ismaster
90
+ end
91
+ new_description = monitor.run_sdam_flow(result, awaited: true)
92
+ # When ismaster fails due to a fail point, the response does not
93
+ # include topology version. In this case we need to keep our existing
94
+ # topology version so that we can resume monitoring.
95
+ # The spec does not appear to directly address this case but
96
+ # https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-monitoring.rst#streaming-ismaster
97
+ # says that topologyVersion should only be updated from successful
98
+ # ismaster responses.
99
+ if new_description.topology_version
100
+ @topology_version = new_description.topology_version
101
+ end
102
+ rescue Mongo::Error => exc
103
+ msg = "Error running awaited ismaster on #{server.address}"
104
+ Utils.warn_monitor_exception(msg, exc,
105
+ logger: options[:logger],
106
+ log_prefix: options[:log_prefix],
107
+ bg_error_backtrace: options[:bg_error_backtrace],
108
+ )
109
+ end
110
+
111
+ def ismaster
112
+ @lock.synchronize do
113
+ if @connection && @connection.pid != Process.pid
114
+ log_warn("Detected PID change - Mongo client should have been reconnected (old pid #{@connection.pid}, new pid #{Process.pid}")
115
+ @connection.disconnect!
116
+ @connection = nil
117
+ end
118
+ end
119
+
120
+ @lock.synchronize do
121
+ unless @connection
122
+ @server_pushing = false
123
+ connection = PushMonitor::Connection.new(server.address, options)
124
+ connection.connect!
125
+ @connection = connection
126
+ end
127
+ end
128
+
129
+ resp_msg = begin
130
+ unless @server_pushing
131
+ write_ismaster
132
+ end
133
+ read_response
134
+ rescue Mongo::Error
135
+ @lock.synchronize do
136
+ @connection.disconnect!
137
+ @connection = nil
138
+ end
139
+ raise
140
+ end
141
+ @server_pushing = resp_msg.flags.include?(:more_to_come)
142
+ result = resp_msg.documents.first
143
+ end
144
+
145
+ def write_ismaster
146
+ payload = Monitor::Connection::ISMASTER_OP_MSG.merge(
147
+ topologyVersion: topology_version.to_doc,
148
+ maxAwaitTimeMS: monitor.heartbeat_interval * 1000,
149
+ )
150
+
151
+ req_msg = Protocol::Msg.new([:exhaust_allowed], {}, payload)
152
+ @lock.synchronize { @connection }.write_bytes(req_msg.serialize.to_s)
153
+ end
154
+
155
+ def read_response
156
+ if timeout = options[:connect_timeout]
157
+ if timeout < 0
158
+ raise Mongo::SocketTimeoutError, "Requested to read with a negative timeout: #{}"
159
+ elsif timeout > 0
160
+ timeout += options[:heartbeat_frequency] || Monitor::DEFAULT_HEARTBEAT_INTERVAL
161
+ end
162
+ end
163
+ # We set the timeout twice: once passed into read_socket which applies
164
+ # to each individual read operation, and again around the entire read.
165
+ Timeout.timeout(timeout, Error::SocketTimeoutError, "Failed to read an awaited ismaster response in #{timeout} seconds") do
166
+ @lock.synchronize { @connection }.read_response(socket_timeout: timeout)
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+
173
+ require 'mongo/server/push_monitor/connection'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2019 MongoDB, Inc.
1
+ # Copyright (C) 2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -13,19 +13,14 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Mongo
16
- module Transactions
17
- Context = Struct.new(
18
- :session0,
19
- :session1,
20
- :session,
21
- ) do
22
- def transform_arguments(arguments)
23
- arguments.dup.tap do |out|
24
- [:session].each do |key|
25
- if out[key]
26
- out[key] = send(key)
27
- end
28
- end
16
+ class Server
17
+ class PushMonitor
18
+
19
+ # @api private
20
+ class Connection < Server::Monitor::Connection
21
+
22
+ def socket_timeout
23
+ options[:socket_timeout]
29
24
  end
30
25
  end
31
26
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2018-2019 MongoDB, Inc.
1
+ # Copyright (C) 2018-2020 MongoDB Inc.
2
2
 
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -34,7 +34,12 @@ module Mongo
34
34
  start = Time.now
35
35
  begin
36
36
  rv = yield
37
- rescue Exception => exc
37
+ rescue Error::SocketError, Error::SocketTimeoutError
38
+ # If we encountered a network error, the round-trip is not
39
+ # complete and thus RTT for it does not make sense.
40
+ raise
41
+ rescue Error, Error::AuthError => exc
42
+ # For other errors, RTT is valid.
38
43
  end
39
44
  last_round_trip_time = Time.now - start
40
45
 
@@ -46,7 +51,11 @@ module Mongo
46
51
  update_average_round_trip_time
47
52
  end
48
53
 
49
- [rv, exc, last_round_trip_time, average_round_trip_time]
54
+ if exc
55
+ raise exc
56
+ else
57
+ rv
58
+ end
50
59
  end
51
60
 
52
61
  private
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2019 MongoDB, Inc.
1
+ # Copyright (C) 2014-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'mongo/server_selector/selectable'
15
+ require 'mongo/server_selector/base'
16
16
  require 'mongo/server_selector/nearest'
17
17
  require 'mongo/server_selector/primary'
18
18
  require 'mongo/server_selector/primary_preferred'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2019 MongoDB, Inc.
1
+ # Copyright (C) 2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -13,12 +13,10 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Mongo
16
+
16
17
  module ServerSelector
17
18
 
18
- # Provides common behavior for filtering a list of servers by server mode or tag set.
19
- #
20
- # @since 2.0.0
21
- module Selectable
19
+ class Base
22
20
 
23
21
  # Initialize the server selector.
24
22
  #
@@ -36,19 +34,25 @@ module Mongo
36
34
  # in seconds, that a secondary can suffer and still be eligible for a read.
37
35
  # A value of -1 is treated identically to nil, which is to not
38
36
  # have a maximum staleness.
37
+ # @option options [ Hash | nil ] hedge A Hash specifying whether to enable hedged
38
+ # reads on the server. Hedged reads are not enabled by default. When
39
+ # specifying this option, it must be in the format: { enabled: true },
40
+ # where the value of the :enabled key is a boolean value.
39
41
  #
40
42
  # @raise [ Error::InvalidServerPreference ] If tag sets are specified
41
43
  # but not allowed.
42
44
  #
43
- # @since 2.0.0
45
+ # @api private
44
46
  def initialize(options = nil)
45
47
  options = options ? options.dup : {}
46
48
  if options[:max_staleness] == -1
47
49
  options.delete(:max_staleness)
48
50
  end
49
- @options = options.freeze
50
- @tag_sets = (options[:tag_sets] || []).freeze
51
+ @options = options
52
+ @tag_sets = options[:tag_sets] || []
51
53
  @max_staleness = options[:max_staleness]
54
+ @hedge = options[:hedge]
55
+
52
56
  validate!
53
57
  end
54
58
 
@@ -58,26 +62,50 @@ module Mongo
58
62
  # @return [ Array ] tag_sets The tag sets used to select servers.
59
63
  attr_reader :tag_sets
60
64
 
61
- # @return [ Integer ] max_staleness The maximum replication lag, in seconds, that a
62
- # secondary can suffer and still be eligible for a read.
65
+ # @return [ Integer ] max_staleness The maximum replication lag, in
66
+ # seconds, that a secondary can suffer and still be eligible for a read.
63
67
  #
64
68
  # @since 2.4.0
65
69
  attr_reader :max_staleness
66
70
 
67
- # Check equality of two server selector.
71
+ # @return [ Hash | nil ] hedge The document specifying whether to enable
72
+ # hedged reads.
73
+ attr_reader :hedge
74
+
75
+ # Get the timeout for server selection.
68
76
  #
69
- # @example Check server selector equality.
70
- # preference == other
77
+ # @example Get the server selection timeout, in seconds.
78
+ # selector.server_selection_timeout
71
79
  #
72
- # @param [ Object ] other The other preference.
80
+ # @return [ Float ] The timeout.
73
81
  #
74
- # @return [ true, false ] Whether the objects are equal.
82
+ # @since 2.0.0
83
+ #
84
+ # @deprecated This setting is now taken from the cluster options when
85
+ # a server is selected. Will be removed in version 3.0.
86
+ def server_selection_timeout
87
+ @server_selection_timeout ||=
88
+ (options[:server_selection_timeout] || ServerSelector::SERVER_SELECTION_TIMEOUT)
89
+ end
90
+
91
+ # Get the local threshold boundary for nearest selection in seconds.
92
+ #
93
+ # @example Get the local threshold.
94
+ # selector.local_threshold
95
+ #
96
+ # @return [ Float ] The local threshold.
75
97
  #
76
98
  # @since 2.0.0
77
- def ==(other)
78
- name == other.name &&
79
- tag_sets == other.tag_sets &&
80
- max_staleness == other.max_staleness
99
+ #
100
+ # @deprecated This setting is now taken from the cluster options when
101
+ # a server is selected. Will be removed in version 3.0.
102
+ def local_threshold
103
+ @local_threshold ||= (options[:local_threshold] || ServerSelector::LOCAL_THRESHOLD)
104
+ end
105
+
106
+ # @api private
107
+ def local_threshold_with_cluster(cluster)
108
+ options[:local_threshold] || cluster.options[:local_threshold] || LOCAL_THRESHOLD
81
109
  end
82
110
 
83
111
  # Inspect the server selector.
@@ -89,7 +117,22 @@ module Mongo
89
117
  #
90
118
  # @since 2.2.0
91
119
  def inspect
92
- "#<#{self.class.name}:0x#{object_id} tag_sets=#{tag_sets.inspect} max_staleness=#{max_staleness.inspect}>"
120
+ "#<#{self.class.name}:0x#{object_id} tag_sets=#{tag_sets.inspect} max_staleness=#{max_staleness.inspect} hedge=#{hedge}>"
121
+ end
122
+
123
+ # Check equality of two server selectors.
124
+ #
125
+ # @example Check server selector equality.
126
+ # preference == other
127
+ #
128
+ # @param [ Object ] other The other preference.
129
+ #
130
+ # @return [ true, false ] Whether the objects are equal.
131
+ #
132
+ # @since 2.0.0
133
+ def ==(other)
134
+ name == other.name && hedge == other.hedge &&
135
+ max_staleness == other.max_staleness && tag_sets == other.tag_sets
93
136
  end
94
137
 
95
138
  # Select a server from the specified cluster, taking into account
@@ -174,6 +217,7 @@ module Mongo
174
217
  if cluster.replica_set?
175
218
  validate_max_staleness_value_early!
176
219
  end
220
+
177
221
  if cluster.addresses.empty?
178
222
  if Lint.enabled?
179
223
  unless cluster.servers.empty?
@@ -183,46 +227,22 @@ module Mongo
183
227
  msg = "Cluster has no addresses, and therefore will never have a server"
184
228
  raise Error::NoServerAvailable.new(self, cluster, msg)
185
229
  end
230
+
186
231
  =begin Add this check in version 3.0.0
187
232
  unless cluster.connected?
188
233
  msg = 'Cluster is disconnected'
189
234
  raise Error::NoServerAvailable.new(self, cluster, msg)
190
235
  end
191
236
  =end
237
+
192
238
  loop do
193
- servers = candidates(cluster)
194
- if Lint.enabled?
195
- servers.each do |server|
196
- # It is possible for a server to have a nil average RTT here
197
- # because the ARTT comes from description which may be updated
198
- # by a background thread while server selection is running.
199
- # Currently lint mode is not a public feature, if/when this
200
- # changes (https://jira.mongodb.org/browse/RUBY-1576) the
201
- # requirement for ARTT to be not nil would need to be removed.
202
- if server.average_round_trip_time.nil?
203
- raise Error::LintError, "Server #{server.address} has nil average rtt"
204
- end
205
- end
206
- end
207
- if servers && !servers.compact.empty?
239
+ server = try_select_server(cluster)
240
+
241
+ if server
208
242
  unless cluster.topology.compatible?
209
243
  raise Error::UnsupportedFeatures, cluster.topology.compatibility_error.to_s
210
244
  end
211
245
 
212
- # This list of servers may be ordered in a specific way
213
- # by the selector (e.g. for secondary preferred, the first
214
- # server may be a secondary and the second server may be primary)
215
- # and we should take the first server here respecting the order
216
- server = servers.first
217
-
218
- if cluster.topology.single? &&
219
- cluster.topology.replica_set_name &&
220
- cluster.topology.replica_set_name != server.description.replica_set_name
221
- then
222
- msg = "Cluster topology specifies replica set name #{cluster.topology.replica_set_name}, but the server has replica set name #{server.description.replica_set_name || '<nil>'}"
223
- raise Error::NoServerAvailable.new(self, cluster, msg)
224
- end
225
-
226
246
  if session && session.starting_transaction? && cluster.sharded?
227
247
  session.pin(server)
228
248
  end
@@ -260,67 +280,106 @@ module Mongo
260
280
  raise e
261
281
  end
262
282
 
263
- # Get the timeout for server selection.
264
- #
265
- # @example Get the server selection timeout, in seconds.
266
- # selector.server_selection_timeout
267
- #
268
- # @return [ Float ] The timeout.
283
+ # Tries to find a suitable server, returns the server if one is available
284
+ # or nil if there isn't a suitable server.
269
285
  #
270
- # @since 2.0.0
286
+ # @return [ Server | nil ] A suitable server, if one exists.
271
287
  #
272
- # @deprecated This setting is now taken from the cluster options when a server is selected.
273
- # Will be removed in 3.0.
274
- def server_selection_timeout
275
- @server_selection_timeout ||=
276
- (options[:server_selection_timeout] || ServerSelector::SERVER_SELECTION_TIMEOUT)
277
- end
288
+ # @api private
289
+ def try_select_server(cluster)
290
+ servers = suitable_servers(cluster)
278
291
 
279
- def local_threshold_with_cluster(cluster)
280
- options[:local_threshold] || cluster.options[:local_threshold] || LOCAL_THRESHOLD
292
+ # This list of servers may be ordered in a specific way
293
+ # by the selector (e.g. for secondary preferred, the first
294
+ # server may be a secondary and the second server may be primary)
295
+ # and we should take the first server here respecting the order
296
+ server = servers.first
297
+
298
+ if server
299
+ if Lint.enabled?
300
+ # It is possible for a server to have a nil average RTT here
301
+ # because the ARTT comes from description which may be updated
302
+ # by a background thread while server selection is running.
303
+ # Currently lint mode is not a public feature, if/when this
304
+ # changes (https://jira.mongodb.org/browse/RUBY-1576) the
305
+ # requirement for ARTT to be not nil would need to be removed.
306
+ if server.average_round_trip_time.nil?
307
+ raise Error::LintError, "Server #{server.address} has nil average rtt"
308
+ end
309
+ end
310
+ end
311
+
312
+ server
281
313
  end
282
314
 
283
- # Get the local threshold boundary for nearest selection in seconds.
315
+ # Returns servers of acceptable types from the cluster.
284
316
  #
285
- # @example Get the local threshold.
286
- # selector.local_threshold
317
+ # Does not perform staleness validation, staleness filtering or
318
+ # latency filtering.
287
319
  #
288
- # @return [ Float ] The local threshold.
320
+ # @param [ Cluster ] cluster The cluster.
289
321
  #
290
- # @since 2.0.0
322
+ # @return [ Array<Server> ] The candidate servers.
291
323
  #
292
- # @deprecated This setting is now taken from the cluster options when a server is selected.
293
- # Will be removed in 3.0.
294
- def local_threshold
295
- @local_threshold ||= (options[:local_threshold] || ServerSelector::LOCAL_THRESHOLD)
324
+ # @api private
325
+ def candidates(cluster)
326
+ servers = cluster.servers
327
+ servers.each do |server|
328
+ validate_max_staleness_support!(server)
329
+ end
330
+ if cluster.single?
331
+ servers
332
+ elsif cluster.sharded?
333
+ servers
334
+ elsif cluster.replica_set?
335
+ select_in_replica_set(servers)
336
+ else
337
+ # Unknown cluster - no servers
338
+ []
339
+ end
296
340
  end
297
341
 
298
- # Get the potential candidates to select from the cluster.
299
- #
300
- # @example Get the server candidates.
301
- # selectable.candidates(cluster)
342
+ # Returns servers satisfying the server selector from the cluster.
302
343
  #
303
344
  # @param [ Cluster ] cluster The cluster.
304
345
  #
305
- # @return [ Array<Server> ] The candidate servers.
346
+ # @return [ Array<Server> ] The suitable servers.
306
347
  #
307
- # @since 2.4.0
308
- def candidates(cluster)
348
+ # @api private
349
+ def suitable_servers(cluster)
309
350
  if cluster.single?
310
- cluster.servers.each { |server| validate_max_staleness_support!(server) }
351
+ candidates(cluster)
311
352
  elsif cluster.sharded?
312
353
  local_threshold = local_threshold_with_cluster(cluster)
313
- near_servers(cluster.servers, local_threshold).each do |server|
314
- validate_max_staleness_support!(server)
315
- end
354
+ servers = candidates(cluster)
355
+ near_servers(servers, local_threshold)
356
+ elsif cluster.replica_set?
357
+ validate_max_staleness_value!(cluster)
358
+ candidates(cluster)
316
359
  else
317
- validate_max_staleness_value!(cluster) unless cluster.unknown?
318
- select(cluster.servers)
360
+ # Unknown cluster - no servers
361
+ []
319
362
  end
320
363
  end
321
364
 
322
365
  private
323
366
 
367
+ # Convert this server preference definition into a format appropriate
368
+ # for sending to a MongoDB server (i.e., as a command field).
369
+ #
370
+ # @return [ Hash ] The server preference formatted as a command field value.
371
+ #
372
+ # @since 2.0.0
373
+ def full_doc
374
+ @full_doc ||= begin
375
+ preference = { :mode => self.class.const_get(:SERVER_FORMATTED_NAME) }
376
+ preference.update(tags: tag_sets) unless tag_sets.empty?
377
+ preference.update(maxStalenessSeconds: max_staleness) if max_staleness
378
+ preference.update(hedge: hedge) if hedge
379
+ preference
380
+ end
381
+ end
382
+
324
383
  # Select the primary from a list of provided candidates.
325
384
  #
326
385
  # @param [ Array ] candidates List of candidate servers to select the
@@ -445,6 +504,20 @@ module Mongo
445
504
  elsif @max_staleness && !max_staleness_allowed?
446
505
  raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_MAX_STALENESS_SUPPORT)
447
506
  end
507
+
508
+ if @hedge
509
+ unless hedge_allowed?
510
+ raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_HEDGE_SUPPORT)
511
+ end
512
+
513
+ unless @hedge.is_a?(Hash) && @hedge.key?(:enabled) &&
514
+ [true, false].include?(@hedge[:enabled])
515
+ raise Error::InvalidServerPreference.new(
516
+ "`hedge` value (#{hedge}) is invalid - hedge must be a Hash in the " \
517
+ "format { enabled: true }"
518
+ )
519
+ end
520
+ end
448
521
  end
449
522
 
450
523
  def validate_max_staleness_support!(server)