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
@@ -14,7 +14,6 @@
14
14
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
- require 'mongo/server/connection_pool/populator'
18
17
 
19
18
  module Mongo
20
19
  class Server
@@ -111,7 +110,7 @@ module Mongo
111
110
  @server = server
112
111
  @options = options.freeze
113
112
 
114
- @generation = 1
113
+ @generation_manager = GenerationManager.new(server: server)
115
114
  @closed = false
116
115
 
117
116
  # A connection owned by this pool should be either in the
@@ -189,12 +188,14 @@ module Mongo
189
188
  @max_idle_time ||= options[:max_idle_time]
190
189
  end
191
190
 
191
+ # @api private
192
+ attr_reader :generation_manager
193
+
192
194
  # @return [ Integer ] generation Generation of connections currently
193
195
  # being used by the queue.
194
196
  #
195
- # @since 2.9.0
196
197
  # @api private
197
- attr_reader :generation
198
+ def_delegator :generation_manager, :generation
198
199
 
199
200
  # Size of the connection pool.
200
201
  #
@@ -277,7 +278,7 @@ module Mongo
277
278
  # and remains so for longer than the wait timeout.
278
279
  #
279
280
  # @since 2.9.0
280
- def check_out
281
+ def check_out(service_id: nil)
281
282
  check_invariants
282
283
 
283
284
  publish_cmap_event(
@@ -306,7 +307,12 @@ module Mongo
306
307
  # a connection while this thread is waiting for one.
307
308
  @lock.synchronize do
308
309
  until @available_connections.empty?
309
- connection = @available_connections.pop
310
+ connection = next_available_connection(service_id: service_id)
311
+
312
+ # If service_id is not nil, connection may be nil here
313
+ # even if there are available connections in the pool
314
+ # (they could be to other services).
315
+ break unless connection
310
316
 
311
317
  if connection.pid != pid
312
318
  log_warn("Detected PID change - Mongo client should have been reconnected (old pid #{connection.pid}, new pid #{pid}")
@@ -315,7 +321,7 @@ module Mongo
315
321
  next
316
322
  end
317
323
 
318
- if connection.generation != generation
324
+ if connection.generation != generation(service_id: connection.service_id)
319
325
  # Stale connections should be disconnected in the clear
320
326
  # method, but if any don't, check again here
321
327
  connection.disconnect!(reason: :stale)
@@ -335,12 +341,22 @@ module Mongo
335
341
  throw(:done)
336
342
  end
337
343
 
338
- # Ruby does not allow a thread to lock a mutex which it already
339
- # holds.
340
- if unsynchronized_size < max_size
341
- connection = create_connection
342
- @pending_connections << connection
343
- throw(:done)
344
+ if service_id
345
+ # If we need a connection to a particular service, we can't
346
+ # create one if we don't already have one, but we can wait
347
+ # for an in-progress operation to return such a connection
348
+ # to the pool, or for the populator to create a suitable
349
+ # connection.
350
+ else
351
+ # If we are below pool capacity, create a new connection.
352
+ #
353
+ # Ruby does not allow a thread to lock a mutex which it already
354
+ # holds.
355
+ if unsynchronized_size < max_size
356
+ connection = create_connection
357
+ @pending_connections << connection
358
+ throw(:done)
359
+ end
344
360
  end
345
361
  end
346
362
 
@@ -354,8 +370,14 @@ module Mongo
354
370
  )
355
371
 
356
372
  msg = @lock.synchronize do
373
+ service_id_msg = if service_id
374
+ " for service #{service_id}"
375
+ else
376
+ ''
377
+ end
378
+
357
379
  "Timed out attempting to check out a connection " +
358
- "from pool for #{@server.address} after #{wait_timeout} sec. " +
380
+ "from pool for #{@server.address}#{service_id_msg} after #{wait_timeout} sec. " +
359
381
  "Connections in pool: #{@available_connections.length} available, " +
360
382
  "#{@checked_out_connections.length} checked out, " +
361
383
  "#{@pending_connections.length} pending " +
@@ -449,7 +471,7 @@ module Mongo
449
471
  # Connection was closed - for example, because it experienced
450
472
  # a network error. Nothing else needs to be done here.
451
473
  @populate_semaphore.signal
452
- elsif connection.generation != @generation
474
+ elsif connection.generation != generation(service_id: connection.service_id)
453
475
  connection.disconnect!(reason: :stale)
454
476
  @populate_semaphore.signal
455
477
  else
@@ -473,8 +495,12 @@ module Mongo
473
495
  # @option options [ true | false ] :lazy If true, do not close any of
474
496
  # the idle connections and instead let them be closed during a
475
497
  # subsequent check out operation.
498
+ # @option options [ Object ] :service_id Discard state for the specified
499
+ # service id only.
476
500
  # @option options [ true | false ] :stop_populator Whether to stop
477
501
  # the populator background thread. For internal driver use only.
502
+ # @option options [ Object ] :service_id Clear connections with
503
+ # the specified service id only.
478
504
  #
479
505
  # @return [ true ] true.
480
506
  #
@@ -488,18 +514,38 @@ module Mongo
488
514
  stop_populator
489
515
  end
490
516
 
517
+ service_id = options && options[:service_id]
518
+
491
519
  @lock.synchronize do
492
- @generation += 1
520
+ @generation_manager.bump(service_id: service_id)
493
521
 
494
522
  publish_cmap_event(
495
- Monitoring::Event::Cmap::PoolCleared.new(@server.address)
523
+ Monitoring::Event::Cmap::PoolCleared.new(
524
+ @server.address,
525
+ service_id: service_id,
526
+ )
496
527
  )
497
528
 
498
529
  unless options && options[:lazy]
499
- until @available_connections.empty?
500
- connection = @available_connections.pop
501
- connection.disconnect!(reason: :stale)
502
- @populate_semaphore.signal
530
+ if service_id
531
+ loop do
532
+ conn = @available_connections.detect do |conn|
533
+ conn.service_id == service_id
534
+ end
535
+ if conn
536
+ @available_connections.delete(conn)
537
+ conn.disconnect!(reason: :stale)
538
+ @populate_semaphore.signal
539
+ else
540
+ break
541
+ end
542
+ end
543
+ else
544
+ until @available_connections.empty?
545
+ connection = @available_connections.pop
546
+ connection.disconnect!(reason: :stale)
547
+ @populate_semaphore.signal
548
+ end
503
549
  end
504
550
  end
505
551
  end
@@ -586,10 +632,10 @@ module Mongo
586
632
  # @return [ Object ] The result of the block.
587
633
  #
588
634
  # @since 2.0.0
589
- def with_connection
635
+ def with_connection(service_id: nil)
590
636
  raise_if_closed!
591
637
 
592
- connection = check_out
638
+ connection = check_out(service_id: service_id)
593
639
  yield(connection)
594
640
  ensure
595
641
  if connection
@@ -705,13 +751,33 @@ module Mongo
705
751
 
706
752
  private
707
753
 
754
+ # Returns the next available connection, optionally scoped to the
755
+ # specified service. If no suitable connections are available,
756
+ # returns nil.
757
+ def next_available_connection(service_id: nil)
758
+ if service_id
759
+ conn = @available_connections.detect do |conn|
760
+ conn.service_id == service_id
761
+ end
762
+ if conn
763
+ @available_connections.delete(conn)
764
+ end
765
+ conn
766
+ else
767
+ @available_connections.pop
768
+ end
769
+ end
770
+
708
771
  def create_connection
709
- connection = Connection.new(@server, options.merge(
710
- generation: generation,
772
+ opts = options.merge(
711
773
  connection_pool: self,
712
774
  # Do not pass app metadata - this will be retrieved by the connection
713
775
  # based on the auth needs.
714
- ))
776
+ )
777
+ unless @server.load_balancer?
778
+ opts[:generation] = generation
779
+ end
780
+ connection = Connection.new(@server, opts)
715
781
  end
716
782
 
717
783
  # Create a connection, connect it, and add it to the pool.
@@ -772,7 +838,11 @@ module Mongo
772
838
  raise
773
839
  end
774
840
  rescue Error::SocketError, Error::SocketTimeoutError => exc
775
- @server.unknown!(generation: exc.generation, stop_push_monitor: true)
841
+ @server.unknown!(
842
+ generation: exc.generation,
843
+ service_id: exc.service_id,
844
+ stop_push_monitor: true,
845
+ )
776
846
  raise
777
847
  end
778
848
 
@@ -800,3 +870,6 @@ module Mongo
800
870
  end
801
871
  end
802
872
  end
873
+
874
+ require 'mongo/server/connection_pool/generation_manager'
875
+ require 'mongo/server/connection_pool/populator'
@@ -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