mongo 2.6.4 → 2.7.0.rc0

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 (832) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +1 -1
  5. data/README.md +1 -1
  6. data/Rakefile +10 -11
  7. data/lib/mongo.rb +3 -1
  8. data/lib/mongo/active_support.rb +17 -0
  9. data/lib/mongo/address.rb +47 -39
  10. data/lib/mongo/address/ipv4.rb +1 -1
  11. data/lib/mongo/address/ipv6.rb +1 -1
  12. data/lib/mongo/address/unix.rb +1 -1
  13. data/lib/mongo/auth.rb +3 -8
  14. data/lib/mongo/auth/cr.rb +2 -2
  15. data/lib/mongo/auth/cr/conversation.rb +4 -4
  16. data/lib/mongo/auth/ldap.rb +2 -2
  17. data/lib/mongo/auth/ldap/conversation.rb +3 -3
  18. data/lib/mongo/auth/roles.rb +1 -1
  19. data/lib/mongo/auth/scram.rb +2 -2
  20. data/lib/mongo/auth/scram/conversation.rb +5 -5
  21. data/lib/mongo/auth/stringprep.rb +1 -1
  22. data/lib/mongo/auth/stringprep/profiles/sasl.rb +1 -1
  23. data/lib/mongo/auth/stringprep/tables.rb +1 -1
  24. data/lib/mongo/auth/user.rb +1 -1
  25. data/lib/mongo/auth/user/view.rb +2 -2
  26. data/lib/mongo/auth/x509.rb +2 -2
  27. data/lib/mongo/auth/x509/conversation.rb +3 -3
  28. data/lib/mongo/bson.rb +1 -1
  29. data/lib/mongo/bulk_write.rb +1 -1
  30. data/lib/mongo/bulk_write/combineable.rb +2 -2
  31. data/lib/mongo/bulk_write/ordered_combiner.rb +1 -1
  32. data/lib/mongo/bulk_write/result.rb +1 -1
  33. data/lib/mongo/bulk_write/result_combiner.rb +1 -1
  34. data/lib/mongo/bulk_write/transformable.rb +2 -2
  35. data/lib/mongo/bulk_write/unordered_combiner.rb +1 -1
  36. data/lib/mongo/bulk_write/validatable.rb +2 -2
  37. data/lib/mongo/client.rb +194 -82
  38. data/lib/mongo/cluster.rb +418 -298
  39. data/lib/mongo/cluster/periodic_executor.rb +10 -3
  40. data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -1
  41. data/lib/mongo/cluster/sdam_flow.rb +481 -0
  42. data/lib/mongo/cluster/topology.rb +37 -16
  43. data/lib/mongo/cluster/topology/base.rb +218 -0
  44. data/lib/mongo/cluster/topology/no_replica_set_options.rb +34 -0
  45. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +168 -0
  46. data/lib/mongo/cluster/topology/replica_set_with_primary.rb +27 -0
  47. data/lib/mongo/cluster/topology/sharded.rb +12 -115
  48. data/lib/mongo/cluster/topology/single.rb +18 -112
  49. data/lib/mongo/cluster/topology/unknown.rb +11 -152
  50. data/lib/mongo/collection.rb +2 -2
  51. data/lib/mongo/collection/view.rb +1 -1
  52. data/lib/mongo/collection/view/aggregation.rb +2 -2
  53. data/lib/mongo/collection/view/builder.rb +1 -1
  54. data/lib/mongo/collection/view/builder/aggregation.rb +1 -1
  55. data/lib/mongo/collection/view/builder/find_command.rb +1 -1
  56. data/lib/mongo/collection/view/builder/flags.rb +2 -2
  57. data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
  58. data/lib/mongo/collection/view/builder/modifiers.rb +2 -2
  59. data/lib/mongo/collection/view/builder/op_query.rb +1 -1
  60. data/lib/mongo/collection/view/change_stream.rb +4 -3
  61. data/lib/mongo/collection/view/change_stream/retryable.rb +1 -1
  62. data/lib/mongo/collection/view/explainable.rb +2 -2
  63. data/lib/mongo/collection/view/immutable.rb +2 -2
  64. data/lib/mongo/collection/view/iterable.rb +2 -2
  65. data/lib/mongo/collection/view/map_reduce.rb +2 -2
  66. data/lib/mongo/collection/view/readable.rb +3 -3
  67. data/lib/mongo/collection/view/writable.rb +2 -2
  68. data/lib/mongo/cursor.rb +8 -6
  69. data/lib/mongo/cursor/builder.rb +1 -1
  70. data/lib/mongo/cursor/builder/get_more_command.rb +1 -1
  71. data/lib/mongo/cursor/builder/kill_cursors_command.rb +1 -1
  72. data/lib/mongo/cursor/builder/op_get_more.rb +2 -2
  73. data/lib/mongo/cursor/builder/op_kill_cursors.rb +2 -2
  74. data/lib/mongo/database.rb +9 -4
  75. data/lib/mongo/database/view.rb +1 -1
  76. data/lib/mongo/dbref.rb +1 -1
  77. data/lib/mongo/error.rb +15 -2
  78. data/lib/mongo/error/bulk_write_error.rb +17 -1
  79. data/lib/mongo/error/change_stream_resumable.rb +1 -1
  80. data/lib/mongo/error/closed_stream.rb +1 -1
  81. data/lib/mongo/error/extra_file_chunk.rb +1 -1
  82. data/lib/mongo/error/file_not_found.rb +1 -1
  83. data/lib/mongo/error/handshake_error.rb +24 -0
  84. data/lib/mongo/error/insufficient_iteration_count.rb +1 -1
  85. data/lib/mongo/error/invalid_application_name.rb +1 -1
  86. data/lib/mongo/error/invalid_bulk_operation.rb +1 -1
  87. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -1
  88. data/lib/mongo/error/invalid_collection_name.rb +1 -1
  89. data/lib/mongo/error/invalid_database_name.rb +1 -1
  90. data/lib/mongo/error/invalid_document.rb +1 -1
  91. data/lib/mongo/error/invalid_file.rb +1 -1
  92. data/lib/mongo/error/invalid_file_revision.rb +1 -1
  93. data/lib/mongo/error/invalid_min_pool_size.rb +1 -1
  94. data/lib/mongo/error/invalid_nonce.rb +1 -1
  95. data/lib/mongo/error/invalid_read_option.rb +1 -1
  96. data/lib/mongo/error/invalid_replacement_document.rb +1 -1
  97. data/lib/mongo/error/invalid_server_preference.rb +1 -1
  98. data/lib/mongo/error/invalid_session.rb +1 -1
  99. data/lib/mongo/error/invalid_signature.rb +1 -1
  100. data/lib/mongo/error/invalid_transaction_operation.rb +2 -2
  101. data/lib/mongo/error/invalid_txt_record.rb +1 -1
  102. data/lib/mongo/error/invalid_update_document.rb +1 -1
  103. data/lib/mongo/error/invalid_uri.rb +1 -1
  104. data/lib/mongo/error/invalid_write_concern.rb +1 -1
  105. data/lib/mongo/error/lint_error.rb +1 -1
  106. data/lib/mongo/error/max_bson_size.rb +1 -1
  107. data/lib/mongo/error/max_message_size.rb +1 -1
  108. data/lib/mongo/error/mismatched_domain.rb +1 -1
  109. data/lib/mongo/error/missing_file_chunk.rb +1 -1
  110. data/lib/mongo/error/missing_resume_token.rb +1 -1
  111. data/lib/mongo/error/multi_index_drop.rb +1 -1
  112. data/lib/mongo/error/need_primary_server.rb +1 -1
  113. data/lib/mongo/error/no_server_available.rb +9 -5
  114. data/lib/mongo/error/no_srv_records.rb +1 -1
  115. data/lib/mongo/error/operation_failure.rb +2 -1
  116. data/lib/mongo/error/parser.rb +10 -1
  117. data/lib/mongo/error/session_ended.rb +27 -0
  118. data/lib/mongo/error/socket_error.rb +1 -1
  119. data/lib/mongo/error/socket_timeout_error.rb +1 -1
  120. data/lib/mongo/error/unchangeable_collection_option.rb +1 -1
  121. data/lib/mongo/error/unexpected_chunk_length.rb +1 -1
  122. data/lib/mongo/error/unexpected_response.rb +1 -1
  123. data/lib/mongo/error/unknown_payload_type.rb +1 -1
  124. data/lib/mongo/error/unsupported_array_filters.rb +1 -1
  125. data/lib/mongo/error/unsupported_collation.rb +1 -1
  126. data/lib/mongo/error/unsupported_features.rb +1 -1
  127. data/lib/mongo/error/unsupported_message_type.rb +1 -1
  128. data/lib/mongo/error/write_retryable.rb +1 -1
  129. data/lib/mongo/event.rb +3 -4
  130. data/lib/mongo/event/base.rb +6 -3
  131. data/lib/mongo/event/description_changed.rb +7 -27
  132. data/lib/mongo/event/listeners.rb +1 -1
  133. data/lib/mongo/event/publisher.rb +1 -1
  134. data/lib/mongo/event/subscriber.rb +1 -1
  135. data/lib/mongo/grid.rb +1 -1
  136. data/lib/mongo/grid/file.rb +1 -1
  137. data/lib/mongo/grid/file/chunk.rb +2 -2
  138. data/lib/mongo/grid/file/info.rb +8 -2
  139. data/lib/mongo/grid/fs_bucket.rb +1 -1
  140. data/lib/mongo/grid/stream.rb +1 -1
  141. data/lib/mongo/grid/stream/read.rb +1 -1
  142. data/lib/mongo/grid/stream/write.rb +1 -1
  143. data/lib/mongo/id.rb +64 -0
  144. data/lib/mongo/index.rb +1 -1
  145. data/lib/mongo/index/view.rb +1 -1
  146. data/lib/mongo/lint.rb +44 -5
  147. data/lib/mongo/loggable.rb +1 -1
  148. data/lib/mongo/logger.rb +1 -1
  149. data/lib/mongo/monitoring.rb +34 -10
  150. data/lib/mongo/monitoring/command_log_subscriber.rb +1 -1
  151. data/lib/mongo/monitoring/event.rb +4 -1
  152. data/lib/mongo/monitoring/event/command_failed.rb +1 -1
  153. data/lib/mongo/monitoring/event/command_started.rb +2 -2
  154. data/lib/mongo/monitoring/event/command_succeeded.rb +1 -1
  155. data/lib/mongo/monitoring/event/secure.rb +2 -2
  156. data/lib/mongo/monitoring/event/server_closed.rb +14 -1
  157. data/lib/mongo/monitoring/event/server_description_changed.rb +16 -1
  158. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +71 -0
  159. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +55 -0
  160. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +63 -0
  161. data/lib/mongo/monitoring/event/server_opening.rb +8 -4
  162. data/lib/mongo/monitoring/event/topology_changed.rb +9 -6
  163. data/lib/mongo/monitoring/event/topology_closed.rb +14 -1
  164. data/lib/mongo/monitoring/event/topology_opening.rb +8 -4
  165. data/lib/mongo/monitoring/publishable.rb +3 -35
  166. data/lib/mongo/monitoring/sdam_log_subscriber.rb +1 -1
  167. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +1 -1
  168. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +1 -1
  169. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +1 -1
  170. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +4 -4
  171. data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +30 -0
  172. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +2 -2
  173. data/lib/mongo/operation.rb +8 -0
  174. data/lib/mongo/operation/aggregate.rb +3 -20
  175. data/lib/mongo/operation/aggregate/command.rb +1 -1
  176. data/lib/mongo/operation/aggregate/op_msg.rb +4 -30
  177. data/lib/mongo/operation/aggregate/result.rb +2 -2
  178. data/lib/mongo/operation/collections_info.rb +1 -1
  179. data/lib/mongo/operation/collections_info/result.rb +2 -2
  180. data/lib/mongo/operation/command.rb +2 -19
  181. data/lib/mongo/operation/command/command.rb +1 -1
  182. data/lib/mongo/operation/command/op_msg.rb +2 -27
  183. data/lib/mongo/operation/count.rb +2 -19
  184. data/lib/mongo/operation/count/command.rb +1 -1
  185. data/lib/mongo/operation/count/op_msg.rb +2 -11
  186. data/lib/mongo/operation/create.rb +2 -19
  187. data/lib/mongo/operation/create/command.rb +1 -1
  188. data/lib/mongo/operation/create/op_msg.rb +3 -20
  189. data/lib/mongo/operation/create_index.rb +2 -19
  190. data/lib/mongo/operation/create_index/command.rb +1 -1
  191. data/lib/mongo/operation/create_index/op_msg.rb +3 -18
  192. data/lib/mongo/operation/create_user.rb +2 -19
  193. data/lib/mongo/operation/create_user/command.rb +1 -1
  194. data/lib/mongo/operation/create_user/op_msg.rb +3 -18
  195. data/lib/mongo/operation/delete.rb +1 -1
  196. data/lib/mongo/operation/delete/bulk_result.rb +2 -2
  197. data/lib/mongo/operation/delete/command.rb +1 -1
  198. data/lib/mongo/operation/delete/legacy.rb +1 -1
  199. data/lib/mongo/operation/delete/op_msg.rb +5 -23
  200. data/lib/mongo/operation/delete/result.rb +2 -2
  201. data/lib/mongo/operation/distinct.rb +2 -19
  202. data/lib/mongo/operation/distinct/command.rb +1 -1
  203. data/lib/mongo/operation/distinct/op_msg.rb +3 -20
  204. data/lib/mongo/operation/drop.rb +2 -19
  205. data/lib/mongo/operation/drop/command.rb +1 -1
  206. data/lib/mongo/operation/drop/op_msg.rb +3 -20
  207. data/lib/mongo/operation/drop_database.rb +2 -19
  208. data/lib/mongo/operation/drop_database/command.rb +1 -1
  209. data/lib/mongo/operation/drop_database/op_msg.rb +3 -20
  210. data/lib/mongo/operation/drop_index.rb +2 -19
  211. data/lib/mongo/operation/drop_index/command.rb +1 -1
  212. data/lib/mongo/operation/drop_index/op_msg.rb +3 -18
  213. data/lib/mongo/operation/explain.rb +2 -21
  214. data/lib/mongo/operation/explain/command.rb +1 -1
  215. data/lib/mongo/operation/explain/legacy.rb +1 -1
  216. data/lib/mongo/operation/explain/op_msg.rb +4 -30
  217. data/lib/mongo/operation/explain/result.rb +2 -2
  218. data/lib/mongo/operation/find.rb +2 -21
  219. data/lib/mongo/operation/find/command.rb +1 -1
  220. data/lib/mongo/operation/find/legacy.rb +1 -1
  221. data/lib/mongo/operation/find/legacy/result.rb +2 -2
  222. data/lib/mongo/operation/find/op_msg.rb +6 -30
  223. data/lib/mongo/operation/find/result.rb +2 -2
  224. data/lib/mongo/operation/get_more.rb +2 -11
  225. data/lib/mongo/operation/get_more/command.rb +1 -1
  226. data/lib/mongo/operation/get_more/legacy.rb +1 -1
  227. data/lib/mongo/operation/get_more/op_msg.rb +6 -30
  228. data/lib/mongo/operation/get_more/result.rb +2 -2
  229. data/lib/mongo/operation/indexes.rb +2 -21
  230. data/lib/mongo/operation/indexes/command.rb +1 -1
  231. data/lib/mongo/operation/indexes/legacy.rb +1 -1
  232. data/lib/mongo/operation/indexes/op_msg.rb +4 -30
  233. data/lib/mongo/operation/indexes/result.rb +2 -2
  234. data/lib/mongo/operation/insert.rb +1 -1
  235. data/lib/mongo/operation/insert/bulk_result.rb +2 -2
  236. data/lib/mongo/operation/insert/command.rb +1 -1
  237. data/lib/mongo/operation/insert/legacy.rb +1 -1
  238. data/lib/mongo/operation/insert/op_msg.rb +10 -23
  239. data/lib/mongo/operation/insert/result.rb +2 -2
  240. data/lib/mongo/operation/kill_cursors.rb +2 -21
  241. data/lib/mongo/operation/kill_cursors/command.rb +1 -1
  242. data/lib/mongo/operation/kill_cursors/legacy.rb +1 -1
  243. data/lib/mongo/operation/kill_cursors/op_msg.rb +3 -20
  244. data/lib/mongo/operation/list_collections.rb +2 -19
  245. data/lib/mongo/operation/list_collections/command.rb +1 -1
  246. data/lib/mongo/operation/list_collections/op_msg.rb +4 -28
  247. data/lib/mongo/operation/list_collections/result.rb +2 -2
  248. data/lib/mongo/operation/map_reduce.rb +2 -19
  249. data/lib/mongo/operation/map_reduce/command.rb +1 -1
  250. data/lib/mongo/operation/map_reduce/op_msg.rb +4 -30
  251. data/lib/mongo/operation/map_reduce/result.rb +2 -2
  252. data/lib/mongo/operation/op_msg_base.rb +30 -0
  253. data/lib/mongo/operation/parallel_scan.rb +2 -19
  254. data/lib/mongo/operation/parallel_scan/command.rb +1 -1
  255. data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -28
  256. data/lib/mongo/operation/parallel_scan/result.rb +2 -2
  257. data/lib/mongo/operation/remove_user.rb +2 -19
  258. data/lib/mongo/operation/remove_user/command.rb +1 -1
  259. data/lib/mongo/operation/remove_user/op_msg.rb +3 -18
  260. data/lib/mongo/operation/result.rb +14 -2
  261. data/lib/mongo/operation/shared/bypass_document_validation.rb +1 -1
  262. data/lib/mongo/operation/shared/causal_consistency_supported.rb +14 -6
  263. data/lib/mongo/operation/shared/executable.rb +10 -3
  264. data/lib/mongo/operation/shared/executable_no_validate.rb +30 -0
  265. data/lib/mongo/operation/shared/executable_transaction_label.rb +34 -0
  266. data/lib/mongo/operation/shared/idable.rb +1 -1
  267. data/lib/mongo/operation/shared/limited.rb +1 -1
  268. data/lib/mongo/operation/shared/object_id_generator.rb +1 -1
  269. data/lib/mongo/operation/shared/op_msg_or_command.rb +42 -0
  270. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +45 -0
  271. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +45 -0
  272. data/lib/mongo/operation/shared/polymorphic_lookup.rb +33 -0
  273. data/lib/mongo/operation/shared/polymorphic_result.rb +32 -0
  274. data/lib/mongo/operation/shared/read_preference_supported.rb +1 -1
  275. data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
  276. data/lib/mongo/operation/shared/sessions_supported.rb +24 -4
  277. data/lib/mongo/operation/shared/specifiable.rb +5 -3
  278. data/lib/mongo/operation/shared/write.rb +1 -1
  279. data/lib/mongo/operation/shared/write_concern_supported.rb +1 -1
  280. data/lib/mongo/operation/update.rb +1 -1
  281. data/lib/mongo/operation/update/bulk_result.rb +2 -2
  282. data/lib/mongo/operation/update/command.rb +1 -1
  283. data/lib/mongo/operation/update/legacy.rb +1 -1
  284. data/lib/mongo/operation/update/legacy/result.rb +2 -2
  285. data/lib/mongo/operation/update/op_msg.rb +5 -23
  286. data/lib/mongo/operation/update/result.rb +2 -2
  287. data/lib/mongo/operation/update_user.rb +2 -19
  288. data/lib/mongo/operation/update_user/command.rb +1 -1
  289. data/lib/mongo/operation/update_user/op_msg.rb +3 -18
  290. data/lib/mongo/operation/users_info.rb +2 -19
  291. data/lib/mongo/operation/users_info/command.rb +1 -1
  292. data/lib/mongo/operation/users_info/op_msg.rb +4 -28
  293. data/lib/mongo/operation/users_info/result.rb +2 -2
  294. data/lib/mongo/options.rb +1 -1
  295. data/lib/mongo/options/mapper.rb +10 -3
  296. data/lib/mongo/options/redacted.rb +1 -1
  297. data/lib/mongo/protocol/bit_vector.rb +1 -1
  298. data/lib/mongo/protocol/compressed.rb +2 -2
  299. data/lib/mongo/protocol/delete.rb +1 -1
  300. data/lib/mongo/protocol/get_more.rb +1 -1
  301. data/lib/mongo/protocol/insert.rb +1 -1
  302. data/lib/mongo/protocol/kill_cursors.rb +1 -1
  303. data/lib/mongo/protocol/message.rb +4 -9
  304. data/lib/mongo/protocol/msg.rb +2 -2
  305. data/lib/mongo/protocol/query.rb +1 -1
  306. data/lib/mongo/protocol/registry.rb +1 -1
  307. data/lib/mongo/protocol/reply.rb +1 -1
  308. data/lib/mongo/protocol/serializers.rb +1 -1
  309. data/lib/mongo/protocol/update.rb +1 -1
  310. data/lib/mongo/retryable.rb +40 -14
  311. data/lib/mongo/semaphore.rb +46 -0
  312. data/lib/mongo/server.rb +159 -44
  313. data/lib/mongo/{cluster → server}/app_metadata.rb +26 -13
  314. data/lib/mongo/server/connectable.rb +9 -13
  315. data/lib/mongo/server/connection.rb +143 -71
  316. data/lib/mongo/server/connection_pool.rb +25 -20
  317. data/lib/mongo/server/connection_pool/queue.rb +163 -46
  318. data/lib/mongo/server/context.rb +13 -13
  319. data/lib/mongo/server/description.rb +93 -48
  320. data/lib/mongo/server/description/features.rb +22 -3
  321. data/lib/mongo/server/monitor.rb +143 -74
  322. data/lib/mongo/server/monitor/app_metadata.rb +34 -0
  323. data/lib/mongo/server/monitor/connection.rb +42 -26
  324. data/lib/mongo/server/round_trip_time_averager.rb +64 -0
  325. data/lib/mongo/server_selector.rb +1 -1
  326. data/lib/mongo/server_selector/nearest.rb +1 -1
  327. data/lib/mongo/server_selector/primary.rb +1 -1
  328. data/lib/mongo/server_selector/primary_preferred.rb +1 -1
  329. data/lib/mongo/server_selector/secondary.rb +1 -1
  330. data/lib/mongo/server_selector/secondary_preferred.rb +1 -1
  331. data/lib/mongo/server_selector/selectable.rb +38 -13
  332. data/lib/mongo/session.rb +189 -40
  333. data/lib/mongo/session/server_session.rb +18 -7
  334. data/lib/mongo/session/session_pool.rb +1 -1
  335. data/lib/mongo/socket.rb +1 -1
  336. data/lib/mongo/socket/ssl.rb +46 -7
  337. data/lib/mongo/socket/tcp.rb +1 -1
  338. data/lib/mongo/socket/unix.rb +1 -1
  339. data/lib/mongo/uri.rb +304 -18
  340. data/lib/mongo/uri/srv_protocol.rb +1 -1
  341. data/lib/mongo/version.rb +2 -2
  342. data/lib/mongo/write_concern.rb +6 -6
  343. data/lib/mongo/write_concern/acknowledged.rb +2 -4
  344. data/lib/mongo/write_concern/{normalizable.rb → base.rb} +5 -6
  345. data/lib/mongo/write_concern/unacknowledged.rb +2 -4
  346. data/mongo.gemspec +1 -1
  347. data/spec/enterprise_auth/kerberos_spec.rb +57 -0
  348. data/spec/integration/bulk_insert_spec.rb +4 -2
  349. data/spec/integration/change_stream_examples_spec.rb +5 -6
  350. data/spec/integration/change_stream_spec.rb +17 -14
  351. data/spec/integration/client_connectivity_spec.rb +38 -0
  352. data/spec/integration/client_construction_spec.rb +94 -0
  353. data/spec/integration/command_monitoring_spec.rb +18 -30
  354. data/spec/integration/connect_single_rs_name_spec.rb +67 -0
  355. data/spec/integration/connection_spec.rb +209 -0
  356. data/spec/integration/cursor_reaping_spec.rb +95 -0
  357. data/spec/integration/docs_examples_spec.rb +6 -5
  358. data/spec/integration/heartbeat_events_spec.rb +116 -0
  359. data/spec/integration/retryable_writes_spec.rb +18 -8
  360. data/spec/integration/sdam_events_spec.rb +47 -0
  361. data/spec/integration/server_description_spec.rb +48 -0
  362. data/spec/integration/time_zone_querying_spec.rb +52 -0
  363. data/spec/lite_spec_helper.rb +74 -19
  364. data/spec/mongo/address_spec.rb +17 -7
  365. data/spec/mongo/auth/cr_spec.rb +8 -5
  366. data/spec/mongo/auth/ldap_spec.rb +9 -6
  367. data/spec/mongo/auth/scram/conversation_spec.rb +4 -1
  368. data/spec/mongo/auth/scram/negotiation_spec.rb +68 -110
  369. data/spec/mongo/auth/scram_spec.rb +8 -5
  370. data/spec/mongo/auth/user/view_spec.rb +5 -5
  371. data/spec/mongo/auth/x509_spec.rb +9 -6
  372. data/spec/mongo/bulk_write_spec.rb +32 -22
  373. data/spec/mongo/client_construction_spec.rb +1164 -0
  374. data/spec/mongo/client_spec.rb +62 -1000
  375. data/spec/mongo/cluster/cursor_reaper_spec.rb +2 -2
  376. data/spec/mongo/cluster/topology/replica_set_spec.rb +186 -251
  377. data/spec/mongo/cluster/topology/sharded_spec.rb +48 -50
  378. data/spec/mongo/cluster/topology/single_spec.rb +62 -22
  379. data/spec/mongo/cluster/topology/unknown_spec.rb +30 -115
  380. data/spec/mongo/cluster/topology_spec.rb +111 -13
  381. data/spec/mongo/cluster_spec.rb +195 -246
  382. data/spec/mongo/collection/view/aggregation_spec.rb +7 -8
  383. data/spec/mongo/collection/view/change_stream_spec.rb +18 -7
  384. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  385. data/spec/mongo/collection/view/immutable_spec.rb +1 -1
  386. data/spec/mongo/collection/view/map_reduce_spec.rb +7 -8
  387. data/spec/mongo/collection/view/readable_spec.rb +7 -8
  388. data/spec/mongo/collection/view/writable_spec.rb +1 -1
  389. data/spec/mongo/collection/view_spec.rb +2 -5
  390. data/spec/mongo/collection_spec.rb +41 -48
  391. data/spec/mongo/cursor/builder/get_more_command_spec.rb +1 -1
  392. data/spec/mongo/cursor/builder/op_get_more_spec.rb +1 -1
  393. data/spec/mongo/cursor_spec.rb +51 -25
  394. data/spec/mongo/database_spec.rb +25 -37
  395. data/spec/mongo/error/no_server_available_spec.rb +22 -0
  396. data/spec/mongo/error/operation_failure_spec.rb +70 -0
  397. data/spec/mongo/error/parser_spec.rb +44 -10
  398. data/spec/mongo/grid/file/info_spec.rb +3 -3
  399. data/spec/mongo/grid/fs_bucket_spec.rb +18 -53
  400. data/spec/mongo/grid/stream/read_spec.rb +9 -15
  401. data/spec/mongo/grid/stream/write_spec.rb +11 -23
  402. data/spec/mongo/id_spec.rb +35 -0
  403. data/spec/mongo/index/view_spec.rb +11 -72
  404. data/spec/mongo/lint_spec.rb +76 -0
  405. data/spec/mongo/monitoring/event/command_failed_spec.rb +1 -1
  406. data/spec/mongo/monitoring/event/command_started_spec.rb +1 -1
  407. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +1 -1
  408. data/spec/mongo/monitoring/event/secure_spec.rb +1 -1
  409. data/spec/mongo/monitoring/event/server_closed_spec.rb +35 -0
  410. data/spec/mongo/monitoring/event/server_description_changed_spec.rb +38 -0
  411. data/spec/mongo/monitoring/event/server_heartbeat_failed_spec.rb +31 -0
  412. data/spec/mongo/monitoring/event/server_heartbeat_started_spec.rb +31 -0
  413. data/spec/mongo/monitoring/event/server_heartbeat_succeeded_spec.rb +31 -0
  414. data/spec/mongo/monitoring/event/server_opening_spec.rb +35 -0
  415. data/spec/mongo/monitoring/event/topology_changed_spec.rb +41 -0
  416. data/spec/mongo/monitoring/event/topology_closed_spec.rb +35 -0
  417. data/spec/mongo/monitoring/event/topology_opening_spec.rb +35 -0
  418. data/spec/mongo/monitoring_spec.rb +2 -2
  419. data/spec/mongo/operation/aggregate_spec.rb +2 -2
  420. data/spec/mongo/operation/collections_info_spec.rb +2 -2
  421. data/spec/mongo/operation/command_spec.rb +1 -1
  422. data/spec/mongo/operation/create_index_spec.rb +8 -11
  423. data/spec/mongo/operation/create_user_spec.rb +6 -3
  424. data/spec/mongo/operation/delete/bulk_spec.rb +21 -12
  425. data/spec/mongo/operation/delete/command_spec.rb +3 -2
  426. data/spec/mongo/operation/delete/op_msg_spec.rb +32 -17
  427. data/spec/mongo/operation/delete_spec.rb +21 -10
  428. data/spec/mongo/operation/drop_index_spec.rb +5 -2
  429. data/spec/mongo/operation/find/legacy_spec.rb +3 -2
  430. data/spec/mongo/operation/get_more_spec.rb +2 -2
  431. data/spec/mongo/operation/indexes_spec.rb +3 -2
  432. data/spec/mongo/operation/insert/bulk_spec.rb +13 -3
  433. data/spec/mongo/operation/insert/command_spec.rb +3 -2
  434. data/spec/mongo/operation/insert/op_msg_spec.rb +34 -18
  435. data/spec/mongo/operation/insert_spec.rb +7 -6
  436. data/spec/mongo/operation/kill_cursors_spec.rb +2 -2
  437. data/spec/mongo/operation/map_reduce_spec.rb +2 -2
  438. data/spec/mongo/operation/remove_user_spec.rb +6 -2
  439. data/spec/mongo/operation/result_spec.rb +6 -3
  440. data/spec/mongo/operation/update/bulk_spec.rb +3 -3
  441. data/spec/mongo/operation/update/command_spec.rb +8 -7
  442. data/spec/mongo/operation/update/op_msg_spec.rb +36 -21
  443. data/spec/mongo/operation/update_spec.rb +8 -6
  444. data/spec/mongo/operation/update_user_spec.rb +6 -6
  445. data/spec/mongo/protocol/compressed_spec.rb +3 -2
  446. data/spec/mongo/protocol/delete_spec.rb +1 -1
  447. data/spec/mongo/protocol/get_more_spec.rb +1 -1
  448. data/spec/mongo/protocol/insert_spec.rb +1 -1
  449. data/spec/mongo/protocol/kill_cursors_spec.rb +1 -1
  450. data/spec/mongo/protocol/msg_spec.rb +14 -13
  451. data/spec/mongo/protocol/query_spec.rb +1 -1
  452. data/spec/mongo/protocol/update_spec.rb +1 -1
  453. data/spec/mongo/retryable_spec.rb +84 -0
  454. data/spec/mongo/{cluster → server}/app_metadata_spec.rb +15 -3
  455. data/spec/mongo/server/connection_auth_spec.rb +114 -0
  456. data/spec/mongo/server/connection_pool/queue_spec.rb +146 -30
  457. data/spec/mongo/server/connection_pool_spec.rb +11 -12
  458. data/spec/mongo/server/connection_spec.rb +339 -152
  459. data/spec/mongo/server/description_query_methods_spec.rb +288 -0
  460. data/spec/mongo/server/description_spec.rb +63 -240
  461. data/spec/mongo/server/monitor/app_metadata_spec.rb +16 -0
  462. data/spec/mongo/server/monitor/connection_spec.rb +31 -28
  463. data/spec/mongo/server/monitor_spec.rb +61 -32
  464. data/spec/mongo/server/round_trip_time_averager_spec.rb +43 -0
  465. data/spec/mongo/server_selector_spec.rb +106 -1
  466. data/spec/mongo/server_spec.rb +31 -12
  467. data/spec/mongo/session/session_pool_spec.rb +3 -1
  468. data/spec/mongo/session_spec.rb +64 -2
  469. data/spec/mongo/session_transaction_spec.rb +64 -0
  470. data/spec/mongo/socket/ssl_spec.rb +86 -10
  471. data/spec/mongo/uri/srv_protocol_spec.rb +40 -40
  472. data/spec/mongo/uri_spec.rb +74 -38
  473. data/spec/spec_helper.rb +39 -64
  474. data/spec/spec_tests/connection_string_spec.rb +4 -32
  475. data/spec/spec_tests/crud_spec.rb +12 -2
  476. data/spec/{support/change_streams_tests → spec_tests/data/change_streams}/change-streams-errors.yml +0 -0
  477. data/spec/{support/change_streams_tests → spec_tests/data/change_streams}/change-streams.yml +0 -0
  478. data/spec/{support → spec_tests/data}/command_monitoring/bulkWrite.yml +0 -0
  479. data/spec/{support → spec_tests/data}/command_monitoring/command.yml +0 -0
  480. data/spec/{support → spec_tests/data}/command_monitoring/deleteMany.yml +0 -0
  481. data/spec/{support → spec_tests/data}/command_monitoring/deleteOne.yml +0 -0
  482. data/spec/{support → spec_tests/data}/command_monitoring/find.yml +0 -0
  483. data/spec/{support → spec_tests/data}/command_monitoring/insertMany.yml +0 -0
  484. data/spec/{support → spec_tests/data}/command_monitoring/insertOne.yml +0 -0
  485. data/spec/{support → spec_tests/data}/command_monitoring/unacknowledgedBulkWrite.yml +0 -0
  486. data/spec/{support → spec_tests/data}/command_monitoring/updateMany.yml +0 -0
  487. data/spec/{support → spec_tests/data}/command_monitoring/updateOne.yml +0 -0
  488. data/spec/{support/connection_string_tests → spec_tests/data/connection_string}/invalid-uris.yml +0 -0
  489. data/spec/{support/connection_string_tests → spec_tests/data/connection_string}/valid-auth.yml +0 -0
  490. data/spec/{support/connection_string_tests → spec_tests/data/connection_string}/valid-db-with-dotted-name.yml +0 -0
  491. data/spec/{support/connection_string_tests → spec_tests/data/connection_string}/valid-host_identifiers.yml +0 -0
  492. data/spec/{support/connection_string_tests → spec_tests/data/connection_string}/valid-options.yml +0 -0
  493. data/spec/{support/connection_string_tests → spec_tests/data/connection_string}/valid-unix_socket-absolute.yml +0 -0
  494. data/spec/{support/connection_string_tests → spec_tests/data/connection_string}/valid-unix_socket-relative.yml +0 -0
  495. data/spec/{support/connection_string_tests → spec_tests/data/connection_string}/valid-warnings.yml +0 -0
  496. data/spec/{support/crud_tests → spec_tests/data/crud}/read/aggregate-collation.yml +0 -0
  497. data/spec/{support/crud_tests → spec_tests/data/crud}/read/aggregate-out.yml +6 -6
  498. data/spec/{support/crud_tests → spec_tests/data/crud}/read/aggregate.yml +0 -0
  499. data/spec/{support/crud_tests → spec_tests/data/crud}/read/count-collation.yml +0 -0
  500. data/spec/{support/crud_tests → spec_tests/data/crud}/read/count.yml +0 -0
  501. data/spec/{support/crud_tests → spec_tests/data/crud}/read/distinct-collation.yml +0 -0
  502. data/spec/{support/crud_tests → spec_tests/data/crud}/read/distinct.yml +0 -0
  503. data/spec/{support/crud_tests → spec_tests/data/crud}/read/find-collation.yml +0 -0
  504. data/spec/{support/crud_tests → spec_tests/data/crud}/read/find.yml +0 -0
  505. data/spec/{support/crud_tests → spec_tests/data/crud}/write/bulkWrite-arrayFilters.yml +0 -0
  506. data/spec/{support/crud_tests → spec_tests/data/crud}/write/deleteMany-collation.yml +0 -0
  507. data/spec/{support/crud_tests → spec_tests/data/crud}/write/deleteMany.yml +0 -0
  508. data/spec/{support/crud_tests → spec_tests/data/crud}/write/deleteOne-collation.yml +0 -0
  509. data/spec/{support/crud_tests → spec_tests/data/crud}/write/deleteOne.yml +0 -0
  510. data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndDelete-collation.yml +0 -0
  511. data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndDelete.yml +0 -0
  512. data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndReplace-collation.yml +0 -0
  513. data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndReplace-upsert.yml +0 -0
  514. data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndReplace-upsert_pre_2.6.yml +0 -0
  515. data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndReplace.yml +0 -0
  516. data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndUpdate-arrayFilters.yml +0 -0
  517. data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndUpdate-collation.yml +0 -0
  518. data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndUpdate.yml +0 -0
  519. data/spec/{support/crud_tests → spec_tests/data/crud}/write/insertMany.yml +0 -0
  520. data/spec/{support/crud_tests → spec_tests/data/crud}/write/insertOne.yml +0 -0
  521. data/spec/{support/crud_tests → spec_tests/data/crud}/write/replaceOne-collation.yml +0 -0
  522. data/spec/{support/crud_tests → spec_tests/data/crud}/write/replaceOne-pre_2.6.yml +0 -0
  523. data/spec/{support/crud_tests → spec_tests/data/crud}/write/replaceOne-upsert.yml +0 -0
  524. data/spec/{support/crud_tests → spec_tests/data/crud}/write/replaceOne.yml +0 -0
  525. data/spec/{support/crud_tests → spec_tests/data/crud}/write/updateMany-arrayFilters.yml +0 -0
  526. data/spec/{support/crud_tests → spec_tests/data/crud}/write/updateMany-collation.yml +0 -0
  527. data/spec/{support/crud_tests → spec_tests/data/crud}/write/updateMany-pre_2.6.yml +0 -0
  528. data/spec/{support/crud_tests → spec_tests/data/crud}/write/updateMany.yml +0 -0
  529. data/spec/{support/crud_tests → spec_tests/data/crud}/write/updateOne-arrayFilters.yml +0 -0
  530. data/spec/{support/crud_tests → spec_tests/data/crud}/write/updateOne-collation.yml +0 -0
  531. data/spec/{support/crud_tests → spec_tests/data/crud}/write/updateOne-pre_2.6.yml +0 -0
  532. data/spec/{support/crud_tests → spec_tests/data/crud}/write/updateOne.yml +0 -0
  533. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/longer-parent-in-return.yml +0 -0
  534. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/misformatted-option.yml +0 -0
  535. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/no-results.yml +0 -0
  536. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/not-enough-parts.yml +0 -0
  537. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/one-result-default-port.yml +0 -0
  538. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/one-txt-record-multiple-strings.yml +0 -0
  539. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/one-txt-record.yml +0 -0
  540. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/parent-part-mismatch1.yml +0 -0
  541. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/parent-part-mismatch2.yml +0 -0
  542. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/parent-part-mismatch3.yml +0 -0
  543. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/parent-part-mismatch4.yml +0 -0
  544. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/parent-part-mismatch5.yml +0 -0
  545. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/returned-parent-too-short.yml +0 -0
  546. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/returned-parent-wrong.yml +0 -0
  547. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/two-results-default-port.yml +0 -0
  548. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/two-results-nonstandard-port.yml +0 -0
  549. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/two-txt-records.yml +0 -0
  550. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/txt-record-not-allowed-option.yml +0 -0
  551. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/txt-record-with-overridden-ssl-option.yml +0 -0
  552. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/txt-record-with-overridden-uri-option.yml +0 -0
  553. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/txt-record-with-unallowed-option.yml +0 -0
  554. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/uri-with-port.yml +0 -0
  555. data/spec/{support/dns_seedlist_discovery_tests → spec_tests/data/dns_seedlist_discovery}/uri-with-two-hosts.yml +0 -0
  556. data/spec/{support/gridfs_tests → spec_tests/data/gridfs}/delete.yml +0 -0
  557. data/spec/{support/gridfs_tests → spec_tests/data/gridfs}/download.yml +0 -0
  558. data/spec/{support/gridfs_tests → spec_tests/data/gridfs}/download_by_name.yml +0 -0
  559. data/spec/{support/gridfs_tests → spec_tests/data/gridfs}/upload.yml +0 -0
  560. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +0 -0
  561. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/Incompatible.yml +0 -0
  562. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +0 -0
  563. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/Nearest.yml +0 -0
  564. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +0 -0
  565. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +0 -0
  566. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +0 -0
  567. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +0 -0
  568. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/Secondary.yml +0 -0
  569. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +0 -0
  570. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +0 -0
  571. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml +0 -0
  572. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +0 -0
  573. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Incompatible.yml +0 -0
  574. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +0 -0
  575. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.yml +0 -0
  576. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml +0 -0
  577. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +0 -0
  578. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +0 -0
  579. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Nearest.yml +0 -0
  580. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +0 -0
  581. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +0 -0
  582. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +0 -0
  583. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.yml +0 -0
  584. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +0 -0
  585. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +0 -0
  586. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +0 -0
  587. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +0 -0
  588. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +0 -0
  589. data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +0 -0
  590. data/spec/{support → spec_tests/data}/max_staleness/Sharded/Incompatible.yml +0 -0
  591. data/spec/{support → spec_tests/data}/max_staleness/Sharded/SmallMaxStaleness.yml +0 -0
  592. data/spec/{support → spec_tests/data}/max_staleness/Single/Incompatible.yml +0 -0
  593. data/spec/{support → spec_tests/data}/max_staleness/Single/SmallMaxStaleness.yml +0 -0
  594. data/spec/{support → spec_tests/data}/max_staleness/Unknown/SmallMaxStaleness.yml +0 -0
  595. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/bulkWrite-serverErrors.yml +0 -0
  596. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/bulkWrite.yml +0 -0
  597. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/deleteOne-serverErrors.yml +0 -0
  598. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/deleteOne.yml +0 -0
  599. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/findOneAndDelete-serverErrors.yml +0 -0
  600. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/findOneAndDelete.yml +0 -0
  601. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/findOneAndReplace-serverErrors.yml +0 -0
  602. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/findOneAndReplace.yml +0 -0
  603. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/findOneAndUpdate-serverErrors.yml +0 -0
  604. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/findOneAndUpdate.yml +0 -0
  605. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/insertMany-serverErrors.yml +0 -0
  606. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/insertMany.yml +0 -0
  607. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/insertOne-serverErrors.yml +0 -0
  608. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/insertOne.yml +0 -0
  609. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/replaceOne-serverErrors.yml +0 -0
  610. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/replaceOne.yml +0 -0
  611. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/updateOne-serverErrors.yml +0 -0
  612. data/spec/{support/retryable_writes_tests → spec_tests/data/retryable_writes}/updateOne.yml +0 -0
  613. data/spec/{support → spec_tests/data}/sdam/rs/compatible.yml +0 -0
  614. data/spec/spec_tests/data/sdam/rs/compatible_unknown.yml +31 -0
  615. data/spec/{support → spec_tests/data}/sdam/rs/discover_arbiters.yml +0 -0
  616. data/spec/{support → spec_tests/data}/sdam/rs/discover_passives.yml +0 -0
  617. data/spec/{support → spec_tests/data}/sdam/rs/discover_primary.yml +0 -0
  618. data/spec/{support → spec_tests/data}/sdam/rs/discover_secondary.yml +0 -0
  619. data/spec/{support → spec_tests/data}/sdam/rs/discovery.yml +0 -0
  620. data/spec/{support → spec_tests/data}/sdam/rs/equal_electionids.yml +2 -0
  621. data/spec/{support → spec_tests/data}/sdam/rs/ghost_discovered.yml +0 -0
  622. data/spec/{support → spec_tests/data}/sdam/rs/hosts_differ_from_seeds.yml +0 -0
  623. data/spec/spec_tests/data/sdam/rs/incompatible_arbiter.yml +32 -0
  624. data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +32 -0
  625. data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +32 -0
  626. data/spec/{support → spec_tests/data}/sdam/rs/ls_timeout.yml +0 -0
  627. data/spec/{support → spec_tests/data}/sdam/rs/member_reconfig.yml +0 -0
  628. data/spec/{support → spec_tests/data}/sdam/rs/member_standalone.yml +0 -0
  629. data/spec/{support → spec_tests/data}/sdam/rs/new_primary.yml +0 -0
  630. data/spec/{support → spec_tests/data}/sdam/rs/new_primary_new_electionid.yml +6 -0
  631. data/spec/{support → spec_tests/data}/sdam/rs/new_primary_new_setversion.yml +6 -0
  632. data/spec/{support → spec_tests/data}/sdam/rs/new_primary_wrong_set_name.yml +0 -0
  633. data/spec/{support → spec_tests/data}/sdam/rs/non_rs_member.yml +0 -0
  634. data/spec/{support → spec_tests/data}/sdam/rs/normalize_case.yml +0 -0
  635. data/spec/{support → spec_tests/data}/sdam/rs/normalize_case_me.yml +0 -0
  636. data/spec/{support → spec_tests/data}/sdam/rs/null_election_id.yml +7 -0
  637. data/spec/spec_tests/data/sdam/rs/primary_becomes_ghost.yml +63 -0
  638. data/spec/spec_tests/data/sdam/rs/primary_becomes_mongos.yml +56 -0
  639. data/spec/{support → spec_tests/data}/sdam/rs/primary_becomes_standalone.yml +0 -0
  640. data/spec/{support → spec_tests/data}/sdam/rs/primary_changes_set_name.yml +0 -0
  641. data/spec/{support → spec_tests/data}/sdam/rs/primary_disconnect.yml +0 -0
  642. data/spec/{support → spec_tests/data}/sdam/rs/primary_disconnect_electionid.yml +10 -0
  643. data/spec/{support → spec_tests/data}/sdam/rs/primary_disconnect_setversion.yml +10 -0
  644. data/spec/{support → spec_tests/data}/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +0 -0
  645. data/spec/{support → spec_tests/data}/sdam/rs/primary_mismatched_me.yml +0 -0
  646. data/spec/{support → spec_tests/data}/sdam/rs/primary_reports_new_member.yml +0 -0
  647. data/spec/{support → spec_tests/data}/sdam/rs/primary_to_no_primary_mismatched_me.yml +0 -0
  648. data/spec/{support → spec_tests/data}/sdam/rs/primary_wrong_set_name.yml +0 -0
  649. data/spec/{support → spec_tests/data}/sdam/rs/response_from_removed.yml +0 -0
  650. data/spec/{support → spec_tests/data}/sdam/rs/rsother_discovered.yml +0 -0
  651. data/spec/{support → spec_tests/data}/sdam/rs/sec_not_auth.yml +0 -0
  652. data/spec/{support → spec_tests/data}/sdam/rs/secondary_ignore_ok_0.yml +0 -0
  653. data/spec/{support → spec_tests/data}/sdam/rs/secondary_mismatched_me.yml +0 -0
  654. data/spec/{support → spec_tests/data}/sdam/rs/secondary_wrong_set_name.yml +0 -0
  655. data/spec/{support → spec_tests/data}/sdam/rs/secondary_wrong_set_name_with_primary.yml +0 -0
  656. data/spec/spec_tests/data/sdam/rs/secondary_wrong_set_name_with_primary_second.yml +73 -0
  657. data/spec/{support → spec_tests/data}/sdam/rs/setversion_without_electionid.yml +2 -0
  658. data/spec/{support → spec_tests/data}/sdam/rs/stepdown_change_set_name.yml +0 -0
  659. data/spec/{support → spec_tests/data}/sdam/rs/too_new.yml +0 -0
  660. data/spec/{support → spec_tests/data}/sdam/rs/too_old.yml +0 -0
  661. data/spec/{support → spec_tests/data}/sdam/rs/unexpected_mongos.yml +0 -0
  662. data/spec/{support → spec_tests/data}/sdam/rs/use_setversion_without_electionid.yml +6 -0
  663. data/spec/{support → spec_tests/data}/sdam/rs/wrong_set_name.yml +0 -0
  664. data/spec/{support → spec_tests/data}/sdam/sharded/compatible.yml +0 -0
  665. data/spec/{support → spec_tests/data}/sdam/sharded/ls_timeout_mongos.yml +0 -0
  666. data/spec/{support → spec_tests/data}/sdam/sharded/mongos_disconnect.yml +0 -0
  667. data/spec/{support → spec_tests/data}/sdam/sharded/multiple_mongoses.yml +0 -0
  668. data/spec/{support → spec_tests/data}/sdam/sharded/non_mongos_removed.yml +0 -0
  669. data/spec/{support → spec_tests/data}/sdam/sharded/normalize_uri_case.yml +0 -0
  670. data/spec/{support → spec_tests/data}/sdam/sharded/single_mongos.yml +0 -0
  671. data/spec/{support → spec_tests/data}/sdam/sharded/too_new.yml +0 -0
  672. data/spec/{support → spec_tests/data}/sdam/sharded/too_old.yml +0 -0
  673. data/spec/{support → spec_tests/data}/sdam/single/compatible.yml +0 -0
  674. data/spec/{support → spec_tests/data}/sdam/single/direct_connection_external_ip.yml +0 -0
  675. data/spec/{support → spec_tests/data}/sdam/single/direct_connection_mongos.yml +0 -0
  676. data/spec/{support → spec_tests/data}/sdam/single/direct_connection_rsarbiter.yml +0 -0
  677. data/spec/{support → spec_tests/data}/sdam/single/direct_connection_rsprimary.yml +0 -0
  678. data/spec/{support → spec_tests/data}/sdam/single/direct_connection_rssecondary.yml +0 -0
  679. data/spec/{support → spec_tests/data}/sdam/single/direct_connection_slave.yml +0 -0
  680. data/spec/{support → spec_tests/data}/sdam/single/direct_connection_standalone.yml +0 -0
  681. data/spec/{support → spec_tests/data}/sdam/single/ls_timeout_standalone.yml +0 -0
  682. data/spec/{support → spec_tests/data}/sdam/single/not_ok_response.yml +0 -0
  683. data/spec/{support → spec_tests/data}/sdam/single/standalone_removed.yml +0 -0
  684. data/spec/{support → spec_tests/data}/sdam/single/too_new.yml +0 -0
  685. data/spec/{support → spec_tests/data}/sdam/single/too_old.yml +0 -0
  686. data/spec/{support → spec_tests/data}/sdam/single/unavailable_seed.yml +0 -0
  687. data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +72 -0
  688. data/spec/spec_tests/data/sdam_monitoring/replica_set_other_chain.yml +222 -0
  689. data/spec/spec_tests/data/sdam_monitoring/replica_set_other_change.yml +225 -0
  690. data/spec/spec_tests/data/sdam_monitoring/replica_set_other_seed.yml +233 -0
  691. data/spec/{support → spec_tests/data}/sdam_monitoring/replica_set_with_no_primary.yml +0 -0
  692. data/spec/{support → spec_tests/data}/sdam_monitoring/replica_set_with_primary.yml +0 -0
  693. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary_and_secondary.yml +198 -0
  694. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary_removal.yml +171 -0
  695. data/spec/{support → spec_tests/data}/sdam_monitoring/replica_set_with_removal.yml +0 -0
  696. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_second_seed_removal.yml +106 -0
  697. data/spec/{support → spec_tests/data}/sdam_monitoring/required_replica_set.yml +23 -0
  698. data/spec/{support → spec_tests/data}/sdam_monitoring/standalone.yml +2 -2
  699. data/spec/spec_tests/data/sdam_monitoring/standalone_repeated.yml +86 -0
  700. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Nearest.yml +0 -0
  701. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Nearest_multiple.yml +0 -0
  702. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +0 -0
  703. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/PossiblePrimary.yml +0 -0
  704. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/PossiblePrimaryNearest.yml +0 -0
  705. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Primary.yml +0 -0
  706. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +0 -0
  707. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +0 -0
  708. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Secondary.yml +0 -0
  709. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +0 -0
  710. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +0 -0
  711. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Secondary_multi_tags.yml +0 -0
  712. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Secondary_multi_tags2.yml +0 -0
  713. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +0 -0
  714. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/Nearest.yml +0 -0
  715. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/Nearest_multiple.yml +0 -0
  716. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +0 -0
  717. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/Primary.yml +0 -0
  718. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +0 -0
  719. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +0 -0
  720. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/Secondary.yml +0 -0
  721. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/SecondaryPreferred.yml +0 -0
  722. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.yml +0 -0
  723. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.yml +0 -0
  724. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/Secondary_non_matching.yml +0 -0
  725. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/Sharded/read/Nearest.yml +0 -0
  726. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/Sharded/read/Primary.yml +0 -0
  727. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/Sharded/read/PrimaryPreferred.yml +0 -0
  728. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/Sharded/read/Secondary.yml +0 -0
  729. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/Sharded/read/SecondaryPreferred.yml +0 -0
  730. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/Single/read/SecondaryPreferred.yml +0 -0
  731. data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/Unknown/read/SecondaryPreferred.yml +0 -0
  732. data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/first_value.yml +0 -0
  733. data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/first_value_zero.yml +0 -0
  734. data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_1.yml +0 -0
  735. data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_2.yml +0 -0
  736. data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_3.yml +0 -0
  737. data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_4.yml +0 -0
  738. data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_5.yml +0 -0
  739. data/spec/{support/transactions_tests → spec_tests/data/transactions}/abort.yml +0 -0
  740. data/spec/{support/transactions_tests → spec_tests/data/transactions}/bulk.yml +0 -0
  741. data/spec/{support/transactions_tests → spec_tests/data/transactions}/causal-consistency.yml +0 -0
  742. data/spec/{support/transactions_tests → spec_tests/data/transactions}/commit.yml +0 -0
  743. data/spec/{support/transactions_tests → spec_tests/data/transactions}/delete.yml +0 -0
  744. data/spec/{support/transactions_tests → spec_tests/data/transactions}/error-labels.yml +0 -0
  745. data/spec/{support/transactions_tests → spec_tests/data/transactions}/errors.yml +0 -0
  746. data/spec/{support/transactions_tests → spec_tests/data/transactions}/findOneAndDelete.yml +0 -0
  747. data/spec/{support/transactions_tests → spec_tests/data/transactions}/findOneAndReplace.yml +0 -0
  748. data/spec/{support/transactions_tests → spec_tests/data/transactions}/findOneAndUpdate.yml +0 -0
  749. data/spec/{support/transactions_tests → spec_tests/data/transactions}/insert.yml +0 -0
  750. data/spec/{support/transactions_tests → spec_tests/data/transactions}/isolation.yml +0 -0
  751. data/spec/{support/transactions_tests → spec_tests/data/transactions}/read-pref.yml +0 -0
  752. data/spec/{support/transactions_tests → spec_tests/data/transactions}/reads.yml +0 -0
  753. data/spec/{support/transactions_tests → spec_tests/data/transactions}/retryable-abort.yml +0 -0
  754. data/spec/{support/transactions_tests → spec_tests/data/transactions}/retryable-commit.yml +0 -0
  755. data/spec/{support/transactions_tests → spec_tests/data/transactions}/retryable-writes.yml +0 -0
  756. data/spec/{support/transactions_tests → spec_tests/data/transactions}/run-command.yml +0 -0
  757. data/spec/{support/transactions_tests → spec_tests/data/transactions}/transaction-options.yml +0 -0
  758. data/spec/{support/transactions_tests → spec_tests/data/transactions}/update.yml +0 -0
  759. data/spec/{support/transactions_tests → spec_tests/data/transactions}/write-concern.yml +0 -0
  760. data/spec/spec_tests/data/transactions_api/callback-aborts.yml +156 -0
  761. data/spec/spec_tests/data/transactions_api/callback-commits.yml +192 -0
  762. data/spec/spec_tests/data/transactions_api/callback-retry.yml +203 -0
  763. data/spec/spec_tests/data/transactions_api/commit-retry.yml +261 -0
  764. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +132 -0
  765. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +178 -0
  766. data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +269 -0
  767. data/spec/spec_tests/data/transactions_api/commit.yml +181 -0
  768. data/spec/spec_tests/data/transactions_api/transaction-options.yml +258 -0
  769. data/spec/spec_tests/data/uri_options/auth-options.yml +14 -0
  770. data/spec/spec_tests/data/uri_options/compression-options.yml +48 -0
  771. data/spec/spec_tests/data/uri_options/concern-options.yml +55 -0
  772. data/spec/spec_tests/data/uri_options/connection-options.yml +106 -0
  773. data/spec/spec_tests/data/uri_options/connection-pool-options.yml +26 -0
  774. data/spec/spec_tests/data/uri_options/read-preference-options.yml +42 -0
  775. data/spec/spec_tests/data/uri_options/tls-options.yml +89 -0
  776. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +0 -40
  777. data/spec/spec_tests/gridfs_spec.rb +1 -1
  778. data/spec/spec_tests/max_staleness_spec.rb +21 -8
  779. data/spec/spec_tests/retryable_writes_spec.rb +6 -6
  780. data/spec/spec_tests/sdam_monitoring_spec.rb +38 -20
  781. data/spec/spec_tests/sdam_spec.rb +80 -15
  782. data/spec/spec_tests/server_selection_rtt_spec.rb +6 -63
  783. data/spec/spec_tests/server_selection_spec.rb +18 -3
  784. data/spec/spec_tests/transactions_api_spec.rb +60 -0
  785. data/spec/spec_tests/transactions_spec.rb +20 -13
  786. data/spec/spec_tests/uri_options_spec.rb +94 -0
  787. data/spec/support/authorization.rb +28 -167
  788. data/spec/support/change_streams.rb +7 -7
  789. data/spec/support/change_streams/operation.rb +1 -1
  790. data/spec/support/client_registry.rb +170 -0
  791. data/spec/support/client_registry_macros.rb +14 -0
  792. data/spec/support/cluster_config.rb +49 -0
  793. data/spec/support/command_monitoring.rb +3 -3
  794. data/spec/support/common_shortcuts.rb +12 -0
  795. data/spec/support/connection_string.rb +99 -7
  796. data/spec/support/constraints.rb +24 -13
  797. data/spec/support/crud.rb +9 -97
  798. data/spec/support/crud/read.rb +2 -2
  799. data/spec/support/crud/verifier.rb +98 -0
  800. data/spec/support/crud/write.rb +2 -2
  801. data/spec/support/event_subscriber.rb +25 -13
  802. data/spec/support/gridfs.rb +8 -5
  803. data/spec/support/json_ext_formatter.rb +9 -0
  804. data/spec/support/lite_constraints.rb +27 -1
  805. data/spec/support/monitoring_ext.rb +16 -0
  806. data/spec/support/sdam_formatter_integration.rb +110 -0
  807. data/spec/support/sdam_monitoring.rb +77 -17
  808. data/spec/support/server_discovery_and_monitoring.rb +43 -20
  809. data/spec/support/server_selection.rb +3 -13
  810. data/spec/support/server_selection_rtt.rb +10 -10
  811. data/spec/support/shared/server_selector.rb +13 -41
  812. data/spec/support/shared/session.rb +44 -22
  813. data/spec/support/spec_config.rb +186 -11
  814. data/spec/support/spec_setup.rb +61 -0
  815. data/spec/support/transactions.rb +79 -145
  816. data/spec/support/transactions/operation.rb +53 -14
  817. data/spec/support/transactions/verifier.rb +94 -0
  818. metadata +712 -565
  819. metadata.gz.sig +0 -0
  820. data/lib/mongo/cluster/topology/replica_set.rb +0 -339
  821. data/lib/mongo/event/member_discovered.rb +0 -67
  822. data/lib/mongo/event/primary_elected.rb +0 -55
  823. data/lib/mongo/event/standalone_discovered.rb +0 -53
  824. data/lib/mongo/server/description/inspector.rb +0 -81
  825. data/lib/mongo/server/description/inspector/description_changed.rb +0 -57
  826. data/lib/mongo/server/description/inspector/member_discovered.rb +0 -59
  827. data/lib/mongo/server/description/inspector/primary_elected.rb +0 -60
  828. data/lib/mongo/server/description/inspector/standalone_discovered.rb +0 -56
  829. data/spec/mongo/server/description/inspector/description_changed_spec.rb +0 -78
  830. data/spec/mongo/server/description/inspector/primary_elected_spec.rb +0 -94
  831. data/spec/support/sdam/rs/set_version_without_electionid.yml +0 -69
  832. data/spec/support/travis.rb +0 -14
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2018 MongoDB, Inc.
1
+ # Copyright (C) 2014-2019 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.
@@ -16,7 +16,6 @@ require 'mongo/cluster/topology'
16
16
  require 'mongo/cluster/reapers/socket_reaper'
17
17
  require 'mongo/cluster/reapers/cursor_reaper'
18
18
  require 'mongo/cluster/periodic_executor'
19
- require 'mongo/cluster/app_metadata'
20
19
 
21
20
  module Mongo
22
21
 
@@ -55,103 +54,6 @@ module Mongo
55
54
  # @since 2.5.0
56
55
  CLUSTER_TIME = 'clusterTime'.freeze
57
56
 
58
- # @return [ Hash ] The options hash.
59
- attr_reader :options
60
-
61
- # @return [ Monitoring ] monitoring The monitoring.
62
- attr_reader :monitoring
63
-
64
- # @return [ Object ] The cluster topology.
65
- attr_reader :topology
66
-
67
- # @return [ Mongo::Cluster::AppMetadata ] The application metadata, used for connection
68
- # handshakes.
69
- #
70
- # @since 2.4.0
71
- attr_reader :app_metadata
72
-
73
- # @return [ BSON::Document ] The latest cluster time seen.
74
- #
75
- # @since 2.5.0
76
- attr_reader :cluster_time
77
-
78
- # @private
79
- #
80
- # @since 2.5.1
81
- attr_reader :session_pool
82
-
83
- def_delegators :topology, :replica_set?, :replica_set_name, :sharded?,
84
- :single?, :unknown?, :member_discovered
85
- def_delegators :@cursor_reaper, :register_cursor, :schedule_kill_cursor, :unregister_cursor
86
-
87
- # Determine if this cluster of servers is equal to another object. Checks the
88
- # servers currently in the cluster, not what was configured.
89
- #
90
- # @example Is the cluster equal to the object?
91
- # cluster == other
92
- #
93
- # @param [ Object ] other The object to compare to.
94
- #
95
- # @return [ true, false ] If the objects are equal.
96
- #
97
- # @since 2.0.0
98
- def ==(other)
99
- return false unless other.is_a?(Cluster)
100
- addresses == other.addresses && options == other.options
101
- end
102
-
103
- # Add a server to the cluster with the provided address. Useful in
104
- # auto-discovery of new servers when an existing server executes an ismaster
105
- # and potentially non-configured servers were included.
106
- #
107
- # @example Add the server for the address to the cluster.
108
- # cluster.add('127.0.0.1:27018')
109
- #
110
- # @param [ String ] host The address of the server to add.
111
- #
112
- # @return [ Server ] The newly added server, if not present already.
113
- #
114
- # @since 2.0.0
115
- def add(host)
116
- address = Address.new(host, options)
117
- if !addresses.include?(address)
118
- if addition_allowed?(address)
119
- @update_lock.synchronize { @addresses.push(address) }
120
- server = Server.new(address, self, @monitoring, event_listeners, options)
121
- @update_lock.synchronize { @servers.push(server) }
122
- server
123
- end
124
- end
125
- end
126
-
127
- # Determine if the cluster would select a readable server for the
128
- # provided read preference.
129
- #
130
- # @example Is a readable server present?
131
- # topology.has_readable_server?(server_selector)
132
- #
133
- # @param [ ServerSelector ] server_selector The server
134
- # selector.
135
- #
136
- # @return [ true, false ] If a readable server is present.
137
- #
138
- # @since 2.4.0
139
- def has_readable_server?(server_selector = nil)
140
- topology.has_readable_server?(self, server_selector)
141
- end
142
-
143
- # Determine if the cluster would select a writable server.
144
- #
145
- # @example Is a writable server present?
146
- # topology.has_writable_server?
147
- #
148
- # @return [ true, false ] If a writable server is present.
149
- #
150
- # @since 2.4.0
151
- def has_writable_server?
152
- topology.has_writable_server?(self)
153
- end
154
-
155
57
  # Instantiate the new cluster.
156
58
  #
157
59
  # @api private
@@ -171,37 +73,80 @@ module Mongo
171
73
  # @param [ Hash ] options Options. Client constructor forwards its
172
74
  # options to Cluster constructor, although Cluster recognizes
173
75
  # only a subset of the options recognized by Client.
76
+ # @option options [ true, false ] :scan Whether to scan all seeds
77
+ # in constructor. The default in driver version 2.x is to do so;
78
+ # driver version 3.x will not scan seeds in constructor. Opt in to the
79
+ # new behavior by setting this option to false. *Note:* setting
80
+ # this option to nil enables scanning seeds in constructor in driver
81
+ # version 2.x. Driver version 3.x will recognize this option but
82
+ # will ignore it and will never scan seeds in the constructor.
83
+ # @option options [ true, false ] :monitoring_io For internal driver
84
+ # use only. Set to false to prevent SDAM-related I/O from being
85
+ # done by this cluster or servers under it. Note: setting this option
86
+ # to false will make the cluster non-functional. It is intended for
87
+ # use in tests which manually invoke SDAM state transitions.
174
88
  #
175
89
  # @since 2.0.0
176
90
  def initialize(seeds, monitoring, options = Options::Redacted.new)
177
- @addresses = []
91
+ if options[:monitoring_io] != false && !options[:server_selection_semaphore]
92
+ raise ArgumentError, 'Need server selection semaphore'
93
+ end
94
+
178
95
  @servers = []
179
96
  @monitoring = monitoring
180
97
  @event_listeners = Event::Listeners.new
181
98
  @options = options.freeze
182
- @app_metadata = AppMetadata.new(self)
99
+ @app_metadata = Server::AppMetadata.new(@options)
183
100
  @update_lock = Mutex.new
101
+ @sdam_flow_lock = Mutex.new
184
102
  @pool_lock = Mutex.new
185
103
  @cluster_time = nil
186
104
  @cluster_time_lock = Mutex.new
187
- @topology = Topology.initial(seeds, monitoring, options)
105
+ @topology = Topology.initial(self, monitoring, options)
188
106
  Session::SessionPool.create(self)
189
107
 
108
+ # The opening topology is always unknown with no servers.
109
+ # https://github.com/mongodb/specifications/pull/388
110
+ opening_topology = Topology::Unknown.new(options, monitoring, self)
111
+
190
112
  publish_sdam_event(
191
113
  Monitoring::TOPOLOGY_OPENING,
192
- Monitoring::Event::TopologyOpening.new(@topology)
114
+ Monitoring::Event::TopologyOpening.new(opening_topology)
193
115
  )
194
116
 
195
- subscribe_to(Event::STANDALONE_DISCOVERED, Event::StandaloneDiscovered.new(self))
196
117
  subscribe_to(Event::DESCRIPTION_CHANGED, Event::DescriptionChanged.new(self))
197
- subscribe_to(Event::MEMBER_DISCOVERED, Event::MemberDiscovered.new(self))
198
118
 
199
- seeds.each{ |seed| add(seed) }
119
+ @seeds = seeds
120
+ servers = seeds.map do |seed|
121
+ # Server opening events must be sent after topology change events.
122
+ # Therefore separate server addition, done here before topoolgy change
123
+ # event is published, from starting to monitor the server which is
124
+ # done later.
125
+ add(seed, monitor: false)
126
+ end
200
127
 
201
- publish_sdam_event(
202
- Monitoring::TOPOLOGY_CHANGED,
203
- Monitoring::Event::TopologyChanged.new(@topology, @topology)
204
- ) if @servers.size > 1
128
+ if seeds.size >= 1
129
+ # Recreate the topology to get the current server list into it
130
+ @topology = topology.class.new(topology.options, topology.monitoring, self)
131
+ publish_sdam_event(
132
+ Monitoring::TOPOLOGY_CHANGED,
133
+ Monitoring::Event::TopologyChanged.new(opening_topology, @topology)
134
+ )
135
+ end
136
+
137
+ servers.each do |server|
138
+ server.start_monitoring
139
+ end
140
+
141
+ if options[:monitoring_io] == false
142
+ # Omit periodic executor construction, because without servers
143
+ # no commands can be sent to the cluster and there shouldn't ever
144
+ # be anything that needs to be cleaned up.
145
+ #
146
+ # Also omit legacy single round of SDAM on the main thread,
147
+ # as it would race with tests that mock SDAM responses.
148
+ return
149
+ end
205
150
 
206
151
  @cursor_reaper = CursorReaper.new
207
152
  @socket_reaper = SocketReaper.new(self)
@@ -209,74 +154,98 @@ module Mongo
209
154
  @periodic_executor.run!
210
155
 
211
156
  ObjectSpace.define_finalizer(self, self.class.finalize(pools, @periodic_executor, @session_pool))
212
- end
213
157
 
214
- # Finalize the cluster for garbage collection. Disconnects all the scoped
215
- # connection pools.
216
- #
217
- # @example Finalize the cluster.
218
- # Cluster.finalize(pools)
219
- #
220
- # @param [ Hash<Address, Server::ConnectionPool> ] pools The connection pools.
221
- # @param [ PeriodicExecutor ] periodic_executor The periodic executor.
222
- # @param [ SessionPool ] session_pool The session pool.
223
- #
224
- # @return [ Proc ] The Finalizer.
225
- #
226
- # @since 2.2.0
227
- def self.finalize(pools, periodic_executor, session_pool)
228
- proc do
229
- session_pool.end_sessions
230
- periodic_executor.stop!
231
- pools.values.each do |pool|
232
- pool.disconnect!
158
+ @connecting = false
159
+ @connected = true
160
+
161
+ if options[:scan] != false
162
+ server_selection_timeout = options[:server_selection_timeout] || ServerSelector::SERVER_SELECTION_TIMEOUT
163
+ # The server selection timeout can be very short especially in
164
+ # tests, when the client waits for a synchronous scan before
165
+ # starting server selection. Limiting the scan to server selection time
166
+ # then aborts the scan before it can process even local servers.
167
+ # Therefore, allow at least 3 seconds for the scan here.
168
+ if server_selection_timeout < 3
169
+ server_selection_timeout = 3
170
+ end
171
+ start_time = Time.now
172
+ deadline = start_time + server_selection_timeout
173
+ # Wait for the first scan of each server to complete, for
174
+ # backwards compatibility.
175
+ # If any servers are discovered during this SDAM round we are going to
176
+ # wait for these servers to also be queried, and so on, up to the
177
+ # server selection timeout or the 3 second minimum.
178
+ loop do
179
+ servers = servers_list.dup
180
+ if servers.all? { |server| server.description.last_update_time > start_time }
181
+ break
182
+ end
183
+ if (time_remaining = deadline - Time.now) <= 0
184
+ break
185
+ end
186
+ options[:server_selection_semaphore].wait(time_remaining)
233
187
  end
234
188
  end
235
189
  end
236
190
 
237
- # Get the nicer formatted string for use in inspection.
238
- #
239
- # @example Inspect the cluster.
240
- # cluster.inspect
241
- #
242
- # @return [ String ] The cluster inspection.
243
- #
244
- # @since 2.0.0
245
- def inspect
246
- "#<Mongo::Cluster:0x#{object_id} servers=#{servers} topology=#{topology.display_name}>"
247
- end
248
-
249
- # Get the next primary server we can send an operation to.
191
+ # Create a cluster for the provided client, for use when we don't want the
192
+ # client's original cluster instance to be the same.
250
193
  #
251
- # @example Get the next primary server.
252
- # cluster.next_primary
194
+ # @api private
253
195
  #
254
- # @param [ true, false ] ping Whether to ping the server before selection. Deprecated,
255
- # not necessary with the implementation of the Server Selection specification.
196
+ # @example Create a cluster for the client.
197
+ # Cluster.create(client)
256
198
  #
199
+ # @param [ Client ] client The client to create on.
257
200
  #
258
- # @return [ Mongo::Server ] A primary server.
201
+ # @return [ Cluster ] The cluster.
259
202
  #
260
203
  # @since 2.0.0
261
- def next_primary(ping = true)
262
- @primary_selector ||= ServerSelector.get(ServerSelector::PRIMARY)
263
- @primary_selector.select_server(self)
204
+ def self.create(client)
205
+ cluster = Cluster.new(
206
+ client.cluster.addresses.map(&:to_s),
207
+ Monitoring.new,
208
+ client.cluster_options,
209
+ )
210
+ client.instance_variable_set(:@cluster, cluster)
264
211
  end
265
212
 
266
- # Elect a primary server from the description that has just changed to a
267
- # primary.
213
+ # @return [ Hash ] The options hash.
214
+ attr_reader :options
215
+
216
+ # @return [ Monitoring ] monitoring The monitoring.
217
+ attr_reader :monitoring
218
+
219
+ # @return [ Object ] The cluster topology.
220
+ attr_reader :topology
221
+
222
+ # @return [ Mongo::Server::AppMetadata ] The application metadata, used for connection
223
+ # handshakes.
268
224
  #
269
- # @example Elect a primary server.
270
- # cluster.elect_primary!(description)
225
+ # @since 2.4.0
226
+ attr_reader :app_metadata
227
+
228
+ # @return [ BSON::Document ] The latest cluster time seen.
271
229
  #
272
- # @param [ Server::Description ] description The newly elected primary.
230
+ # @since 2.5.0
231
+ attr_reader :cluster_time
232
+
233
+ # @return [ Array<String> ] The addresses of seed servers. Contains
234
+ # addresses that were given to Cluster when it was instantiated, not
235
+ # current addresses that the cluster is using as a result of SDAM.
273
236
  #
274
- # @return [ Topology ] The cluster topology.
237
+ # @since 2.7.0
238
+ # @api private
239
+ attr_reader :seeds
240
+
241
+ # @private
275
242
  #
276
- # @since 2.0.0
277
- def elect_primary!(description)
278
- @topology = topology.elect_primary(description, servers_list)
279
- end
243
+ # @since 2.5.1
244
+ attr_reader :session_pool
245
+
246
+ def_delegators :topology, :replica_set?, :replica_set_name, :sharded?,
247
+ :single?, :unknown?
248
+ def_delegators :@cursor_reaper, :register_cursor, :schedule_kill_cursor, :unregister_cursor
280
249
 
281
250
  # Get the maximum number of times the cluster can retry a read operation on
282
251
  # a mongos.
@@ -291,22 +260,6 @@ module Mongo
291
260
  options[:max_read_retries] || MAX_READ_RETRIES
292
261
  end
293
262
 
294
- # Get the scoped connection pool for the server.
295
- #
296
- # @example Get the connection pool.
297
- # cluster.pool(server)
298
- #
299
- # @param [ Server ] server The server.
300
- #
301
- # @return [ Server::ConnectionPool ] The connection pool.
302
- #
303
- # @since 2.2.0
304
- def pool(server)
305
- @pool_lock.synchronize do
306
- pools[server.address] ||= Server::ConnectionPool.get(server)
307
- end
308
- end
309
-
310
263
  # Get the interval, in seconds, in which a mongos read operation is
311
264
  # retried.
312
265
  #
@@ -320,87 +273,134 @@ module Mongo
320
273
  options[:read_retry_interval] || READ_RETRY_INTERVAL
321
274
  end
322
275
 
323
- # Notify the cluster that a standalone server was discovered so that the
324
- # topology can be updated accordingly.
276
+ # Whether the cluster object is connected to its cluster.
325
277
  #
326
- # @example Notify the cluster that a standalone server was discovered.
327
- # cluster.standalone_discovered
278
+ # @return [ true|false ] Whether the cluster is connected.
328
279
  #
329
- # @return [ Topology ] The cluster topology.
330
- #
331
- # @since 2.0.6
332
- def standalone_discovered
333
- @topology = topology.standalone_discovered
280
+ # @api private
281
+ # @since 2.7.0
282
+ def connected?
283
+ !!@connected
334
284
  end
335
285
 
336
- # Remove the server from the cluster for the provided address, if it
337
- # exists.
286
+ # Get a list of server candidates from the cluster that can have operations
287
+ # executed on them.
338
288
  #
339
- # @example Remove the server from the cluster.
340
- # server.remove('127.0.0.1:27017')
289
+ # @example Get the server candidates for an operation.
290
+ # cluster.servers
341
291
  #
342
- # @param [ String ] host The host/port or socket address.
292
+ # @return [ Array<Server> ] The candidate servers.
343
293
  #
344
294
  # @since 2.0.0
345
- def remove(host)
346
- log_warn("Removing server #{host}")
347
- address = Address.new(host)
348
- removed_servers = @servers.select { |s| s.address == address }
349
- @update_lock.synchronize do
350
- @servers = @servers - removed_servers
351
- if @servers.empty?
352
- log_warn(
353
- "Topology now has no servers - this is likely a misconfiguration of the cluster and/or the application"
354
- )
355
- end
356
- end
357
- removed_servers.each{ |server| server.disconnect! } if removed_servers
358
- publish_sdam_event(
359
- Monitoring::SERVER_CLOSED,
360
- Monitoring::Event::ServerClosed.new(address, topology)
361
- )
362
- @update_lock.synchronize { @addresses.reject! { |addr| addr == address } }
295
+ def servers
296
+ topology.servers(servers_list.compact).compact
363
297
  end
364
298
 
365
- # Force a scan of all known servers in the cluster.
299
+ # The addresses in the cluster.
366
300
  #
367
- # @example Force a full cluster scan.
368
- # cluster.scan!
301
+ # @example Get the addresses in the cluster.
302
+ # cluster.addresses
369
303
  #
370
- # @note This operation is done synchronously. If servers in the cluster are
371
- # down or slow to respond this can potentially be a slow operation.
304
+ # @return [ Array<Mongo::Address> ] The addresses.
372
305
  #
373
- # @return [ true ] Always true.
306
+ # @since 2.0.6
307
+ def addresses
308
+ servers_list.map(&:address).dup
309
+ end
310
+
311
+ # The logical session timeout value in minutes.
312
+ #
313
+ # @example Get the logical session timeout in minutes.
314
+ # cluster.logical_session_timeout
315
+ #
316
+ # @return [ Integer, nil ] The logical session timeout.
317
+ #
318
+ # @since 2.5.0
319
+ def_delegators :topology, :logical_session_timeout
320
+
321
+ # Get the nicer formatted string for use in inspection.
322
+ #
323
+ # @example Inspect the cluster.
324
+ # cluster.inspect
325
+ #
326
+ # @return [ String ] The cluster inspection.
374
327
  #
375
328
  # @since 2.0.0
376
- def scan!
377
- servers_list.each{ |server| server.scan! } and true
329
+ def inspect
330
+ "#<Mongo::Cluster:0x#{object_id} servers=#{servers} topology=#{topology.summary}>"
378
331
  end
379
332
 
380
- # Get a list of server candidates from the cluster that can have operations
381
- # executed on them.
333
+ # @note This method is experimental and subject to change.
382
334
  #
383
- # @example Get the server candidates for an operation.
384
- # cluster.servers
335
+ # @api experimental
336
+ # @since 2.7.0
337
+ def summary
338
+ "#<Cluster " +
339
+ "topology=#{topology.summary} "+
340
+ "servers=[#{servers.map(&:summary).join(',')}]>"
341
+ end
342
+
343
+ # @api private
344
+ attr_reader :server_selection_semaphore
345
+
346
+ # Finalize the cluster for garbage collection. Disconnects all the scoped
347
+ # connection pools.
385
348
  #
386
- # @return [ Array<Server> ] The candidate servers.
349
+ # @example Finalize the cluster.
350
+ # Cluster.finalize(pools)
387
351
  #
388
- # @since 2.0.0
389
- def servers
390
- topology.servers(servers_list.compact).compact
352
+ # @param [ Hash<Address, Server::ConnectionPool> ] pools The connection pools.
353
+ # @param [ PeriodicExecutor ] periodic_executor The periodic executor.
354
+ # @param [ SessionPool ] session_pool The session pool.
355
+ #
356
+ # @return [ Proc ] The Finalizer.
357
+ #
358
+ # @since 2.2.0
359
+ def self.finalize(pools, periodic_executor, session_pool)
360
+ proc do
361
+ session_pool.end_sessions
362
+ periodic_executor.stop!
363
+ pools.values.each do |pool|
364
+ pool.disconnect!
365
+ end
366
+ end
391
367
  end
392
368
 
393
369
  # Disconnect all servers.
394
370
  #
371
+ # @note Applications should call Client#close to disconnect from
372
+ # the cluster rather than calling this method. This method is for
373
+ # internal driver use only.
374
+ #
395
375
  # @example Disconnect the cluster's servers.
396
376
  # cluster.disconnect!
397
377
  #
378
+ # @param [ Boolean ] wait Whether to wait for background threads to
379
+ # finish running.
380
+ #
398
381
  # @return [ true ] Always true.
399
382
  #
400
383
  # @since 2.1.0
401
- def disconnect!
384
+ def disconnect!(wait=false)
385
+ unless @connecting || @connected
386
+ return true
387
+ end
402
388
  @periodic_executor.stop!
403
- @servers.each { |server| server.disconnect! } and true
389
+ @servers.each do |server|
390
+ if server.connected?
391
+ server.disconnect!(wait)
392
+ publish_sdam_event(
393
+ Monitoring::SERVER_CLOSED,
394
+ Monitoring::Event::ServerClosed.new(server.address, topology)
395
+ )
396
+ end
397
+ end
398
+ publish_sdam_event(
399
+ Monitoring::TOPOLOGY_CLOSED,
400
+ Monitoring::Event::TopologyClosed.new(topology)
401
+ )
402
+ @connecting = @connected = false
403
+ true
404
404
  end
405
405
 
406
406
  # Reconnect all servers.
@@ -411,88 +411,131 @@ module Mongo
411
411
  # @return [ true ] Always true.
412
412
  #
413
413
  # @since 2.1.0
414
+ # @deprecated Use Client#reconnect to reconnect to the cluster instead of
415
+ # calling this method. This method does not send SDAM events.
414
416
  def reconnect!
417
+ @connecting = true
415
418
  scan!
416
- servers.each { |server| server.reconnect! }
417
- @periodic_executor.restart! and true
419
+ servers.each do |server|
420
+ server.reconnect!
421
+ end
422
+ @periodic_executor.restart!
423
+ @connecting = false
424
+ @connected = true
418
425
  end
419
426
 
420
- # Add hosts in a description to the cluster.
427
+ # Force a scan of all known servers in the cluster.
421
428
  #
422
- # @example Add hosts in a description to the cluster.
423
- # cluster.add_hosts(description)
429
+ # If the sync parameter is true which is the default, the scan is
430
+ # performed synchronously in the thread which called this method.
431
+ # Each server in the cluster is checked sequentially. If there are
432
+ # many servers in the cluster or they are slow to respond, this
433
+ # can be a long running operation.
424
434
  #
425
- # @param [ Mongo::Server::Description ] description The description.
435
+ # If the sync parameter is false, this method instructs all server
436
+ # monitor threads to perform an immediate scan and returns without
437
+ # waiting for scan results.
426
438
  #
427
- # @since 2.0.6
428
- def add_hosts(description)
429
- if topology.add_hosts?(description, servers_list)
430
- description.servers.each { |s| add(s) }
439
+ # @note In both synchronous and asynchronous scans, each monitor
440
+ # thread maintains a minimum interval between scans, meaning
441
+ # calling this method may not initiate a scan on a particular server
442
+ # the very next instant.
443
+ #
444
+ # @example Force a full cluster scan.
445
+ # cluster.scan!
446
+ #
447
+ # @return [ true ] Always true.
448
+ #
449
+ # @since 2.0.0
450
+ def scan!(sync=true)
451
+ if sync
452
+ servers_list.each do |server|
453
+ server.scan!
454
+ end
455
+ else
456
+ servers_list.each do |server|
457
+ server.monitor.scan_semaphore.signal
458
+ end
431
459
  end
460
+ true
432
461
  end
433
462
 
434
- # Remove hosts in a description from the cluster.
463
+ # Determine if this cluster of servers is equal to another object. Checks the
464
+ # servers currently in the cluster, not what was configured.
435
465
  #
436
- # @example Remove hosts in a description from the cluster.
437
- # cluster.remove_hosts(description)
466
+ # @example Is the cluster equal to the object?
467
+ # cluster == other
438
468
  #
439
- # @param [ Mongo::Server::Description ] description The description.
469
+ # @param [ Object ] other The object to compare to.
440
470
  #
441
- # @since 2.0.6
442
- def remove_hosts(description)
443
- if topology.remove_hosts?(description)
444
- servers_list.each do |s|
445
- remove(s.address.to_s) if topology.remove_server?(description, s)
446
- end
447
- end
471
+ # @return [ true, false ] If the objects are equal.
472
+ #
473
+ # @since 2.0.0
474
+ def ==(other)
475
+ return false unless other.is_a?(Cluster)
476
+ addresses == other.addresses &&
477
+ options.merge(server_selection_semaphore: nil) ==
478
+ other.options.merge(server_selection_semaphore: nil)
448
479
  end
449
480
 
450
- # Create a cluster for the provided client, for use when we don't want the
451
- # client's original cluster instance to be the same.
481
+ # Determine if the cluster would select a readable server for the
482
+ # provided read preference.
452
483
  #
453
- # @api private
484
+ # @example Is a readable server present?
485
+ # topology.has_readable_server?(server_selector)
454
486
  #
455
- # @example Create a cluster for the client.
456
- # Cluster.create(client)
487
+ # @param [ ServerSelector ] server_selector The server
488
+ # selector.
457
489
  #
458
- # @param [ Client ] client The client to create on.
490
+ # @return [ true, false ] If a readable server is present.
459
491
  #
460
- # @return [ Cluster ] The cluster.
492
+ # @since 2.4.0
493
+ def has_readable_server?(server_selector = nil)
494
+ topology.has_readable_server?(self, server_selector)
495
+ end
496
+
497
+ # Determine if the cluster would select a writable server.
461
498
  #
462
- # @since 2.0.0
463
- def self.create(client)
464
- cluster = Cluster.new(
465
- client.cluster.addresses.map(&:to_s),
466
- Monitoring.new,
467
- client.options
468
- )
469
- client.instance_variable_set(:@cluster, cluster)
499
+ # @example Is a writable server present?
500
+ # topology.has_writable_server?
501
+ #
502
+ # @return [ true, false ] If a writable server is present.
503
+ #
504
+ # @since 2.4.0
505
+ def has_writable_server?
506
+ topology.has_writable_server?(self)
470
507
  end
471
508
 
472
- # The addresses in the cluster.
509
+ # Get the next primary server we can send an operation to.
473
510
  #
474
- # @example Get the addresses in the cluster.
475
- # cluster.addresses
511
+ # @example Get the next primary server.
512
+ # cluster.next_primary
476
513
  #
477
- # @return [ Array<Mongo::Address> ] The addresses.
514
+ # @param [ true, false ] ping Whether to ping the server before selection. Deprecated,
515
+ # not necessary with the implementation of the Server Selection specification.
478
516
  #
479
- # @since 2.0.6
480
- def addresses
481
- addresses_list
517
+ #
518
+ # @return [ Mongo::Server ] A primary server.
519
+ #
520
+ # @since 2.0.0
521
+ def next_primary(ping = true)
522
+ @primary_selector ||= ServerSelector.get(ServerSelector::PRIMARY)
523
+ @primary_selector.select_server(self)
482
524
  end
483
525
 
484
- # The logical session timeout value in minutes.
526
+ # Get the scoped connection pool for the server.
485
527
  #
486
- # @example Get the logical session timeout in minutes.
487
- # cluster.logical_session_timeout
528
+ # @example Get the connection pool.
529
+ # cluster.pool(server)
488
530
  #
489
- # @return [ Integer, nil ] The logical session timeout.
531
+ # @param [ Server ] server The server.
490
532
  #
491
- # @since 2.5.0
492
- def logical_session_timeout
493
- servers.inject(nil) do |min, server|
494
- break unless timeout = server.logical_session_timeout
495
- [timeout, (min || timeout)].min
533
+ # @return [ Server::ConnectionPool ] The connection pool.
534
+ #
535
+ # @since 2.2.0
536
+ def pool(server)
537
+ @pool_lock.synchronize do
538
+ pools[server.address] ||= Server::ConnectionPool.get(server)
496
539
  end
497
540
  end
498
541
 
@@ -518,8 +561,88 @@ module Mongo
518
561
  end
519
562
  end
520
563
 
564
+ # Add a server to the cluster with the provided address. Useful in
565
+ # auto-discovery of new servers when an existing server executes an ismaster
566
+ # and potentially non-configured servers were included.
567
+ #
568
+ # @example Add the server for the address to the cluster.
569
+ # cluster.add('127.0.0.1:27018')
570
+ #
571
+ # @param [ String ] host The address of the server to add.
572
+ #
573
+ # @option options [ Boolean ] :monitor For internal driver use only:
574
+ # whether to monitor the newly added server.
575
+ #
576
+ # @return [ Server ] The newly added server, if not present already.
577
+ #
578
+ # @since 2.0.0
579
+ def add(host, add_options=nil)
580
+ address = Address.new(host, options)
581
+ if !addresses.include?(address)
582
+ server = Server.new(address, self, @monitoring, event_listeners, options.merge(
583
+ monitor: false))
584
+ @update_lock.synchronize { @servers.push(server) }
585
+ if add_options.nil? || add_options[:monitor] != false
586
+ server.start_monitoring
587
+ end
588
+ server
589
+ end
590
+ end
591
+
592
+ # Remove the server from the cluster for the provided address, if it
593
+ # exists.
594
+ #
595
+ # @example Remove the server from the cluster.
596
+ # server.remove('127.0.0.1:27017')
597
+ #
598
+ # @param [ String ] host The host/port or socket address.
599
+ #
600
+ # @return [ true|false ] Whether any servers were removed.
601
+ #
602
+ # @since 2.0.0, return value added in 2.7.0
603
+ def remove(host)
604
+ address = Address.new(host)
605
+ removed_servers = @servers.select { |s| s.address == address }
606
+ @update_lock.synchronize { @servers = @servers - removed_servers }
607
+ removed_servers.each do |server|
608
+ if server.connected?
609
+ server.disconnect!
610
+ publish_sdam_event(
611
+ Monitoring::SERVER_CLOSED,
612
+ Monitoring::Event::ServerClosed.new(address, topology)
613
+ )
614
+ end
615
+ end
616
+ removed_servers.any?
617
+ end
618
+
619
+ # @api private
620
+ def update_topology(new_topology)
621
+ old_topology = topology
622
+ @topology = new_topology
623
+ publish_sdam_event(
624
+ Monitoring::TOPOLOGY_CHANGED,
625
+ Monitoring::Event::TopologyChanged.new(old_topology, topology)
626
+ )
627
+ end
628
+
629
+ # @api private
630
+ def servers_list
631
+ @update_lock.synchronize { @servers.dup }
632
+ end
633
+
634
+ # @api private
635
+ attr_reader :sdam_flow_lock
636
+
521
637
  private
522
638
 
639
+ # If options[:session] is set, validates that session and returns it.
640
+ # If deployment supports sessions, creates a new session and returns it.
641
+ # The session is implicit unless options[:implicit] is given.
642
+ # If deployment does not support session, returns nil.
643
+ #
644
+ # @note This method will return nil if deployment has no data-bearing
645
+ # servers at the time of the call.
523
646
  def get_session(client, options = {})
524
647
  return options[:session].validate!(self) if options[:session]
525
648
  if sessions_supported?
@@ -534,32 +657,29 @@ module Mongo
534
657
  session.end_session if (session && session.implicit?)
535
658
  end
536
659
 
660
+ # Returns whether the deployment (as this term is defined in the sessions
661
+ # spec) supports sessions.
662
+ #
663
+ # @note If the cluster has no data bearing servers, for example because
664
+ # the deployment is in the middle of a failover, this method returns
665
+ # false.
537
666
  def sessions_supported?
538
- if servers.empty? && !topology.single?
539
- ServerSelector.get(mode: :primary_preferred).select_server(self)
667
+ if topology.data_bearing_servers?
668
+ return !!topology.logical_session_timeout
540
669
  end
541
- !!logical_session_timeout
542
- rescue Error::NoServerAvailable
543
- end
544
-
545
- def direct_connection?(address)
546
- address.seed == @topology.seed
547
- end
548
670
 
549
- def addition_allowed?(address)
550
- !@topology.single? || direct_connection?(address)
671
+ begin
672
+ ServerSelector.get(mode: :primary_preferred).select_server(self)
673
+ !!topology.logical_session_timeout
674
+ rescue Error::NoServerAvailable
675
+ false
676
+ end
551
677
  end
552
678
 
553
679
  def pools
554
680
  @pools ||= {}
555
681
  end
556
-
557
- def servers_list
558
- @update_lock.synchronize { @servers.dup }
559
- end
560
-
561
- def addresses_list
562
- @update_lock.synchronize { @addresses.dup }
563
- end
564
682
  end
565
683
  end
684
+
685
+ require 'mongo/cluster/sdam_flow'