mongo 2.15.1 → 2.16.0.alpha1

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 (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