mongo 2.15.1 → 2.16.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (326) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/lib/mongo/bulk_write.rb +2 -2
  5. data/lib/mongo/client.rb +45 -5
  6. data/lib/mongo/cluster/periodic_executor.rb +4 -3
  7. data/lib/mongo/cluster/reapers/cursor_reaper.rb +76 -43
  8. data/lib/mongo/cluster/sdam_flow.rb +9 -3
  9. data/lib/mongo/cluster/topology/base.rb +13 -9
  10. data/lib/mongo/cluster/topology/load_balanced.rb +102 -0
  11. data/lib/mongo/cluster/topology.rb +28 -8
  12. data/lib/mongo/cluster.rb +136 -51
  13. data/lib/mongo/collection/view/aggregation.rb +5 -10
  14. data/lib/mongo/collection/view/builder/aggregation.rb +6 -5
  15. data/lib/mongo/collection/view/builder/map_reduce.rb +12 -49
  16. data/lib/mongo/collection/view/builder.rb +0 -4
  17. data/lib/mongo/collection/view/iterable.rb +42 -18
  18. data/lib/mongo/collection/view/map_reduce.rb +39 -15
  19. data/lib/mongo/collection/view/readable.rb +60 -51
  20. data/lib/mongo/collection/view/writable.rb +178 -175
  21. data/lib/mongo/collection/view.rb +15 -21
  22. data/lib/mongo/collection.rb +13 -13
  23. data/lib/mongo/cursor/kill_spec.rb +38 -0
  24. data/lib/mongo/cursor.rb +62 -31
  25. data/lib/mongo/database/view.rb +1 -1
  26. data/lib/mongo/error/bad_load_balancer_target.rb +26 -0
  27. data/lib/mongo/error/missing_service_id.rb +26 -0
  28. data/lib/mongo/error/no_service_connection_available.rb +49 -0
  29. data/lib/mongo/error/notable.rb +7 -0
  30. data/lib/mongo/error.rb +3 -0
  31. data/lib/mongo/grid/fs_bucket.rb +21 -2
  32. data/lib/mongo/id.rb +7 -5
  33. data/lib/mongo/index/view.rb +22 -41
  34. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +7 -4
  35. data/lib/mongo/monitoring/event/command_failed.rb +1 -1
  36. data/lib/mongo/monitoring/event/command_started.rb +2 -0
  37. data/lib/mongo/monitoring/publishable.rb +2 -2
  38. data/lib/mongo/operation/aggregate/command.rb +8 -0
  39. data/lib/mongo/operation/context.rb +19 -1
  40. data/lib/mongo/operation/count/command.rb +6 -0
  41. data/lib/mongo/operation/count/op_msg.rb +6 -0
  42. data/lib/mongo/operation/create/command.rb +7 -1
  43. data/lib/mongo/operation/create/op_msg.rb +7 -0
  44. data/lib/mongo/operation/create_index/command.rb +17 -1
  45. data/lib/mongo/operation/create_index/op_msg.rb +17 -4
  46. data/lib/mongo/operation/delete/command.rb +6 -3
  47. data/lib/mongo/operation/delete/legacy.rb +9 -2
  48. data/lib/mongo/operation/delete/op_msg.rb +8 -1
  49. data/lib/mongo/operation/distinct/command.rb +6 -0
  50. data/lib/mongo/operation/distinct/op_msg.rb +7 -0
  51. data/lib/mongo/operation/explain/command.rb +13 -1
  52. data/lib/mongo/operation/explain/legacy.rb +12 -5
  53. data/lib/mongo/operation/explain/op_msg.rb +9 -1
  54. data/lib/mongo/operation/find/builder/command.rb +110 -0
  55. data/lib/mongo/{collection/view → operation/find}/builder/flags.rb +10 -14
  56. data/lib/mongo/operation/find/builder/legacy.rb +123 -0
  57. data/lib/mongo/{collection/view → operation/find}/builder/modifiers.rb +31 -25
  58. data/lib/mongo/{cursor → operation/find}/builder.rb +4 -4
  59. data/lib/mongo/operation/find/command.rb +9 -0
  60. data/lib/mongo/operation/find/legacy.rb +10 -1
  61. data/lib/mongo/operation/find/op_msg.rb +12 -0
  62. data/lib/mongo/operation/find.rb +1 -0
  63. data/lib/mongo/operation/get_more/command.rb +1 -0
  64. data/lib/mongo/operation/get_more/command_builder.rb +38 -0
  65. data/lib/mongo/operation/get_more/op_msg.rb +1 -0
  66. data/lib/mongo/operation/get_more.rb +1 -0
  67. data/lib/mongo/operation/kill_cursors/command.rb +8 -0
  68. data/lib/mongo/operation/kill_cursors/command_builder.rb +35 -0
  69. data/lib/mongo/operation/kill_cursors/legacy.rb +2 -1
  70. data/lib/mongo/operation/kill_cursors/op_msg.rb +10 -0
  71. data/lib/mongo/operation/kill_cursors.rb +1 -0
  72. data/lib/mongo/operation/map_reduce/command.rb +8 -0
  73. data/lib/mongo/operation/map_reduce/op_msg.rb +1 -1
  74. data/lib/mongo/operation/shared/executable.rb +15 -1
  75. data/lib/mongo/operation/shared/polymorphic_operation.rb +1 -1
  76. data/lib/mongo/operation/shared/read_preference_supported.rb +3 -1
  77. data/lib/mongo/operation/shared/response_handling.rb +1 -0
  78. data/lib/mongo/operation/shared/sessions_supported.rb +12 -12
  79. data/lib/mongo/operation/shared/specifiable.rb +11 -29
  80. data/lib/mongo/operation/shared/validatable.rb +87 -0
  81. data/lib/mongo/operation/shared/write.rb +1 -1
  82. data/lib/mongo/operation/update/command.rb +6 -3
  83. data/lib/mongo/operation/update/legacy.rb +19 -11
  84. data/lib/mongo/operation/update/op_msg.rb +7 -4
  85. data/lib/mongo/operation/write_command/command.rb +51 -0
  86. data/lib/mongo/operation/write_command/op_msg.rb +43 -0
  87. data/lib/mongo/operation/write_command.rb +32 -0
  88. data/lib/mongo/operation.rb +10 -0
  89. data/lib/mongo/protocol/query.rb +35 -18
  90. data/lib/mongo/server/connection.rb +25 -3
  91. data/lib/mongo/server/connection_base.rb +12 -1
  92. data/lib/mongo/server/connection_common.rb +38 -1
  93. data/lib/mongo/server/connection_pool/generation_manager.rb +71 -0
  94. data/lib/mongo/server/connection_pool.rb +100 -27
  95. data/lib/mongo/server/description/features.rb +17 -16
  96. data/lib/mongo/server/description/load_balancer.rb +33 -0
  97. data/lib/mongo/server/description.rb +85 -6
  98. data/lib/mongo/server/monitor/connection.rb +5 -6
  99. data/lib/mongo/server/monitor.rb +2 -1
  100. data/lib/mongo/server/pending_connection.rb +47 -31
  101. data/lib/mongo/server.rb +73 -26
  102. data/lib/mongo/server_selector/base.rb +5 -1
  103. data/lib/mongo/session/session_pool.rb +11 -0
  104. data/lib/mongo/session.rb +21 -1
  105. data/lib/mongo/socket/ocsp_verifier.rb +6 -37
  106. data/lib/mongo/uri/options_mapper.rb +1 -0
  107. data/lib/mongo/uri/srv_protocol.rb +6 -8
  108. data/lib/mongo/uri.rb +18 -0
  109. data/lib/mongo/utils.rb +0 -7
  110. data/lib/mongo/version.rb +1 -1
  111. data/mongo.gemspec +1 -1
  112. data/spec/integration/auth_spec.rb +31 -1
  113. data/spec/integration/awaited_ismaster_spec.rb +1 -1
  114. data/spec/integration/bulk_write_spec.rb +1 -1
  115. data/spec/integration/change_stream_spec.rb +3 -3
  116. data/spec/integration/client_construction_spec.rb +54 -0
  117. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +1 -1
  118. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +1 -1
  119. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +1 -1
  120. data/spec/integration/client_side_encryption/data_key_spec.rb +1 -1
  121. data/spec/integration/client_spec.rb +2 -0
  122. data/spec/integration/command_monitoring_spec.rb +1 -1
  123. data/spec/integration/command_spec.rb +1 -1
  124. data/spec/integration/connection_spec.rb +52 -35
  125. data/spec/integration/crud_spec.rb +174 -1
  126. data/spec/integration/cursor_pinning_spec.rb +121 -0
  127. data/spec/integration/cursor_reaping_spec.rb +8 -4
  128. data/spec/integration/fork_reconnect_spec.rb +1 -5
  129. data/spec/integration/get_more_spec.rb +1 -1
  130. data/spec/integration/heartbeat_events_spec.rb +1 -1
  131. data/spec/integration/map_reduce_spec.rb +77 -0
  132. data/spec/integration/query_cache_spec.rb +2 -2
  133. data/spec/integration/query_cache_transactions_spec.rb +1 -1
  134. data/spec/integration/read_concern_spec.rb +1 -1
  135. data/spec/integration/read_preference_spec.rb +1 -1
  136. data/spec/integration/reconnect_spec.rb +30 -12
  137. data/spec/integration/retryable_errors_spec.rb +1 -1
  138. data/spec/integration/retryable_writes/retryable_writes_36_and_older_spec.rb +1 -1
  139. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -1
  140. data/spec/integration/sdam_error_handling_spec.rb +5 -3
  141. data/spec/integration/sdam_events_spec.rb +35 -19
  142. data/spec/integration/sdam_prose_spec.rb +1 -1
  143. data/spec/integration/server_monitor_spec.rb +1 -0
  144. data/spec/integration/server_selector_spec.rb +22 -5
  145. data/spec/integration/server_spec.rb +2 -0
  146. data/spec/integration/srv_monitoring_spec.rb +1 -1
  147. data/spec/integration/step_down_spec.rb +1 -1
  148. data/spec/integration/transaction_pinning_spec.rb +120 -0
  149. data/spec/integration/versioned_api_examples_spec.rb +45 -0
  150. data/spec/integration/x509_auth_spec.rb +1 -1
  151. data/spec/lite_spec_helper.rb +1 -2
  152. data/spec/mongo/address/unix_spec.rb +1 -0
  153. data/spec/mongo/auth/cr_spec.rb +2 -3
  154. data/spec/mongo/auth/ldap_spec.rb +2 -3
  155. data/spec/mongo/auth/scram_spec.rb +2 -3
  156. data/spec/mongo/auth/user/view_spec.rb +1 -1
  157. data/spec/mongo/auth/x509_spec.rb +2 -3
  158. data/spec/mongo/bulk_write_spec.rb +3 -3
  159. data/spec/mongo/client_construction_spec.rb +259 -28
  160. data/spec/mongo/client_spec.rb +6 -4
  161. data/spec/mongo/cluster/cursor_reaper_spec.rb +36 -21
  162. data/spec/mongo/cluster/periodic_executor_spec.rb +3 -1
  163. data/spec/mongo/cluster_spec.rb +44 -3
  164. data/spec/mongo/collection/view/aggregation_spec.rb +1 -1
  165. data/spec/mongo/collection/view/builder/find_command_spec.rb +4 -0
  166. data/spec/mongo/collection/view/builder/op_query_spec.rb +4 -0
  167. data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
  168. data/spec/mongo/collection_crud_spec.rb +7 -2
  169. data/spec/mongo/collection_ddl_spec.rb +1 -1
  170. data/spec/mongo/collection_spec.rb +1 -1
  171. data/spec/mongo/cursor/builder/get_more_command_spec.rb +4 -0
  172. data/spec/mongo/cursor/builder/op_get_more_spec.rb +4 -0
  173. data/spec/mongo/cursor_spec.rb +15 -5
  174. data/spec/mongo/database_spec.rb +15 -15
  175. data/spec/mongo/error/operation_failure_heavy_spec.rb +1 -1
  176. data/spec/mongo/grid/fs_bucket_spec.rb +18 -12
  177. data/spec/mongo/grid/stream/write_spec.rb +3 -9
  178. data/spec/mongo/grid/stream_spec.rb +1 -1
  179. data/spec/mongo/index/view_spec.rb +2 -2
  180. data/spec/mongo/operation/delete/op_msg_spec.rb +1 -1
  181. data/spec/mongo/{collection/view → operation/find}/builder/flags_spec.rb +2 -2
  182. data/spec/mongo/{collection/view → operation/find}/builder/modifiers_spec.rb +2 -2
  183. data/spec/mongo/operation/find/legacy_spec.rb +1 -0
  184. data/spec/mongo/operation/insert/bulk_spec.rb +1 -1
  185. data/spec/mongo/operation/insert/op_msg_spec.rb +1 -1
  186. data/spec/mongo/operation/kill_cursors_spec.rb +4 -1
  187. data/spec/mongo/operation/read_preference_legacy_spec.rb +4 -0
  188. data/spec/mongo/operation/read_preference_op_msg_spec.rb +2 -0
  189. data/spec/mongo/operation/update/bulk_spec.rb +1 -1
  190. data/spec/mongo/operation/update/op_msg_spec.rb +1 -1
  191. data/spec/mongo/query_cache_spec.rb +6 -2
  192. data/spec/mongo/server/connection_common_spec.rb +62 -11
  193. data/spec/mongo/server/connection_pool_spec.rb +73 -7
  194. data/spec/mongo/server/connection_spec.rb +138 -43
  195. data/spec/mongo/server/description_spec.rb +1 -1
  196. data/spec/mongo/server/monitor_spec.rb +4 -3
  197. data/spec/mongo/session/session_pool_spec.rb +42 -10
  198. data/spec/mongo/session_transaction_spec.rb +15 -30
  199. data/spec/mongo/socket/unix_spec.rb +1 -0
  200. data/spec/mongo/uri_option_parsing_spec.rb +38 -5
  201. data/spec/runners/change_streams/test.rb +1 -1
  202. data/spec/runners/cmap.rb +1 -1
  203. data/spec/runners/connection_string.rb +7 -3
  204. data/spec/runners/crud/operation.rb +5 -3
  205. data/spec/runners/crud/requirement.rb +1 -0
  206. data/spec/runners/crud.rb +1 -1
  207. data/spec/runners/sdam.rb +2 -1
  208. data/spec/runners/transactions/test.rb +2 -2
  209. data/spec/runners/unified/assertions.rb +2 -3
  210. data/spec/runners/unified/event_subscriber.rb +2 -2
  211. data/spec/runners/unified/test.rb +3 -0
  212. data/spec/runners/unified.rb +1 -1
  213. data/spec/shared/lib/mrss/constraints.rb +11 -5
  214. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  215. data/spec/shared/lib/mrss/server_version_registry.rb +17 -12
  216. data/spec/shared/share/Dockerfile.erb +2 -1
  217. data/spec/shared/shlib/server.sh +70 -20
  218. data/spec/spec_tests/change_streams_spec.rb +1 -1
  219. data/spec/spec_tests/cmap_spec.rb +4 -1
  220. data/spec/spec_tests/command_monitoring_spec.rb +2 -2
  221. data/spec/spec_tests/data/command_monitoring/find.yml +9 -9
  222. data/spec/spec_tests/data/crud/read/aggregate-collation.yml +2 -1
  223. data/spec/spec_tests/data/crud/read/aggregate-out.yml +1 -0
  224. data/spec/spec_tests/data/crud/read/count-collation.yml +2 -1
  225. data/spec/spec_tests/data/crud/read/distinct-collation.yml +2 -1
  226. data/spec/spec_tests/data/crud/read/find-collation.yml +2 -1
  227. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +2 -1
  228. data/spec/spec_tests/data/crud/write/deleteMany-collation.yml +2 -1
  229. data/spec/spec_tests/data/crud/write/deleteOne-collation.yml +2 -1
  230. data/spec/spec_tests/data/crud/write/findOneAndDelete-collation.yml +3 -2
  231. data/spec/spec_tests/data/crud/write/findOneAndReplace-collation.yml +2 -1
  232. data/spec/spec_tests/data/crud/write/findOneAndUpdate-collation.yml +3 -2
  233. data/spec/spec_tests/data/crud/write/replaceOne-collation.yml +3 -2
  234. data/spec/spec_tests/data/crud/write/updateMany-collation.yml +2 -1
  235. data/spec/spec_tests/data/crud/write/updateOne-collation.yml +2 -1
  236. data/spec/spec_tests/data/load_balancers/event-monitoring.yml +99 -0
  237. data/spec/spec_tests/data/load_balancers/lb-connection-establishment.yml +36 -0
  238. data/spec/spec_tests/data/load_balancers/non-lb-connection-establishment.yml +56 -0
  239. data/spec/spec_tests/data/load_balancers/server-selection.yml +50 -0
  240. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +1 -1
  241. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +1 -1
  242. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +1 -1
  243. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +1 -1
  244. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +1 -1
  245. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +1 -1
  246. data/spec/spec_tests/data/retryable_reads/mapReduce.yml +3 -1
  247. data/spec/spec_tests/data/sdam/load-balanced/discover_load_balancer.yml +25 -0
  248. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +2 -0
  249. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +2 -0
  250. data/spec/spec_tests/data/sdam_integration/hello-command-error.yml +3 -1
  251. data/spec/spec_tests/data/sdam_integration/hello-network-error.yml +3 -1
  252. data/spec/spec_tests/data/sdam_integration/hello-timeout.yml +2 -0
  253. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +2 -0
  254. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +2 -0
  255. data/spec/spec_tests/data/sdam_monitoring/load_balancer.yml +65 -0
  256. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-directConnection.yml +13 -0
  257. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-replicaSet-errors.yml +6 -0
  258. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-multiple-hosts.yml +5 -0
  259. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-txt.yml +10 -0
  260. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-false.yml +0 -0
  261. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-true.yml +0 -0
  262. data/spec/spec_tests/data/seed_list_discovery/replica-set/encoded-userinfo-and-db.yml +15 -0
  263. data/spec/spec_tests/data/seed_list_discovery/replica-set/loadBalanced-false-txt.yml +10 -0
  264. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/longer-parent-in-return.yml +0 -0
  265. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/misformatted-option.yml +0 -0
  266. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/no-results.yml +0 -0
  267. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/not-enough-parts.yml +0 -0
  268. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-result-default-port.yml +0 -0
  269. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record-multiple-strings.yml +0 -0
  270. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record.yml +0 -0
  271. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch1.yml +0 -0
  272. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch2.yml +0 -0
  273. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch3.yml +0 -0
  274. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch4.yml +0 -0
  275. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch5.yml +0 -0
  276. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-too-short.yml +0 -0
  277. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-wrong.yml +0 -0
  278. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-default-port.yml +0 -0
  279. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-nonstandard-port.yml +0 -0
  280. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-txt-records.yml +0 -0
  281. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-not-allowed-option.yml +0 -0
  282. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-ssl-option.yml +0 -0
  283. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-uri-option.yml +0 -0
  284. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-unallowed-option.yml +0 -0
  285. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-admin-database.yml +13 -0
  286. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-auth.yml +12 -0
  287. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-port.yml +0 -0
  288. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-two-hosts.yml +0 -0
  289. data/spec/spec_tests/data/transactions/retryable-abort-errorLabels.yml +2 -0
  290. data/spec/spec_tests/data/transactions/retryable-abort.yml +2 -0
  291. data/spec/spec_tests/data/transactions/retryable-commit-errorLabels.yml +2 -0
  292. data/spec/spec_tests/data/transactions/retryable-commit.yml +2 -0
  293. data/spec/spec_tests/data/transactions/retryable-writes.yml +2 -0
  294. data/spec/spec_tests/data/uri_options/connection-options.yml +60 -0
  295. data/spec/spec_tests/load_balancers_spec.rb +15 -0
  296. data/spec/spec_tests/retryable_reads_spec.rb +2 -2
  297. data/spec/spec_tests/retryable_writes_spec.rb +1 -1
  298. data/spec/spec_tests/sdam_integration_spec.rb +1 -1
  299. data/spec/spec_tests/sdam_monitoring_spec.rb +10 -5
  300. data/spec/spec_tests/sdam_spec.rb +1 -1
  301. data/spec/spec_tests/seed_list_discovery_spec.rb +118 -0
  302. data/spec/spec_tests/uri_options_spec.rb +4 -4
  303. data/spec/stress/fork_reconnect_stress_spec.rb +1 -5
  304. data/spec/support/certificates/atlas-ocsp-ca.crt +82 -90
  305. data/spec/support/certificates/atlas-ocsp.crt +127 -122
  306. data/spec/support/common_shortcuts.rb +2 -3
  307. data/spec/support/matchers.rb +13 -0
  308. data/spec/support/shared/auth_context.rb +16 -0
  309. data/spec/support/shared/session.rb +2 -2
  310. data/spec/support/spec_config.rb +9 -10
  311. data/spec/support/using_hash.rb +31 -0
  312. data/spec/support/utils.rb +1 -1
  313. data.tar.gz.sig +0 -0
  314. metadata +120 -76
  315. metadata.gz.sig +0 -0
  316. data/lib/mongo/collection/view/builder/find_command.rb +0 -173
  317. data/lib/mongo/collection/view/builder/op_query.rb +0 -94
  318. data/lib/mongo/cursor/builder/get_more_command.rb +0 -80
  319. data/lib/mongo/cursor/builder/kill_cursors_command.rb +0 -111
  320. data/lib/mongo/cursor/builder/op_get_more.rb +0 -64
  321. data/lib/mongo/cursor/builder/op_kill_cursors.rb +0 -106
  322. data/lib/mongo/server/context.rb +0 -72
  323. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -66
  324. data/spec/runners/unified/using_hash.rb +0 -34
  325. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +0 -79
  326. data/spec/support/event_subscriber.rb +0 -221
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abc1ceb1549c601a0b9d34ae3df301219e1de84ebdda6747734b9228395fa860
4
- data.tar.gz: b5dc267b2fc65cfaef33a3e0966edd9b90fb35c414e996d2bd778d0c43ff9cc3
3
+ metadata.gz: 3112358aa696aa5d05305642f004ad5b32bbab28162dea03b96572ed546fc932
4
+ data.tar.gz: fa983d69caf1b98e44b035fd43d264df4e2c76fa1cb0761d8798e83af2173f92
5
5
  SHA512:
6
- metadata.gz: 7688c5325d3a4746ba6c2975dbdaf4aaf15929d49d467ff27cc3ec9a437ea1e34913436307c0ee845f3f8c53d9fdfdbfd6037fa71aa6479a33e165a3111651d8
7
- data.tar.gz: 910a844b6907a24914990a4697e74ceff60bddfc160464f43f83f0a7fd94eb10eb8a098afc696f35eee68603c26213432dba5ae573e3cc71f8a0fd464ae89d2a
6
+ metadata.gz: c38dca4384567fa492f8ecea2b357c4e72178bb70fcf1a1da9b3b932c56848f209e3c637ad5c40cb95bcb8b9e0a8017e389ea95e610cf45078108fff5bcbf49a
7
+ data.tar.gz: 8b2fe87f2f589c2af5ebb67a195d981cc4cf0c08c19f7090cbffe35fe270d56cd0ea6d6fa9dd304c444a8480b0793bba639787e7545bc84e18dd42fd9b7f22e3
checksums.yaml.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -5,7 +5,7 @@ MongoDB Ruby Driver
5
5
 
6
6
  The officially supported Ruby driver for [MongoDB](https://www.mongodb.org/).
7
7
 
8
- The Ruby driver supports Ruby 2.3-3.0 and JRuby 9.2.
8
+ The Ruby driver supports Ruby 2.4-3.0 and JRuby 9.2.
9
9
 
10
10
 
11
11
  Documentation
@@ -66,7 +66,7 @@ module Mongo
66
66
  if single_statement?(operation)
67
67
  write_concern = write_concern(session)
68
68
  write_with_retry(session, write_concern) do |server, txn_num|
69
- server.with_connection do |connection|
69
+ server.with_connection(service_id: context.service_id) do |connection|
70
70
  execute_operation(
71
71
  operation.keys.first,
72
72
  operation.values.flatten,
@@ -80,7 +80,7 @@ module Mongo
80
80
  end
81
81
  else
82
82
  nro_write_with_retry(session, write_concern) do |server|
83
- server.with_connection do |connection|
83
+ server.with_connection(service_id: context.service_id) do |connection|
84
84
  execute_operation(
85
85
  operation.keys.first,
86
86
  operation.values.flatten,
data/lib/mongo/client.rb CHANGED
@@ -67,6 +67,7 @@ module Mongo
67
67
  :database,
68
68
  :heartbeat_frequency,
69
69
  :id_generator,
70
+ :load_balanced,
70
71
  :local_threshold,
71
72
  :logger,
72
73
  :log_prefix,
@@ -243,7 +244,10 @@ module Mongo
243
244
  # @option options [ Symbol ] :connect Deprecated - use :direct_connection
244
245
  # option instead of this option. The connection method to use. This
245
246
  # forces the cluster to behave in the specified way instead of
246
- # auto-discovering. One of :direct, :replica_set, :sharded
247
+ # auto-discovering. One of :direct, :replica_set, :sharded,
248
+ # :load_balanced. If :connect is set to :load_balanced, the driver
249
+ # will behave as if the server is a load balancer even if it isn't
250
+ # connected to a load balancer.
247
251
  # @option options [ Float ] :connect_timeout The timeout, in seconds, to
248
252
  # attempt a connection.
249
253
  # @option options [ String ] :database The database to connect to.
@@ -251,6 +255,8 @@ module Mongo
251
255
  # for the server monitor to refresh its description via hello.
252
256
  # @option options [ Object ] :id_generator A custom object to generate ids
253
257
  # for documents. Must respond to #generate.
258
+ # @option options [ true | false ] :load_balanced Whether to expect to
259
+ # connect to a load balancer.
254
260
  # @option options [ Integer ] :local_threshold The local threshold boundary
255
261
  # in seconds for selecting a near server for an operation.
256
262
  # @option options [ Logger ] :logger A custom logger to use.
@@ -1234,9 +1240,15 @@ module Mongo
1234
1240
  raise ArgumentError, "If :write and :write_concern are both given, they must be identical: #{options.inspect}"
1235
1241
  end
1236
1242
 
1243
+ connect = options[:connect]&.to_sym
1244
+
1245
+ if connect && !%i(direct replica_set sharded load_balanced).include?(connect)
1246
+ raise ArgumentError, "Invalid :connect option value: #{connect}"
1247
+ end
1248
+
1237
1249
  if options[:direct_connection]
1238
- if options[:connect] && options[:connect].to_sym != :direct
1239
- raise ArgumentError, "Conflicting client options: direct_connection=true and connect=#{options[:connect]}"
1250
+ if connect && connect != :direct
1251
+ raise ArgumentError, "Conflicting client options: direct_connection=true and connect=#{connect}"
1240
1252
  end
1241
1253
  # When a new client is created, we get the list of seed addresses
1242
1254
  if addresses && addresses.length > 1
@@ -1248,8 +1260,36 @@ module Mongo
1248
1260
  end
1249
1261
  end
1250
1262
 
1251
- if options[:direct_connection] == false && options[:connect] && options[:connect].to_sym == :direct
1252
- raise ArgumentError, "Conflicting client options: direct_connection=false and connect=#{options[:connect]}"
1263
+ if options[:load_balanced]
1264
+ if addresses && addresses.length > 1
1265
+ raise ArgumentError, "load_balanced=true cannot be used with multiple seeds"
1266
+ end
1267
+
1268
+ if options[:direct_connection]
1269
+ raise ArgumentError, "direct_connection=true cannot be used with load_balanced=true"
1270
+ end
1271
+
1272
+ if connect && connect != :load_balanced
1273
+ raise ArgumentError, "connect=#{connect} cannot be used with load_balanced=true"
1274
+ end
1275
+
1276
+ if options[:replica_set]
1277
+ raise ArgumentError, "load_balanced=true cannot be used with replica_set option"
1278
+ end
1279
+ end
1280
+
1281
+ if connect == :load_balanced
1282
+ if addresses && addresses.length > 1
1283
+ raise ArgumentError, "connect=load_balanced cannot be used with multiple seeds"
1284
+ end
1285
+
1286
+ if options[:replica_set]
1287
+ raise ArgumentError, "connect=load_balanced cannot be used with replica_set option"
1288
+ end
1289
+ end
1290
+
1291
+ if options[:direct_connection] == false && connect && connect == :direct
1292
+ raise ArgumentError, "Conflicting client options: direct_connection=false and connect=#{connect}"
1253
1293
  end
1254
1294
 
1255
1295
  %i(connect_timeout socket_timeout).each do |key|
@@ -36,14 +36,15 @@ module Mongo
36
36
  #
37
37
  # @example Create a PeriodicExecutor.
38
38
  # Mongo::Cluster::PeriodicExecutor.new([reaper, reaper2])
39
+ #
40
+ # @param [ Array<Object> ] executors The executors. Each must respond
41
+ # to #execute and #flush.
39
42
  # @param [ Hash ] options The options.
40
43
  #
41
44
  # @option options [ Logger ] :logger A custom logger to use.
42
45
  #
43
46
  # @api private
44
- #
45
- # @since 2.5.0
46
- def initialize(executors = [], options = {})
47
+ def initialize(executors, options = {})
47
48
  @thread = nil
48
49
  @executors = executors
49
50
  @stop_semaphore = Semaphore.new
@@ -28,42 +28,38 @@ module Mongo
28
28
  class CursorReaper
29
29
  include Retryable
30
30
 
31
- # The default time interval for the cursor reaper to send pending kill cursors operations.
31
+ # The default time interval for the cursor reaper to send pending
32
+ # kill cursors operations.
32
33
  #
33
34
  # @since 2.3.0
34
35
  FREQUENCY = 1.freeze
35
36
 
36
37
  # Create a cursor reaper.
37
38
  #
38
- # @example Create a CursorReaper.
39
- # Mongo::Cluster::CursorReaper.new(cluster)
39
+ # @param [ Cluster ] cluster The cluster.
40
40
  #
41
41
  # @api private
42
- #
43
- # @since 2.3.0
44
- def initialize
42
+ def initialize(cluster)
43
+ @cluster = cluster
45
44
  @to_kill = {}
46
- @active_cursors = Set.new
45
+ @active_cursor_ids = Set.new
47
46
  @mutex = Mutex.new
48
47
  end
49
48
 
49
+ attr_reader :cluster
50
+
50
51
  # Schedule a kill cursors operation to be eventually executed.
51
52
  #
52
- # @example Schedule a kill cursors operation.
53
- # cursor_reaper.schedule_kill_cursor(id, op_spec, server)
54
- #
55
- # @param [ Integer ] id The id of the cursor to kill.
56
- # @param [ Hash ] op_spec The spec for the kill cursors op.
57
- # @param [ Mongo::Server ] server The server to send the kill cursors operation to.
53
+ # @param [ Cursor::KillSpec ] kill_spec The kill specification.
54
+ # @param [ Mongo::Server ] server The server to send the kill cursors
55
+ # operation to.
58
56
  #
59
57
  # @api private
60
- #
61
- # @since 2.3.0
62
- def schedule_kill_cursor(id, op_spec, server)
58
+ def schedule_kill_cursor(kill_spec, server)
63
59
  @mutex.synchronize do
64
- if @active_cursors.include?(id)
65
- @to_kill[server] ||= Set.new
66
- @to_kill[server] << op_spec
60
+ if @active_cursor_ids.include?(kill_spec.cursor_id)
61
+ @to_kill[server.address.seed] ||= Set.new
62
+ @to_kill[server.address.seed] << kill_spec
67
63
  end
68
64
  end
69
65
  end
@@ -87,7 +83,7 @@ module Mongo
87
83
  end
88
84
 
89
85
  @mutex.synchronize do
90
- @active_cursors << id
86
+ @active_cursor_ids << id
91
87
  end
92
88
  end
93
89
 
@@ -110,7 +106,7 @@ module Mongo
110
106
  end
111
107
 
112
108
  @mutex.synchronize do
113
- @active_cursors.delete(id)
109
+ @active_cursor_ids.delete(id)
114
110
  end
115
111
  end
116
112
 
@@ -123,33 +119,70 @@ module Mongo
123
119
  #
124
120
  # @since 2.3.0
125
121
  def kill_cursors
126
- to_kill_copy = {}
127
- active_cursors_copy = []
122
+ # TODO optimize this to batch kill cursor operations for the same
123
+ # server/database/collection instead of killing each cursor
124
+ # individually.
128
125
 
129
- @mutex.synchronize do
130
- to_kill_copy = @to_kill.dup
131
- active_cursors_copy = @active_cursors.dup
132
- @to_kill = {}
133
- end
126
+ loop do
127
+ server_address_str = nil
128
+
129
+ kill_spec = @mutex.synchronize do
130
+ # Find a server that has any cursors scheduled for destruction.
131
+ server_address_str, specs =
132
+ @to_kill.detect { |server_address_str, specs| specs.any? }
133
+
134
+ if specs.nil?
135
+ # All servers have empty specs, nothing to do.
136
+ return
137
+ end
138
+
139
+ # Note that this mutates the spec in the queue.
140
+ # If the kill cursor operation fails, we don't attempt to
141
+ # kill that cursor again.
142
+ spec = specs.take(1).tap do |arr|
143
+ specs.subtract(arr)
144
+ end.first
145
+
146
+ unless @active_cursor_ids.include?(spec.cursor_id)
147
+ # The cursor was already killed, typically because it has
148
+ # been iterated to completion. Remove the kill spec from
149
+ # our records without doing any more work.
150
+ spec = nil
151
+ end
152
+
153
+ spec
154
+ end
155
+
156
+ # If there was a spec to kill but its cursor was already killed,
157
+ # look for another spec.
158
+ next unless kill_spec
159
+
160
+ # We could also pass kill_spec directly into the KillCursors
161
+ # operation, though this would make that operation have a
162
+ # different API from all of the other ones which accept hashes.
163
+ spec = {
164
+ cursor_ids: [kill_spec.cursor_id],
165
+ coll_name: kill_spec.coll_name,
166
+ db_name: kill_spec.db_name,
167
+ }
168
+ op = Operation::KillCursors.new(spec)
169
+
170
+ server = cluster.servers.detect do |server|
171
+ server.address.seed == server_address_str
172
+ end
173
+
174
+ unless server
175
+ # TODO We currently don't have a server for the address that the
176
+ # cursor is associated with. We should leave the cursor in the
177
+ # queue to be killed at a later time (when the server comes back).
178
+ next
179
+ end
134
180
 
135
- to_kill_copy.each do |server, op_specs|
136
181
  options = {
137
182
  server_api: server.options[:server_api],
183
+ service_id: kill_spec.service_id,
138
184
  }
139
- context = Operation::Context.new(options: options)
140
- op_specs.each do |op_spec|
141
- if server.features.find_command_enabled?
142
- Cursor::Builder::KillCursorsCommand.update_cursors(op_spec, active_cursors_copy.to_a)
143
- if Cursor::Builder::KillCursorsCommand.get_cursors_list(op_spec).size > 0
144
- Operation::KillCursors.new(op_spec).execute(server, context: context)
145
- end
146
- else
147
- Cursor::Builder::OpKillCursors.update_cursors(op_spec, active_cursors_copy.to_a)
148
- if Cursor::Builder::OpKillCursors.get_cursors_list(op_spec).size > 0
149
- Operation::KillCursors.new(op_spec).execute(server, context: context)
150
- end
151
- end
152
- end
185
+ op.execute(server, context: Operation::Context.new(options: options))
153
186
  end
154
187
  end
155
188
  alias :execute :kill_cursors
@@ -105,6 +105,11 @@ class Mongo::Cluster
105
105
  end
106
106
 
107
107
  case topology
108
+ when Topology::LoadBalanced
109
+ @updated_desc = ::Mongo::Server::Description::LoadBalancer.new(
110
+ updated_desc.address,
111
+ )
112
+ update_server_descriptions
108
113
  when Topology::Single
109
114
  if topology.replica_set_name
110
115
  if updated_desc.replica_set_name != topology.replica_set_name
@@ -112,7 +117,7 @@ class Mongo::Cluster
112
117
  "Server #{updated_desc.address.to_s} has an incorrect replica set name '#{updated_desc.replica_set_name}'; expected '#{topology.replica_set_name}'"
113
118
  )
114
119
  @updated_desc = ::Mongo::Server::Description.new(updated_desc.address,
115
- {}, updated_desc.average_round_trip_time)
120
+ {}, average_round_trip_time: updated_desc.average_round_trip_time)
116
121
  update_server_descriptions
117
122
  end
118
123
  end
@@ -229,7 +234,7 @@ class Mongo::Cluster
229
234
 
230
235
  if stale_primary?
231
236
  @updated_desc = ::Mongo::Server::Description.new(updated_desc.address,
232
- {}, updated_desc.average_round_trip_time)
237
+ {}, average_round_trip_time: updated_desc.average_round_trip_time)
233
238
  update_server_descriptions
234
239
  check_if_has_primary
235
240
  return
@@ -258,7 +263,8 @@ class Mongo::Cluster
258
263
  if server.address != updated_desc.address
259
264
  if server.primary?
260
265
  server.update_description(::Mongo::Server::Description.new(
261
- server.address, {}, server.description.average_round_trip_time))
266
+ server.address, {},
267
+ average_round_trip_time: server.description.average_round_trip_time))
262
268
  end
263
269
  end
264
270
  end
@@ -67,17 +67,21 @@ module Mongo
67
67
  @server_descriptions[server.address.to_s] = server.description
68
68
  end
69
69
 
70
- begin
71
- server_descriptions.each do |address_str, desc|
72
- unless desc.unknown?
73
- desc.features.check_driver_support!
70
+ if is_a?(LoadBalanced)
71
+ @compatible = true
72
+ else
73
+ begin
74
+ server_descriptions.each do |address_str, desc|
75
+ unless desc.unknown?
76
+ desc.features.check_driver_support!
77
+ end
74
78
  end
79
+ rescue Error::UnsupportedFeatures => e
80
+ @compatible = false
81
+ @compatibility_error = e
82
+ else
83
+ @compatible = true
75
84
  end
76
- rescue Error::UnsupportedFeatures => e
77
- @compatible = false
78
- @compatibility_error = e
79
- else
80
- @compatible = true
81
85
  end
82
86
 
83
87
  @have_data_bearing_servers = false
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ # Copyright (C) 2021 MongoDB Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ module Mongo
19
+ class Cluster
20
+ module Topology
21
+
22
+ # Defines behavior for when a cluster is in load-balanced topology.
23
+ class LoadBalanced < Base
24
+
25
+ # The display name for the topology.
26
+ NAME = 'LoadBalanced'.freeze
27
+
28
+ # Get the display name.
29
+ #
30
+ # @return [ String ] The display name.
31
+ def display_name
32
+ self.class.name.gsub(/.*::/, '')
33
+ end
34
+
35
+ # @note This method is experimental and subject to change.
36
+ #
37
+ # @api experimental
38
+ def summary
39
+ details = server_descriptions.keys.join(',')
40
+ "#{display_name}[#{details}]"
41
+ end
42
+
43
+ # Determine if the topology would select a readable server for the
44
+ # provided candidates and read preference.
45
+ #
46
+ # @param [ Cluster ] cluster The cluster.
47
+ # @param [ ServerSelector ] server_selector The server
48
+ # selector.
49
+ #
50
+ # @return [ true ] A standalone always has a readable server.
51
+ def has_readable_server?(cluster, server_selector = nil); true; end
52
+
53
+ # Determine if the topology would select a writable server for the
54
+ # provided candidates.
55
+ #
56
+ # @param [ Cluster ] cluster The cluster.
57
+ #
58
+ # @return [ true ] A standalone always has a writable server.
59
+ def has_writable_server?(cluster); true; end
60
+
61
+ # Returns whether this topology is one of the replica set ones.
62
+ #
63
+ # @return [ false ] Always false.
64
+ def replica_set?; false; end
65
+
66
+ # Select appropriate servers for this topology.
67
+ #
68
+ # @param [ Array<Server> ] servers The known servers.
69
+ #
70
+ # @return [ Array<Server> ] All of the known servers.
71
+ def servers(servers, name = nil)
72
+ servers
73
+ end
74
+
75
+ # Returns whether this topology is sharded.
76
+ #
77
+ # @return [ false ] Always false.
78
+ def sharded?; false; end
79
+
80
+ # Returns whether this topology is Single.
81
+ #
82
+ # @return [ true ] Always false.
83
+ def single?; false; end
84
+
85
+ # Returns whether this topology is Unknown.
86
+ #
87
+ # @return [ false ] Always false.
88
+ def unknown?; false; end
89
+
90
+ private
91
+
92
+ def validate_options(options, cluster)
93
+ if cluster.servers_list.length > 1
94
+ raise ArgumentError, "Cannot instantiate a load-balanced topology with more than one server in the cluster: #{cluster.servers_list.map(&:address).map(&:seed).join(', ')}"
95
+ end
96
+
97
+ super(options, cluster)
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -38,6 +38,7 @@ end
38
38
 
39
39
  require 'mongo/cluster/topology/base'
40
40
  require 'mongo/cluster/topology/no_replica_set_options'
41
+ require 'mongo/cluster/topology/load_balanced'
41
42
  require 'mongo/cluster/topology/replica_set_no_primary'
42
43
  require 'mongo/cluster/topology/replica_set_with_primary'
43
44
  require 'mongo/cluster/topology/sharded'
@@ -50,10 +51,12 @@ module Mongo
50
51
  # The various topologies for server selection.
51
52
  #
52
53
  # @since 2.0.0
54
+ # @api private
53
55
  OPTIONS = {
56
+ direct: Single,
57
+ load_balanced: LoadBalanced,
54
58
  replica_set: ReplicaSetNoPrimary,
55
59
  sharded: Sharded,
56
- direct: Single,
57
60
  }.freeze
58
61
 
59
62
  # Get the initial cluster topology for the provided options.
@@ -71,26 +74,43 @@ module Mongo
71
74
  # @option options [ Symbol ] :connect Deprecated - use :direct_connection
72
75
  # option instead of this option. The connection method to use. This
73
76
  # forces the cluster to behave in the specified way instead of
74
- # auto-discovering. One of :direct, :replica_set, :sharded
77
+ # auto-discovering. One of :direct, :replica_set, :sharded,
78
+ # :load_balanced. If :connect is set to :load_balanced, the driver
79
+ # will behave as if the server is a load balancer even if it isn't
80
+ # connected to a load balancer.
81
+ # @option options [ true | false ] :load_balanced Whether to expect to
82
+ # connect to a load balancer.
75
83
  # @option options [ Symbol ] :replica_set The name of the replica set to
76
84
  # connect to. Servers not in this replica set will be ignored.
77
85
  #
78
- # @return [ ReplicaSet, Sharded, Single ] The topology.
86
+ # @return [ ReplicaSet, Sharded, Single, LoadBalanced ] The topology.
79
87
  #
80
88
  # @since 2.0.0
81
89
  # @api private
82
90
  def initial(cluster, monitoring, options)
91
+ connect = options[:connect]&.to_sym
83
92
  cls = if options[:direct_connection]
84
- if options[:connect] && options[:connect] && options[:connect].to_sym != :direct
85
- raise ArgumentError, "Conflicting topology options: direct_connection=true and connect=#{options[:connect]}"
93
+ if connect && connect != :direct
94
+ raise ArgumentError, "Conflicting topology options: direct_connection=true and connect=#{connect}"
95
+ end
96
+ if options[:load_balanced]
97
+ raise ArgumentError, "Conflicting topology options: direct_connection=true and load_balanced=true"
86
98
  end
87
99
  Single
88
- elsif options[:direct_connection] == false && options[:connect] && options[:connect].to_sym == :direct
89
- raise ArgumentError, "Conflicting topology options: direct_connection=false and connect=#{options[:connect]}"
90
- elsif options.key?(:connect)
100
+ elsif options[:direct_connection] == false && connect && connect == :direct
101
+ raise ArgumentError, "Conflicting topology options: direct_connection=false and connect=#{connect}"
102
+ elsif connect && connect != :load_balanced
103
+ if options[:load_balanced]
104
+ raise ArgumentError, "Conflicting topology options: connect=#{options[:connect].inspect} and load_balanced=true"
105
+ end
91
106
  OPTIONS.fetch(options[:connect].to_sym)
92
107
  elsif options.key?(:replica_set) || options.key?(:replica_set_name)
108
+ if options[:load_balanced]
109
+ raise ArgumentError, "Conflicting topology options: replica_set/replica_set_name and load_balanced=true"
110
+ end
93
111
  ReplicaSetNoPrimary
112
+ elsif options[:load_balanced] || connect == :load_balanced
113
+ LoadBalanced
94
114
  else
95
115
  Unknown
96
116
  end