mongo 2.15.0 → 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 (328) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -1
  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 +58 -24
  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 +72 -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/push_monitor.rb +6 -0
  102. data/lib/mongo/server.rb +73 -26
  103. data/lib/mongo/server_selector/base.rb +5 -1
  104. data/lib/mongo/session/session_pool.rb +11 -0
  105. data/lib/mongo/session.rb +21 -1
  106. data/lib/mongo/socket/ocsp_verifier.rb +6 -37
  107. data/lib/mongo/uri/options_mapper.rb +1 -0
  108. data/lib/mongo/uri/srv_protocol.rb +6 -8
  109. data/lib/mongo/uri.rb +18 -0
  110. data/lib/mongo/utils.rb +0 -7
  111. data/lib/mongo/version.rb +1 -1
  112. data/mongo.gemspec +1 -1
  113. data/spec/integration/auth_spec.rb +31 -1
  114. data/spec/integration/awaited_ismaster_spec.rb +1 -1
  115. data/spec/integration/bulk_write_spec.rb +1 -1
  116. data/spec/integration/change_stream_spec.rb +3 -3
  117. data/spec/integration/client_construction_spec.rb +54 -0
  118. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +1 -1
  119. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +1 -1
  120. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +1 -1
  121. data/spec/integration/client_side_encryption/data_key_spec.rb +1 -1
  122. data/spec/integration/client_spec.rb +2 -0
  123. data/spec/integration/command_monitoring_spec.rb +1 -1
  124. data/spec/integration/command_spec.rb +1 -1
  125. data/spec/integration/connection_spec.rb +52 -35
  126. data/spec/integration/crud_spec.rb +174 -1
  127. data/spec/integration/cursor_pinning_spec.rb +121 -0
  128. data/spec/integration/cursor_reaping_spec.rb +8 -4
  129. data/spec/integration/fork_reconnect_spec.rb +1 -5
  130. data/spec/integration/get_more_spec.rb +1 -1
  131. data/spec/integration/heartbeat_events_spec.rb +1 -1
  132. data/spec/integration/map_reduce_spec.rb +77 -0
  133. data/spec/integration/query_cache_spec.rb +47 -2
  134. data/spec/integration/query_cache_transactions_spec.rb +1 -1
  135. data/spec/integration/read_concern_spec.rb +1 -1
  136. data/spec/integration/read_preference_spec.rb +1 -1
  137. data/spec/integration/reconnect_spec.rb +30 -12
  138. data/spec/integration/retryable_errors_spec.rb +1 -1
  139. data/spec/integration/retryable_writes/retryable_writes_36_and_older_spec.rb +1 -1
  140. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -1
  141. data/spec/integration/sdam_error_handling_spec.rb +5 -3
  142. data/spec/integration/sdam_events_spec.rb +35 -19
  143. data/spec/integration/sdam_prose_spec.rb +1 -1
  144. data/spec/integration/server_monitor_spec.rb +1 -0
  145. data/spec/integration/server_selector_spec.rb +22 -5
  146. data/spec/integration/server_spec.rb +2 -0
  147. data/spec/integration/srv_monitoring_spec.rb +1 -1
  148. data/spec/integration/step_down_spec.rb +1 -1
  149. data/spec/integration/transaction_pinning_spec.rb +120 -0
  150. data/spec/integration/versioned_api_examples_spec.rb +45 -0
  151. data/spec/integration/x509_auth_spec.rb +1 -1
  152. data/spec/lite_spec_helper.rb +1 -2
  153. data/spec/mongo/address/unix_spec.rb +1 -0
  154. data/spec/mongo/auth/cr_spec.rb +2 -3
  155. data/spec/mongo/auth/ldap_spec.rb +2 -3
  156. data/spec/mongo/auth/scram_spec.rb +2 -3
  157. data/spec/mongo/auth/user/view_spec.rb +1 -1
  158. data/spec/mongo/auth/x509_spec.rb +2 -3
  159. data/spec/mongo/bulk_write_spec.rb +3 -3
  160. data/spec/mongo/client_construction_spec.rb +259 -28
  161. data/spec/mongo/client_spec.rb +6 -4
  162. data/spec/mongo/cluster/cursor_reaper_spec.rb +36 -21
  163. data/spec/mongo/cluster/periodic_executor_spec.rb +3 -1
  164. data/spec/mongo/cluster_spec.rb +44 -3
  165. data/spec/mongo/collection/view/aggregation_spec.rb +1 -1
  166. data/spec/mongo/collection/view/builder/find_command_spec.rb +4 -0
  167. data/spec/mongo/collection/view/builder/op_query_spec.rb +4 -0
  168. data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
  169. data/spec/mongo/collection_crud_spec.rb +7 -2
  170. data/spec/mongo/collection_ddl_spec.rb +1 -1
  171. data/spec/mongo/collection_spec.rb +1 -1
  172. data/spec/mongo/cursor/builder/get_more_command_spec.rb +4 -0
  173. data/spec/mongo/cursor/builder/op_get_more_spec.rb +4 -0
  174. data/spec/mongo/cursor_spec.rb +15 -5
  175. data/spec/mongo/database_spec.rb +15 -15
  176. data/spec/mongo/error/operation_failure_heavy_spec.rb +1 -1
  177. data/spec/mongo/grid/fs_bucket_spec.rb +18 -12
  178. data/spec/mongo/grid/stream/write_spec.rb +3 -9
  179. data/spec/mongo/grid/stream_spec.rb +1 -1
  180. data/spec/mongo/index/view_spec.rb +2 -2
  181. data/spec/mongo/operation/delete/op_msg_spec.rb +1 -1
  182. data/spec/mongo/{collection/view → operation/find}/builder/flags_spec.rb +2 -2
  183. data/spec/mongo/{collection/view → operation/find}/builder/modifiers_spec.rb +2 -2
  184. data/spec/mongo/operation/find/legacy_spec.rb +1 -0
  185. data/spec/mongo/operation/insert/bulk_spec.rb +1 -1
  186. data/spec/mongo/operation/insert/op_msg_spec.rb +1 -1
  187. data/spec/mongo/operation/kill_cursors_spec.rb +4 -1
  188. data/spec/mongo/operation/read_preference_legacy_spec.rb +4 -0
  189. data/spec/mongo/operation/read_preference_op_msg_spec.rb +2 -0
  190. data/spec/mongo/operation/update/bulk_spec.rb +1 -1
  191. data/spec/mongo/operation/update/op_msg_spec.rb +1 -1
  192. data/spec/mongo/query_cache_spec.rb +6 -2
  193. data/spec/mongo/server/connection_common_spec.rb +62 -11
  194. data/spec/mongo/server/connection_pool_spec.rb +73 -7
  195. data/spec/mongo/server/connection_spec.rb +138 -43
  196. data/spec/mongo/server/description_spec.rb +1 -1
  197. data/spec/mongo/server/monitor_spec.rb +4 -3
  198. data/spec/mongo/session/session_pool_spec.rb +42 -10
  199. data/spec/mongo/session_transaction_spec.rb +15 -30
  200. data/spec/mongo/socket/unix_spec.rb +1 -0
  201. data/spec/mongo/uri_option_parsing_spec.rb +38 -5
  202. data/spec/runners/change_streams/test.rb +1 -1
  203. data/spec/runners/cmap.rb +1 -1
  204. data/spec/runners/connection_string.rb +7 -3
  205. data/spec/runners/crud/operation.rb +5 -3
  206. data/spec/runners/crud/requirement.rb +1 -0
  207. data/spec/runners/crud.rb +1 -1
  208. data/spec/runners/sdam.rb +2 -1
  209. data/spec/runners/transactions/test.rb +2 -2
  210. data/spec/runners/unified/assertions.rb +2 -3
  211. data/spec/runners/unified/event_subscriber.rb +2 -2
  212. data/spec/runners/unified/test.rb +3 -0
  213. data/spec/runners/unified.rb +1 -1
  214. data/spec/shared/lib/mrss/constraints.rb +11 -5
  215. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  216. data/spec/shared/lib/mrss/server_version_registry.rb +17 -12
  217. data/spec/shared/share/Dockerfile.erb +2 -1
  218. data/spec/shared/shlib/server.sh +70 -20
  219. data/spec/spec_tests/change_streams_spec.rb +1 -1
  220. data/spec/spec_tests/cmap_spec.rb +4 -1
  221. data/spec/spec_tests/command_monitoring_spec.rb +2 -2
  222. data/spec/spec_tests/data/command_monitoring/find.yml +9 -9
  223. data/spec/spec_tests/data/crud/read/aggregate-collation.yml +2 -1
  224. data/spec/spec_tests/data/crud/read/aggregate-out.yml +1 -0
  225. data/spec/spec_tests/data/crud/read/count-collation.yml +2 -1
  226. data/spec/spec_tests/data/crud/read/distinct-collation.yml +2 -1
  227. data/spec/spec_tests/data/crud/read/find-collation.yml +2 -1
  228. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +2 -1
  229. data/spec/spec_tests/data/crud/write/deleteMany-collation.yml +2 -1
  230. data/spec/spec_tests/data/crud/write/deleteOne-collation.yml +2 -1
  231. data/spec/spec_tests/data/crud/write/findOneAndDelete-collation.yml +3 -2
  232. data/spec/spec_tests/data/crud/write/findOneAndReplace-collation.yml +2 -1
  233. data/spec/spec_tests/data/crud/write/findOneAndUpdate-collation.yml +3 -2
  234. data/spec/spec_tests/data/crud/write/replaceOne-collation.yml +3 -2
  235. data/spec/spec_tests/data/crud/write/updateMany-collation.yml +2 -1
  236. data/spec/spec_tests/data/crud/write/updateOne-collation.yml +2 -1
  237. data/spec/spec_tests/data/load_balancers/event-monitoring.yml +99 -0
  238. data/spec/spec_tests/data/load_balancers/lb-connection-establishment.yml +36 -0
  239. data/spec/spec_tests/data/load_balancers/non-lb-connection-establishment.yml +56 -0
  240. data/spec/spec_tests/data/load_balancers/server-selection.yml +50 -0
  241. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +1 -1
  242. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +1 -1
  243. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +1 -1
  244. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +1 -1
  245. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +1 -1
  246. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +1 -1
  247. data/spec/spec_tests/data/retryable_reads/mapReduce.yml +3 -1
  248. data/spec/spec_tests/data/sdam/load-balanced/discover_load_balancer.yml +25 -0
  249. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +2 -0
  250. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +2 -0
  251. data/spec/spec_tests/data/sdam_integration/hello-command-error.yml +3 -1
  252. data/spec/spec_tests/data/sdam_integration/hello-network-error.yml +3 -1
  253. data/spec/spec_tests/data/sdam_integration/hello-timeout.yml +2 -0
  254. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +2 -0
  255. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +2 -0
  256. data/spec/spec_tests/data/sdam_monitoring/load_balancer.yml +65 -0
  257. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-directConnection.yml +13 -0
  258. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-replicaSet-errors.yml +6 -0
  259. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-multiple-hosts.yml +5 -0
  260. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-txt.yml +10 -0
  261. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-false.yml +0 -0
  262. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-true.yml +0 -0
  263. data/spec/spec_tests/data/seed_list_discovery/replica-set/encoded-userinfo-and-db.yml +15 -0
  264. data/spec/spec_tests/data/seed_list_discovery/replica-set/loadBalanced-false-txt.yml +10 -0
  265. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/longer-parent-in-return.yml +0 -0
  266. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/misformatted-option.yml +0 -0
  267. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/no-results.yml +0 -0
  268. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/not-enough-parts.yml +0 -0
  269. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-result-default-port.yml +0 -0
  270. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record-multiple-strings.yml +0 -0
  271. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record.yml +0 -0
  272. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch1.yml +0 -0
  273. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch2.yml +0 -0
  274. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch3.yml +0 -0
  275. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch4.yml +0 -0
  276. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch5.yml +0 -0
  277. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-too-short.yml +0 -0
  278. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-wrong.yml +0 -0
  279. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-default-port.yml +0 -0
  280. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-nonstandard-port.yml +0 -0
  281. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-txt-records.yml +0 -0
  282. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-not-allowed-option.yml +0 -0
  283. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-ssl-option.yml +0 -0
  284. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-uri-option.yml +0 -0
  285. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-unallowed-option.yml +0 -0
  286. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-admin-database.yml +13 -0
  287. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-auth.yml +12 -0
  288. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-port.yml +0 -0
  289. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-two-hosts.yml +0 -0
  290. data/spec/spec_tests/data/transactions/retryable-abort-errorLabels.yml +2 -0
  291. data/spec/spec_tests/data/transactions/retryable-abort.yml +2 -0
  292. data/spec/spec_tests/data/transactions/retryable-commit-errorLabels.yml +2 -0
  293. data/spec/spec_tests/data/transactions/retryable-commit.yml +2 -0
  294. data/spec/spec_tests/data/transactions/retryable-writes.yml +2 -0
  295. data/spec/spec_tests/data/uri_options/connection-options.yml +60 -0
  296. data/spec/spec_tests/load_balancers_spec.rb +15 -0
  297. data/spec/spec_tests/retryable_reads_spec.rb +2 -2
  298. data/spec/spec_tests/retryable_writes_spec.rb +1 -1
  299. data/spec/spec_tests/sdam_integration_spec.rb +1 -1
  300. data/spec/spec_tests/sdam_monitoring_spec.rb +10 -5
  301. data/spec/spec_tests/sdam_spec.rb +1 -1
  302. data/spec/spec_tests/seed_list_discovery_spec.rb +118 -0
  303. data/spec/spec_tests/uri_options_spec.rb +4 -4
  304. data/spec/stress/fork_reconnect_stress_spec.rb +1 -5
  305. data/spec/stress/push_monitor_close_spec.rb +44 -0
  306. data/spec/support/certificates/atlas-ocsp-ca.crt +82 -90
  307. data/spec/support/certificates/atlas-ocsp.crt +127 -122
  308. data/spec/support/common_shortcuts.rb +2 -3
  309. data/spec/support/matchers.rb +13 -0
  310. data/spec/support/shared/auth_context.rb +16 -0
  311. data/spec/support/shared/session.rb +2 -2
  312. data/spec/support/spec_config.rb +9 -10
  313. data/spec/support/using_hash.rb +31 -0
  314. data/spec/support/utils.rb +1 -1
  315. data.tar.gz.sig +2 -4
  316. metadata +1050 -1004
  317. metadata.gz.sig +0 -0
  318. data/lib/mongo/collection/view/builder/find_command.rb +0 -173
  319. data/lib/mongo/collection/view/builder/op_query.rb +0 -94
  320. data/lib/mongo/cursor/builder/get_more_command.rb +0 -80
  321. data/lib/mongo/cursor/builder/kill_cursors_command.rb +0 -111
  322. data/lib/mongo/cursor/builder/op_get_more.rb +0 -64
  323. data/lib/mongo/cursor/builder/op_kill_cursors.rb +0 -106
  324. data/lib/mongo/server/context.rb +0 -72
  325. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -66
  326. data/spec/runners/unified/using_hash.rb +0 -34
  327. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +0 -79
  328. data/spec/support/event_subscriber.rb +0 -221
@@ -38,28 +38,29 @@ module Mongo
38
38
  #
39
39
  # @since 2.0.0
40
40
  MAPPINGS = {
41
- :retryable_write_error_label => 9,
41
+ retryable_write_error_label: 9,
42
+ commit_quorum: 9,
42
43
  # Server versions older than 4.2 do not reliably validate options
43
44
  # provided by the client during findAndModify operations, requiring the
44
45
  # driver to raise client-side errors when those options are provided.
45
- :find_and_modify_option_validation => 8,
46
- :transactions => 7,
47
- :scram_sha_256 => 7,
48
- :array_filters => 6,
49
- :op_msg => 6,
50
- :sessions => 6,
51
- :collation => 5,
52
- :max_staleness => 5,
46
+ find_and_modify_option_validation: 8,
47
+ transactions: 7,
48
+ scram_sha_256: 7,
49
+ array_filters: 6,
50
+ op_msg: 6,
51
+ sessions: 6,
52
+ collation: 5,
53
+ max_staleness: 5,
53
54
  # Server versions older than 3.4 do not reliably validate options
54
55
  # provided by the client during update/delete operations, requiring the
55
56
  # driver to raise client-side errors when those options are provided.
56
- :update_delete_option_validation => 5,
57
- :find_command => 4,
58
- :list_collections => 3,
59
- :list_indexes => 3,
60
- :scram_sha_1 => 3,
61
- :write_command => 2,
62
- :users_info => 2
57
+ update_delete_option_validation: 5,
58
+ find_command: 4,
59
+ list_collections: 3,
60
+ list_indexes: 3,
61
+ scram_sha_1: 3,
62
+ write_command: 2,
63
+ users_info: 2,
63
64
  }.freeze
64
65
 
65
66
  # Error message if the server is too old for this version of the driver.
@@ -0,0 +1,33 @@
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 Server
20
+ class Description
21
+
22
+ # Represents an assumed description of servers behind load balancers.
23
+ class LoadBalancer
24
+ def initialize(address)
25
+ @address = address
26
+ end
27
+
28
+ # @return [ Address ] address The server's address.
29
+ attr_reader :address
30
+ end
31
+ end
32
+ end
33
+ end
@@ -15,8 +15,6 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
 
18
- require 'mongo/server/description/features'
19
-
20
18
  module Mongo
21
19
  class Server
22
20
 
@@ -201,7 +199,8 @@ module Mongo
201
199
  ].freeze
202
200
 
203
201
  # Instantiate the new server description from the result of the hello
204
- # command.
202
+ # command or fabricate a placeholder description for Unknown and
203
+ # LoadBalancer servers.
205
204
  #
206
205
  # @example Instantiate the new description.
207
206
  # Description.new(address, { 'isWritablePrimary' => true }, 0.5)
@@ -209,17 +208,67 @@ module Mongo
209
208
  # @param [ Address ] address The server address.
210
209
  # @param [ Hash ] config The result of the hello command.
211
210
  # @param [ Float ] average_round_trip_time The moving average time (sec) the hello
212
- # call took to complete.
211
+ # command took to complete.
212
+ # @param [ Float ] average_round_trip_time The moving average time (sec)
213
+ # the ismaster call took to complete.
214
+ # @param [ true | false ] load_balancer Whether the server is treated as
215
+ # a load balancer.
216
+ # @param [ true | false ] force_load_balancer Whether the server is
217
+ # forced to be a load balancer.
213
218
  #
214
- # @since 2.0.0
215
- def initialize(address, config = {}, average_round_trip_time = nil)
219
+ # @api private
220
+ def initialize(address, config = {}, average_round_trip_time: nil,
221
+ load_balancer: false, force_load_balancer: false
222
+ )
216
223
  @address = address
217
224
  @config = config
225
+ @load_balancer = !!load_balancer
226
+ @force_load_balancer = !!force_load_balancer
218
227
  @features = Features.new(wire_versions, me || @address.to_s)
219
228
  @average_round_trip_time = average_round_trip_time
220
229
  @last_update_time = Time.now.freeze
221
230
  @last_update_monotime = Utils.monotonic_time
222
231
 
232
+ if load_balancer
233
+ # When loadBalanced=true URI option is set, the driver will refuse
234
+ # to work if the server it communicates with does not set serviceId
235
+ # in ismaster/hello response.
236
+ #
237
+ # In practice, there are currently no server version that actually
238
+ # sets this field.
239
+ #
240
+ # Therefore, when connect=:load_balanced Ruby option is used instead
241
+ # of the loadBalanced=true URI option, if serviceId is not set in
242
+ # ismaster/hello response, the driver fabricates a serviceId and
243
+ # proceeds to treat a server that does not report itself as being
244
+ # behind a load balancer as a server that is behind a load balancer.
245
+ #
246
+ # 5.0+ servers should provide topologyVersion.processId which
247
+ # is specific to the particular process instance. We can use that
248
+ # field as a proxy for serviceId.
249
+ #
250
+ # If the topologyVersion isn't provided for whatever reason, we
251
+ # fabricate a serviceId locally.
252
+ #
253
+ # In either case, a serviceId provided by an actual server behind
254
+ # a load balancer is supposed to be a BSON::ObjectId. The fabricated
255
+ # service ids are strings, to distinguish them from the real ones.
256
+ # In particular processId is also a BSON::ObjectId, but will be
257
+ # mapped to a string for clarity that this is a fake service id.
258
+ if ok? && !service_id
259
+ unless force_load_balancer
260
+ raise Error::MissingServiceId, "The server at #{address.seed} did not provide a service id in handshake response"
261
+ end
262
+
263
+ fake_service_id = if process_id = topology_version && topology_version['processId']
264
+ "process:#{process_id}"
265
+ else
266
+ "fake:#{rand(2**32-1)+1}"
267
+ end
268
+ @config = @config.merge('serviceId' => fake_service_id)
269
+ end
270
+ end
271
+
223
272
  if Mongo::Lint.enabled?
224
273
  # prepopulate cache instance variables
225
274
  hosts
@@ -237,11 +286,23 @@ module Mongo
237
286
  # @return [ Hash ] The actual result from the hello command.
238
287
  attr_reader :config
239
288
 
289
+ # Returns whether this server is a load balancer.
290
+ #
291
+ # @return [ true | false ] Whether this server is a load balancer.
292
+ def load_balancer?
293
+ @load_balancer
294
+ end
295
+
240
296
  # @return [ Features ] features The features for the server.
241
297
  def features
242
298
  @features
243
299
  end
244
300
 
301
+ # @return [ nil | Object ] The service id, if any.
302
+ def service_id
303
+ config['serviceId']
304
+ end
305
+
245
306
  # @return [ Float ] The moving average time the hello call took to complete.
246
307
  attr_reader :average_round_trip_time
247
308
 
@@ -625,6 +686,7 @@ module Mongo
625
686
  #
626
687
  # @since 2.4.0
627
688
  def server_type
689
+ return :load_balancer if load_balancer?
628
690
  return :arbiter if arbiter?
629
691
  return :ghost if ghost?
630
692
  return :sharded if mongos?
@@ -659,6 +721,7 @@ module Mongo
659
721
  #
660
722
  # @since 2.0.0
661
723
  def unknown?
724
+ return false if load_balancer?
662
725
  config.empty? || config.keys == %w(topologyVersion) || !ok?
663
726
  end
664
727
 
@@ -780,6 +843,11 @@ module Mongo
780
843
  config['connectionId']
781
844
  end
782
845
 
846
+ # @api experimental
847
+ def service_id
848
+ config['serviceId']
849
+ end
850
+
783
851
  # Check equality of two descriptions.
784
852
  #
785
853
  # @example Check description equality.
@@ -825,8 +893,19 @@ module Mongo
825
893
  raise ArgumentError, "Bogus required version #{version}"
826
894
  end
827
895
 
896
+ if load_balancer?
897
+ # If we are talking to a load balancer, there is no monitoring
898
+ # and we don't know what server is behind the load balancer.
899
+ # Assume everything is supported.
900
+ # TODO remove this when RUBY-2220 is implemented.
901
+ return true
902
+ end
903
+
828
904
  required_wv >= min_wire_version && required_wv <= max_wire_version
829
905
  end
830
906
  end
831
907
  end
832
908
  end
909
+
910
+ require 'mongo/server/description/features'
911
+ require 'mongo/server/description/load_balancer'
@@ -194,13 +194,12 @@ module Mongo
194
194
  #
195
195
  # @raise [Mongo::Error] If handshake failed.
196
196
  def handshake!
197
- document = handshake_document(
198
- @app_metadata,
199
- server_api: options[:server_api]
197
+ command = handshake_command(
198
+ handshake_document(
199
+ @app_metadata,
200
+ server_api: options[:server_api]
201
+ )
200
202
  )
201
- # TODO (DR): OP_MSG should be used if api version is declared.
202
- # See https://github.com/mongodb/specifications/blob/master/source/message/OP_MSG.rst#id5
203
- command = Protocol::Query.new(Database::ADMIN, Database::COMMAND, document, :limit => -1)
204
203
  payload = command.serialize.to_s
205
204
  message = dispatch_bytes(payload)
206
205
  result = Operation::Result.new(message)
@@ -215,7 +215,8 @@ module Mongo
215
215
  old_description = server.description
216
216
 
217
217
  new_description = Description.new(server.address, result,
218
- server.round_trip_time_averager.average_round_trip_time)
218
+ average_round_trip_time: server.round_trip_time_averager.average_round_trip_time
219
+ )
219
220
 
220
221
  server.cluster.run_sdam_flow(server.description, new_description, awaited: awaited)
221
222
 
@@ -71,32 +71,41 @@ module Mongo
71
71
  raise Error::InternalDriverError, "Connection description cannot be unknown after successful handshake: #{description.inspect}"
72
72
  end
73
73
 
74
- if speculative_auth_doc && (speculative_auth_result = result['speculativeAuthenticate'])
75
- unless description.features.scram_sha_1_enabled?
76
- raise Error::InvalidServerAuthResponse, "Speculative auth succeeded on a pre-3.0 server"
77
- end
78
- case speculative_auth_user.mechanism
79
- when :mongodb_x509
80
- # Done
81
- # We default auth mechanism to scram256, but if user specified
82
- # scram explicitly we may be able to authenticate speculatively
83
- # with scram.
84
- when :scram, :scram256
85
- authenticate!(
86
- speculative_auth_client_nonce: speculative_auth.conversation.client_nonce,
87
- speculative_auth_mech: speculative_auth_user.mechanism,
88
- speculative_auth_result: speculative_auth_result,
89
- )
90
- else
91
- raise Error::InternalDriverError, "Speculative auth unexpectedly succeeded for mechanism #{speculative_auth_user.mechanism.inspect}"
74
+ begin
75
+ if speculative_auth_doc && (speculative_auth_result = result['speculativeAuthenticate'])
76
+ unless description.features.scram_sha_1_enabled?
77
+ raise Error::InvalidServerAuthResponse, "Speculative auth succeeded on a pre-3.0 server"
78
+ end
79
+ case speculative_auth_user.mechanism
80
+ when :mongodb_x509
81
+ # Done
82
+ # We default auth mechanism to scram256, but if user specified
83
+ # scram explicitly we may be able to authenticate speculatively
84
+ # with scram.
85
+ when :scram, :scram256
86
+ authenticate!(
87
+ speculative_auth_client_nonce: speculative_auth.conversation.client_nonce,
88
+ speculative_auth_mech: speculative_auth_user.mechanism,
89
+ speculative_auth_result: speculative_auth_result,
90
+ )
91
+ else
92
+ raise Error::InternalDriverError, "Speculative auth unexpectedly succeeded for mechanism #{speculative_auth_user.mechanism.inspect}"
93
+ end
94
+ elsif !description.arbiter?
95
+ authenticate!
92
96
  end
93
- elsif !description.arbiter?
94
- authenticate!
97
+ rescue Mongo::Error, Mongo::Error::AuthError => exc
98
+ exc.service_id = service_id
99
+ raise
95
100
  end
96
101
 
97
102
  if description.unknown?
98
103
  raise Error::InternalDriverError, "Connection description cannot be unknown after successful authentication: #{description.inspect}"
99
104
  end
105
+
106
+ if server.load_balancer? && !description.mongos?
107
+ raise Error::BadLoadBalancerTarget, "Load-balanced operation requires being connected a mongos, but the server at #{address.seed} reported itself as #{description.server_type.to_s.gsub('_', ' ')}"
108
+ end
100
109
  end
101
110
 
102
111
  private
@@ -111,16 +120,14 @@ module Mongo
111
120
  raise Error::InternalDriverError, "Cannot handshake because there is no usable socket (for #{address})"
112
121
  end
113
122
 
114
- hello_doc = handshake_document(
115
- app_metadata,
116
- speculative_auth_doc: speculative_auth_doc,
117
- server_api: options[:server_api],
123
+ hello_command = handshake_command(
124
+ handshake_document(
125
+ app_metadata,
126
+ speculative_auth_doc: speculative_auth_doc,
127
+ load_balancer: server.load_balancer?,
128
+ server_api: options[:server_api]
129
+ )
118
130
  )
119
-
120
- # TODO (DR): OP_MSG should be used if api version is declared.
121
- # See https://github.com/mongodb/specifications/blob/master/source/message/OP_MSG.rst#id5
122
- hello_command = Protocol::Query.new(Database::ADMIN, Database::COMMAND, hello_doc, :limit => -1)
123
-
124
131
  doc = nil
125
132
  @server.handle_handshake_failure! do
126
133
  begin
@@ -144,6 +151,10 @@ module Mongo
144
151
  end
145
152
  end
146
153
 
154
+ if @server.force_load_balancer?
155
+ doc['serviceId'] ||= "fake:#{rand(2**32-1)+1}"
156
+ end
157
+
147
158
  post_handshake(doc, @server.round_trip_time_averager.average_round_trip_time)
148
159
 
149
160
  doc
@@ -193,7 +204,7 @@ module Mongo
193
204
  # This is a separate method to keep the nesting level down.
194
205
  #
195
206
  # @return [ Server::Description ] The server description calculated from
196
- # hello response for this particular connection.
207
+ # the handshake response for this particular connection.
197
208
  def post_handshake(response, average_rtt)
198
209
  if response["ok"] == 1
199
210
  # Auth mechanism is entirely dependent on the contents of
@@ -210,7 +221,12 @@ module Mongo
210
221
  @sasl_supported_mechanisms = nil
211
222
  end
212
223
 
213
- @description = Description.new(address, response, average_rtt).tap do |new_description|
224
+ @description = Description.new(
225
+ address, response,
226
+ average_round_trip_time: average_rtt,
227
+ load_balancer: server.load_balancer?,
228
+ force_load_balancer: options[:connect] == :load_balanced,
229
+ ).tap do |new_description|
214
230
  @server.cluster.run_sdam_flow(@server.description, new_description)
215
231
  end
216
232
  end
@@ -111,6 +111,12 @@ module Mongo
111
111
  @topology_version = new_description.topology_version
112
112
  end
113
113
  rescue Mongo::Error => exc
114
+ stop_requested = @lock.synchronize { @stop_requested }
115
+ if stop_requested
116
+ # Ignore the exception, see RUBY-2771.
117
+ return
118
+ end
119
+
114
120
  msg = "Error running awaited hello on #{server.address}"
115
121
  Utils.warn_bg_exception(msg, exc,
116
122
  logger: options[:logger],
data/lib/mongo/server.rb CHANGED
@@ -54,6 +54,9 @@ module Mongo
54
54
  # done by this server. Note: setting this option to false will make
55
55
  # the server non-functional. It is intended for use in tests which
56
56
  # manually invoke SDAM state transitions.
57
+ # @option options [ true | false ] :load_balancer Whether this server
58
+ # is a load balancer.
59
+ # @option options [ String ] :connect The client connection mode.
57
60
  #
58
61
  # @since 2.0.0
59
62
  def initialize(address, cluster, monitoring, event_listeners, options = {})
@@ -69,7 +72,10 @@ module Mongo
69
72
  end
70
73
  @scan_semaphore = DistinguishingSemaphore.new
71
74
  @round_trip_time_averager = RoundTripTimeAverager.new
72
- @description = Description.new(address, {})
75
+ @description = Description.new(address, {},
76
+ load_balancer: !!@options[:load_balancer],
77
+ force_load_balancer: force_load_balancer?,
78
+ )
73
79
  @last_scan = nil
74
80
  @last_scan_monotime = nil
75
81
  unless options[:monitoring_io] == false
@@ -107,6 +113,15 @@ module Mongo
107
113
  # description the monitor refreshes.
108
114
  attr_reader :description
109
115
 
116
+ # Returns whether this server is forced to be a load balancer.
117
+ #
118
+ # @return [ true | false ] Whether this server is forced to be a load balancer.
119
+ #
120
+ # @api private
121
+ def force_load_balancer?
122
+ options[:connect] == :load_balanced
123
+ end
124
+
110
125
  # @return [ Time | nil ] last_scan The time when the last server scan
111
126
  # completed, or nil if the server has not been scanned yet.
112
127
  #
@@ -180,6 +195,7 @@ module Mongo
180
195
  :secondary?,
181
196
  :standalone?,
182
197
  :unknown?,
198
+ :load_balancer?,
183
199
  :last_write_date,
184
200
  :logical_session_timeout
185
201
 
@@ -222,20 +238,6 @@ module Mongo
222
238
  address == other.address
223
239
  end
224
240
 
225
- # Get a new context for this server in which to send messages.
226
- #
227
- # @example Get the server context.
228
- # server.context
229
- #
230
- # @return [ Mongo::Server::Context ] context The server context.
231
- #
232
- # @since 2.0.0
233
- #
234
- # @deprecated Will be removed in version 3.0
235
- def context
236
- Context.new(self)
237
- end
238
-
239
241
  # Determine if a connection to the server is able to be established and
240
242
  # messages can be sent to it.
241
243
  #
@@ -301,13 +303,20 @@ module Mongo
301
303
  #
302
304
  # @api private
303
305
  def start_monitoring
306
+ publish_opening_event
307
+ if options[:monitoring_io] != false
308
+ monitor.run!
309
+ end
310
+ end
311
+
312
+ # Publishes the server opening event.
313
+ #
314
+ # @api private
315
+ def publish_opening_event
304
316
  publish_sdam_event(
305
317
  Monitoring::SERVER_OPENING,
306
318
  Monitoring::Event::ServerOpening.new(address, cluster.topology)
307
319
  )
308
- if options[:monitoring_io] != false
309
- monitor.run!
310
- end
311
320
  end
312
321
 
313
322
  # Get a pretty printed server inspection.
@@ -327,6 +336,8 @@ module Mongo
327
336
  # @api private
328
337
  def status
329
338
  case
339
+ when load_balancer?
340
+ 'LB'
330
341
  when primary?
331
342
  'PRIMARY'
332
343
  when secondary?
@@ -433,8 +444,8 @@ module Mongo
433
444
  # @return [ Object ] The result of the block execution.
434
445
  #
435
446
  # @since 2.3.0
436
- def with_connection(&block)
437
- pool.with_connection(&block)
447
+ def with_connection(service_id: nil, &block)
448
+ pool.with_connection(service_id: service_id, &block)
438
449
  end
439
450
 
440
451
  # Handle handshake failure.
@@ -444,7 +455,11 @@ module Mongo
444
455
  def handle_handshake_failure!
445
456
  yield
446
457
  rescue Mongo::Error::SocketError, Mongo::Error::SocketTimeoutError => e
447
- unknown!(generation: e.generation, stop_push_monitor: true)
458
+ unknown!(
459
+ generation: e.generation,
460
+ service_id: e.service_id,
461
+ stop_push_monitor: true,
462
+ )
448
463
  raise
449
464
  end
450
465
 
@@ -467,7 +482,11 @@ module Mongo
467
482
  raise
468
483
  rescue Mongo::Error::SocketError => e
469
484
  # non-timeout network error
470
- unknown!(generation: e.generation, stop_push_monitor: true)
485
+ unknown!(
486
+ generation: e.generation,
487
+ service_id: e.service_id,
488
+ stop_push_monitor: true,
489
+ )
471
490
  raise
472
491
  rescue Auth::Unauthorized
473
492
  # auth error, keep server description and topology as they are
@@ -513,13 +532,33 @@ module Mongo
513
532
  # respective server is cleared. Set this option to true to keep the
514
533
  # existing connection pool (required when handling not master errors
515
534
  # on 4.2+ servers).
535
+ # @option options [ Object ] :service_id Discard state for the specified
536
+ # service id only.
516
537
  # @option options [ TopologyVersion ] :topology_version Topology version
517
538
  # of the error response that is causing the server to be marked unknown.
518
539
  # @option options [ true | false ] :stop_push_monitor Whether to stop
519
540
  # the PushMonitor associated with the server, if any.
541
+ # @option options [ Object ] :service_id Discard state for the specified
542
+ # service id only.
520
543
  #
521
544
  # @since 2.4.0, SDAM events are sent as of version 2.7.0
522
545
  def unknown!(options = {})
546
+ if load_balancer?
547
+ # When the client is in load-balanced topology, servers (the one and
548
+ # only that can be) starts out as a load balancer and stays as a
549
+ # load balancer indefinitely. As such it is not marked unknown.
550
+ #
551
+ # However, this method also clears connection pool for the server
552
+ # when the latter is marked unknown, and this part needs to happen
553
+ # when the server is a load balancer.
554
+ if service_id = options[:service_id]
555
+ pool.disconnect!(service_id: service_id)
556
+ elsif Lint.enabled?
557
+ raise Error::LintError, 'Load balancer was asked to be marked unknown without a service id'
558
+ end
559
+ return
560
+ end
561
+
523
562
  if options[:generation] && options[:generation] < pool.generation
524
563
  return
525
564
  end
@@ -537,10 +576,16 @@ module Mongo
537
576
  # SDAM flow will update description on the server without in-place
538
577
  # mutations and invoke SDAM transitions as needed.
539
578
  config = {}
579
+ if options[:service_id]
580
+ config['serviceId'] = options[:service_id]
581
+ end
540
582
  if options[:topology_version]
541
583
  config['topologyVersion'] = options[:topology_version]
542
584
  end
543
- new_description = Description.new(address, config)
585
+ new_description = Description.new(address, config,
586
+ load_balancer: load_balancer?,
587
+ force_load_balancer: options[:connect] == :load_balanced,
588
+ )
544
589
  cluster.run_sdam_flow(description, new_description, options)
545
590
  end
546
591
 
@@ -549,11 +594,14 @@ module Mongo
549
594
  @description = description
550
595
  end
551
596
 
597
+ # @param [ Object ] :service_id Close connections with the specified
598
+ # service id only.
599
+ #
552
600
  # @api private
553
- def clear_connection_pool
601
+ def clear_connection_pool(service_id: nil)
554
602
  @pool_lock.synchronize do
555
603
  if @pool
556
- @pool.disconnect!
604
+ @pool.disconnect!(service_id: service_id)
557
605
  end
558
606
  end
559
607
  end
@@ -577,7 +625,6 @@ require 'mongo/server/connection_base'
577
625
  require 'mongo/server/pending_connection'
578
626
  require 'mongo/server/connection'
579
627
  require 'mongo/server/connection_pool'
580
- require 'mongo/server/context'
581
628
  require 'mongo/server/description'
582
629
  require 'mongo/server/monitor'
583
630
  require 'mongo/server/round_trip_time_averager'