mongo 2.15.0 → 2.16.1

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 (332) 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 +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 +10 -1
  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/connection_spec.rb +22 -0
  198. data/spec/mongo/server/monitor_spec.rb +4 -3
  199. data/spec/mongo/server/push_monitor_spec.rb +101 -0
  200. data/spec/mongo/session/session_pool_spec.rb +42 -10
  201. data/spec/mongo/session_transaction_spec.rb +15 -30
  202. data/spec/mongo/socket/unix_spec.rb +1 -0
  203. data/spec/mongo/uri_option_parsing_spec.rb +38 -5
  204. data/spec/runners/change_streams/test.rb +1 -1
  205. data/spec/runners/cmap.rb +1 -1
  206. data/spec/runners/connection_string.rb +7 -3
  207. data/spec/runners/crud/operation.rb +5 -3
  208. data/spec/runners/crud/requirement.rb +1 -0
  209. data/spec/runners/crud.rb +1 -1
  210. data/spec/runners/sdam.rb +2 -1
  211. data/spec/runners/transactions/test.rb +2 -2
  212. data/spec/runners/unified/assertions.rb +2 -3
  213. data/spec/runners/unified/event_subscriber.rb +2 -2
  214. data/spec/runners/unified/support_operations.rb +10 -2
  215. data/spec/runners/unified/test.rb +3 -0
  216. data/spec/runners/unified.rb +1 -1
  217. data/spec/shared/lib/mrss/cluster_config.rb +6 -1
  218. data/spec/shared/lib/mrss/constraints.rb +11 -5
  219. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  220. data/spec/shared/lib/mrss/server_version_registry.rb +17 -12
  221. data/spec/shared/share/Dockerfile.erb +5 -4
  222. data/spec/shared/shlib/server.sh +70 -20
  223. data/spec/spec_tests/change_streams_spec.rb +1 -1
  224. data/spec/spec_tests/cmap_spec.rb +4 -1
  225. data/spec/spec_tests/command_monitoring_spec.rb +2 -2
  226. data/spec/spec_tests/data/command_monitoring/find.yml +9 -9
  227. data/spec/spec_tests/data/crud/read/aggregate-collation.yml +2 -1
  228. data/spec/spec_tests/data/crud/read/aggregate-out.yml +1 -0
  229. data/spec/spec_tests/data/crud/read/count-collation.yml +2 -1
  230. data/spec/spec_tests/data/crud/read/distinct-collation.yml +2 -1
  231. data/spec/spec_tests/data/crud/read/find-collation.yml +2 -1
  232. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +2 -1
  233. data/spec/spec_tests/data/crud/write/deleteMany-collation.yml +2 -1
  234. data/spec/spec_tests/data/crud/write/deleteOne-collation.yml +2 -1
  235. data/spec/spec_tests/data/crud/write/findOneAndDelete-collation.yml +3 -2
  236. data/spec/spec_tests/data/crud/write/findOneAndReplace-collation.yml +2 -1
  237. data/spec/spec_tests/data/crud/write/findOneAndUpdate-collation.yml +3 -2
  238. data/spec/spec_tests/data/crud/write/replaceOne-collation.yml +3 -2
  239. data/spec/spec_tests/data/crud/write/updateMany-collation.yml +2 -1
  240. data/spec/spec_tests/data/crud/write/updateOne-collation.yml +2 -1
  241. data/spec/spec_tests/data/load_balancers/event-monitoring.yml +99 -0
  242. data/spec/spec_tests/data/load_balancers/lb-connection-establishment.yml +36 -0
  243. data/spec/spec_tests/data/load_balancers/non-lb-connection-establishment.yml +56 -0
  244. data/spec/spec_tests/data/load_balancers/server-selection.yml +50 -0
  245. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +1 -1
  246. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +1 -1
  247. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +1 -1
  248. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +1 -1
  249. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +1 -1
  250. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +1 -1
  251. data/spec/spec_tests/data/retryable_reads/mapReduce.yml +3 -1
  252. data/spec/spec_tests/data/sdam/load-balanced/discover_load_balancer.yml +25 -0
  253. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +2 -0
  254. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +2 -0
  255. data/spec/spec_tests/data/sdam_integration/hello-command-error.yml +3 -1
  256. data/spec/spec_tests/data/sdam_integration/hello-network-error.yml +3 -1
  257. data/spec/spec_tests/data/sdam_integration/hello-timeout.yml +2 -0
  258. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +2 -0
  259. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +2 -0
  260. data/spec/spec_tests/data/sdam_monitoring/load_balancer.yml +65 -0
  261. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-directConnection.yml +13 -0
  262. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-replicaSet-errors.yml +6 -0
  263. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-multiple-hosts.yml +5 -0
  264. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-txt.yml +10 -0
  265. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-false.yml +0 -0
  266. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-true.yml +0 -0
  267. data/spec/spec_tests/data/seed_list_discovery/replica-set/encoded-userinfo-and-db.yml +15 -0
  268. data/spec/spec_tests/data/seed_list_discovery/replica-set/loadBalanced-false-txt.yml +10 -0
  269. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/longer-parent-in-return.yml +0 -0
  270. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/misformatted-option.yml +0 -0
  271. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/no-results.yml +0 -0
  272. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/not-enough-parts.yml +0 -0
  273. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-result-default-port.yml +0 -0
  274. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record-multiple-strings.yml +0 -0
  275. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record.yml +0 -0
  276. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch1.yml +0 -0
  277. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch2.yml +0 -0
  278. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch3.yml +0 -0
  279. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch4.yml +0 -0
  280. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch5.yml +0 -0
  281. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-too-short.yml +0 -0
  282. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-wrong.yml +0 -0
  283. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-default-port.yml +0 -0
  284. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-nonstandard-port.yml +0 -0
  285. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-txt-records.yml +0 -0
  286. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-not-allowed-option.yml +0 -0
  287. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-ssl-option.yml +0 -0
  288. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-uri-option.yml +0 -0
  289. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-unallowed-option.yml +0 -0
  290. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-admin-database.yml +13 -0
  291. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-auth.yml +12 -0
  292. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-port.yml +0 -0
  293. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-two-hosts.yml +0 -0
  294. data/spec/spec_tests/data/transactions/retryable-abort-errorLabels.yml +2 -0
  295. data/spec/spec_tests/data/transactions/retryable-abort.yml +2 -0
  296. data/spec/spec_tests/data/transactions/retryable-commit-errorLabels.yml +2 -0
  297. data/spec/spec_tests/data/transactions/retryable-commit.yml +2 -0
  298. data/spec/spec_tests/data/transactions/retryable-writes.yml +2 -0
  299. data/spec/spec_tests/data/uri_options/connection-options.yml +60 -0
  300. data/spec/spec_tests/load_balancers_spec.rb +15 -0
  301. data/spec/spec_tests/retryable_reads_spec.rb +2 -2
  302. data/spec/spec_tests/retryable_writes_spec.rb +1 -1
  303. data/spec/spec_tests/sdam_integration_spec.rb +1 -1
  304. data/spec/spec_tests/sdam_monitoring_spec.rb +10 -5
  305. data/spec/spec_tests/sdam_spec.rb +1 -1
  306. data/spec/spec_tests/seed_list_discovery_spec.rb +118 -0
  307. data/spec/spec_tests/uri_options_spec.rb +4 -4
  308. data/spec/stress/fork_reconnect_stress_spec.rb +1 -5
  309. data/spec/stress/push_monitor_close_spec.rb +44 -0
  310. data/spec/support/certificates/atlas-ocsp-ca.crt +82 -90
  311. data/spec/support/certificates/atlas-ocsp.crt +127 -122
  312. data/spec/support/common_shortcuts.rb +2 -3
  313. data/spec/support/matchers.rb +13 -0
  314. data/spec/support/shared/auth_context.rb +16 -0
  315. data/spec/support/shared/session.rb +2 -2
  316. data/spec/support/spec_config.rb +10 -11
  317. data/spec/support/using_hash.rb +31 -0
  318. data/spec/support/utils.rb +1 -1
  319. data.tar.gz.sig +0 -0
  320. metadata +1077 -1029
  321. metadata.gz.sig +0 -0
  322. data/lib/mongo/collection/view/builder/find_command.rb +0 -173
  323. data/lib/mongo/collection/view/builder/op_query.rb +0 -94
  324. data/lib/mongo/cursor/builder/get_more_command.rb +0 -80
  325. data/lib/mongo/cursor/builder/kill_cursors_command.rb +0 -111
  326. data/lib/mongo/cursor/builder/op_get_more.rb +0 -64
  327. data/lib/mongo/cursor/builder/op_kill_cursors.rb +0 -106
  328. data/lib/mongo/server/context.rb +0 -72
  329. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -66
  330. data/spec/runners/unified/using_hash.rb +0 -34
  331. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +0 -79
  332. data/spec/support/event_subscriber.rb +0 -221
@@ -57,13 +57,15 @@ module Mongo
57
57
  # @param [ Server::AppMetadata ] app_metadata Application metadata
58
58
  # @param [ BSON::Document ] speculative_auth_doc The speculative
59
59
  # authentication document, if any.
60
+ # @param [ true | false ] load_balancer Whether the connection is to
61
+ # a load balancer.
60
62
  # @param server_api [ Hash | nil ] server_api Server API version.
61
63
  #
62
64
  # @return [BSON::Document] Document that should be sent to a server
63
65
  # for handshake purposes.
64
66
  #
65
67
  # @api private
66
- def handshake_document(app_metadata, speculative_auth_doc: nil, server_api: nil)
68
+ def handshake_document(app_metadata, speculative_auth_doc: nil, load_balancer: false, server_api: nil)
67
69
  serv_api = app_metadata.server_api || server_api
68
70
  document = if serv_api
69
71
  HELLO_DOC.merge(Utils.transform_server_api(serv_api))
@@ -74,6 +76,33 @@ module Mongo
74
76
  if speculative_auth_doc
75
77
  doc.update(speculativeAuthenticate: speculative_auth_doc)
76
78
  end
79
+ if load_balancer
80
+ doc.update(loadBalanced: true)
81
+ end
82
+ end
83
+ end
84
+
85
+ # Build a command that should be used for connection handshake.
86
+ #
87
+ # @param [ BSON::Document ] handshake_document Document that should be
88
+ # sent to a server for handshake purpose.
89
+ #
90
+ # @return [ Protocol::Message ] Command that should be sent to a server
91
+ # for handshake purposes.
92
+ #
93
+ # @api private
94
+ def handshake_command(handshake_document)
95
+ if handshake_document['apiVersion']
96
+ Protocol::Msg.new(
97
+ [], {}, handshake_document.merge({'$db' => Database::ADMIN})
98
+ )
99
+ else
100
+ Protocol::Query.new(
101
+ Database::ADMIN,
102
+ Database::COMMAND,
103
+ handshake_document,
104
+ :limit => -1
105
+ )
77
106
  end
78
107
  end
79
108
 
@@ -125,10 +154,18 @@ module Mongo
125
154
  if respond_to?(:id)
126
155
  note << ", connection #{generation}:#{id}"
127
156
  end
157
+ # Non-monitoring connections have service id.
158
+ # Monitoring connections do not.
159
+ if respond_to?(:service_id) && service_id
160
+ note << ", service id #{service_id}"
161
+ end
128
162
  e.add_note(note)
129
163
  if respond_to?(:generation)
130
164
  # Non-monitoring connections
131
165
  e.generation = generation
166
+ if respond_to?(:description)
167
+ e.service_id = service_id
168
+ end
132
169
  end
133
170
  raise e
134
171
  end
@@ -0,0 +1,71 @@
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 ConnectionPool
21
+
22
+ # @api private
23
+ class GenerationManager
24
+
25
+ def initialize(server:)
26
+ @map = Hash.new { |hash, key| hash[key] = 1 }
27
+ @server = server
28
+ @lock = Mutex.new
29
+ end
30
+
31
+ attr_reader :server
32
+
33
+ def generation(service_id: nil)
34
+ if service_id
35
+ unless server.load_balancer?
36
+ raise ArgumentError, "Generation scoping to services is only available in load-balanced mode, but the server at #{server.address} is not a load balancer"
37
+ end
38
+ else
39
+ if server.load_balancer?
40
+ raise ArgumentError, "The server at #{server.address} is a load balancer and therefore does not have a single global generation"
41
+ end
42
+ end
43
+ @lock.synchronize do
44
+ @map[service_id]
45
+ end
46
+ end
47
+
48
+ def bump(service_id: nil)
49
+ @lock.synchronize do
50
+ if service_id
51
+ @map[service_id] += 1
52
+ else
53
+ # When service id is not supplied, one of two things may be
54
+ # happening;
55
+ #
56
+ # 1. The pool is not to a load balancer, in which case we only
57
+ # need to increment the generation for the nil service_id.
58
+ # 2. The pool is to a load balancer, in which case we need to
59
+ # increment the generation for each service.
60
+ #
61
+ # Incrementing everything in the map accomplishes both tasks.
62
+ @map.each do |k, v|
63
+ @map[k] += 1
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -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