mongo 2.13.0.beta1 → 2.14.0

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 (339) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -5
  4. data/Rakefile +50 -9
  5. data/lib/mongo.rb +13 -2
  6. data/lib/mongo/address.rb +1 -1
  7. data/lib/mongo/address/ipv4.rb +1 -1
  8. data/lib/mongo/address/ipv6.rb +1 -1
  9. data/lib/mongo/auth/aws/request.rb +31 -5
  10. data/lib/mongo/bulk_write.rb +18 -0
  11. data/lib/mongo/caching_cursor.rb +74 -0
  12. data/lib/mongo/client.rb +238 -31
  13. data/lib/mongo/cluster.rb +56 -20
  14. data/lib/mongo/cluster/sdam_flow.rb +13 -10
  15. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +3 -2
  16. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  17. data/lib/mongo/cluster/topology/single.rb +2 -2
  18. data/lib/mongo/collection.rb +66 -24
  19. data/lib/mongo/collection/view.rb +24 -20
  20. data/lib/mongo/collection/view/aggregation.rb +25 -4
  21. data/lib/mongo/collection/view/builder/find_command.rb +38 -18
  22. data/lib/mongo/collection/view/explainable.rb +27 -8
  23. data/lib/mongo/collection/view/iterable.rb +72 -12
  24. data/lib/mongo/collection/view/readable.rb +19 -3
  25. data/lib/mongo/collection/view/writable.rb +55 -5
  26. data/lib/mongo/crypt/encryption_io.rb +6 -6
  27. data/lib/mongo/cursor.rb +16 -3
  28. data/lib/mongo/database.rb +37 -4
  29. data/lib/mongo/database/view.rb +18 -3
  30. data/lib/mongo/distinguishing_semaphore.rb +55 -0
  31. data/lib/mongo/error.rb +5 -0
  32. data/lib/mongo/error/invalid_read_concern.rb +28 -0
  33. data/lib/mongo/error/invalid_server_auth_host.rb +22 -0
  34. data/lib/mongo/error/invalid_session.rb +2 -1
  35. data/lib/mongo/error/operation_failure.rb +11 -5
  36. data/lib/mongo/error/server_certificate_revoked.rb +22 -0
  37. data/lib/mongo/error/sessions_not_supported.rb +35 -0
  38. data/lib/mongo/error/unsupported_option.rb +14 -12
  39. data/lib/mongo/event/base.rb +6 -0
  40. data/lib/mongo/grid/file.rb +5 -0
  41. data/lib/mongo/grid/file/chunk.rb +2 -0
  42. data/lib/mongo/grid/fs_bucket.rb +15 -13
  43. data/lib/mongo/grid/stream/write.rb +9 -3
  44. data/lib/mongo/index/view.rb +3 -0
  45. data/lib/mongo/lint.rb +2 -1
  46. data/lib/mongo/logger.rb +3 -3
  47. data/lib/mongo/monitoring.rb +38 -0
  48. data/lib/mongo/monitoring/command_log_subscriber.rb +10 -2
  49. data/lib/mongo/monitoring/event/command_failed.rb +11 -0
  50. data/lib/mongo/monitoring/event/command_started.rb +37 -2
  51. data/lib/mongo/monitoring/event/command_succeeded.rb +11 -0
  52. data/lib/mongo/monitoring/event/server_closed.rb +1 -1
  53. data/lib/mongo/monitoring/event/server_description_changed.rb +27 -4
  54. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +9 -2
  55. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +9 -2
  56. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +9 -2
  57. data/lib/mongo/monitoring/event/server_opening.rb +1 -1
  58. data/lib/mongo/monitoring/event/topology_changed.rb +1 -1
  59. data/lib/mongo/monitoring/event/topology_closed.rb +1 -1
  60. data/lib/mongo/monitoring/event/topology_opening.rb +1 -1
  61. data/lib/mongo/monitoring/publishable.rb +6 -3
  62. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +9 -1
  63. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +1 -1
  64. data/lib/mongo/operation.rb +2 -0
  65. data/lib/mongo/operation/aggregate/result.rb +9 -8
  66. data/lib/mongo/operation/collections_info/command.rb +5 -0
  67. data/lib/mongo/operation/collections_info/result.rb +18 -1
  68. data/lib/mongo/operation/delete/bulk_result.rb +2 -0
  69. data/lib/mongo/operation/delete/result.rb +3 -0
  70. data/lib/mongo/operation/explain/command.rb +4 -0
  71. data/lib/mongo/operation/explain/legacy.rb +4 -0
  72. data/lib/mongo/operation/explain/op_msg.rb +6 -0
  73. data/lib/mongo/operation/explain/result.rb +3 -0
  74. data/lib/mongo/operation/find/legacy/result.rb +2 -0
  75. data/lib/mongo/operation/find/result.rb +13 -0
  76. data/lib/mongo/operation/get_more/result.rb +3 -0
  77. data/lib/mongo/operation/indexes/result.rb +5 -0
  78. data/lib/mongo/operation/insert/bulk_result.rb +5 -0
  79. data/lib/mongo/operation/insert/result.rb +5 -0
  80. data/lib/mongo/operation/list_collections/result.rb +5 -0
  81. data/lib/mongo/operation/map_reduce/result.rb +10 -0
  82. data/lib/mongo/operation/parallel_scan/result.rb +4 -0
  83. data/lib/mongo/operation/result.rb +35 -6
  84. data/lib/mongo/operation/shared/bypass_document_validation.rb +1 -0
  85. data/lib/mongo/operation/shared/causal_consistency_supported.rb +1 -0
  86. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +2 -0
  87. data/lib/mongo/operation/shared/executable.rb +1 -0
  88. data/lib/mongo/operation/shared/idable.rb +2 -1
  89. data/lib/mongo/operation/shared/limited.rb +1 -0
  90. data/lib/mongo/operation/shared/object_id_generator.rb +1 -0
  91. data/lib/mongo/operation/shared/result/aggregatable.rb +1 -0
  92. data/lib/mongo/operation/shared/sessions_supported.rb +1 -0
  93. data/lib/mongo/operation/shared/specifiable.rb +1 -0
  94. data/lib/mongo/operation/shared/write.rb +1 -0
  95. data/lib/mongo/operation/shared/write_concern_supported.rb +1 -0
  96. data/lib/mongo/operation/update/legacy/result.rb +7 -0
  97. data/lib/mongo/operation/update/result.rb +8 -0
  98. data/lib/mongo/operation/users_info/result.rb +3 -0
  99. data/lib/mongo/protocol/message.rb +47 -10
  100. data/lib/mongo/protocol/msg.rb +34 -1
  101. data/lib/mongo/protocol/query.rb +36 -0
  102. data/lib/mongo/protocol/serializers.rb +5 -2
  103. data/lib/mongo/query_cache.rb +242 -0
  104. data/lib/mongo/retryable.rb +8 -1
  105. data/lib/mongo/server.rb +15 -4
  106. data/lib/mongo/server/app_metadata.rb +27 -3
  107. data/lib/mongo/server/connection.rb +4 -4
  108. data/lib/mongo/server/connection_base.rb +38 -12
  109. data/lib/mongo/server/connection_common.rb +2 -2
  110. data/lib/mongo/server/connection_pool.rb +3 -0
  111. data/lib/mongo/server/description.rb +13 -1
  112. data/lib/mongo/server/monitor.rb +76 -44
  113. data/lib/mongo/server/monitor/connection.rb +57 -9
  114. data/lib/mongo/server/pending_connection.rb +14 -4
  115. data/lib/mongo/server/push_monitor.rb +173 -0
  116. data/{spec/runners/transactions/context.rb → lib/mongo/server/push_monitor/connection.rb} +9 -14
  117. data/lib/mongo/server_selector.rb +0 -1
  118. data/lib/mongo/server_selector/base.rb +583 -1
  119. data/lib/mongo/server_selector/nearest.rb +1 -6
  120. data/lib/mongo/server_selector/primary.rb +1 -6
  121. data/lib/mongo/server_selector/primary_preferred.rb +7 -10
  122. data/lib/mongo/server_selector/secondary.rb +1 -6
  123. data/lib/mongo/server_selector/secondary_preferred.rb +1 -7
  124. data/lib/mongo/session.rb +7 -1
  125. data/lib/mongo/socket.rb +26 -12
  126. data/lib/mongo/socket/ocsp_cache.rb +97 -0
  127. data/lib/mongo/socket/ocsp_verifier.rb +368 -0
  128. data/lib/mongo/socket/ssl.rb +46 -25
  129. data/lib/mongo/socket/tcp.rb +1 -1
  130. data/lib/mongo/srv/monitor.rb +7 -13
  131. data/lib/mongo/srv/resolver.rb +14 -10
  132. data/lib/mongo/timeout.rb +2 -0
  133. data/lib/mongo/topology_version.rb +9 -0
  134. data/lib/mongo/uri.rb +21 -390
  135. data/lib/mongo/uri/options_mapper.rb +582 -0
  136. data/lib/mongo/uri/srv_protocol.rb +3 -2
  137. data/lib/mongo/utils.rb +73 -0
  138. data/lib/mongo/version.rb +1 -1
  139. data/spec/NOTES.aws-auth.md +12 -7
  140. data/spec/README.aws-auth.md +2 -2
  141. data/spec/README.md +63 -1
  142. data/spec/integration/awaited_ismaster_spec.rb +28 -0
  143. data/spec/integration/bson_symbol_spec.rb +4 -2
  144. data/spec/integration/bulk_write_spec.rb +67 -0
  145. data/spec/integration/change_stream_examples_spec.rb +6 -2
  146. data/spec/integration/change_stream_spec.rb +1 -1
  147. data/spec/integration/check_clean_slate_spec.rb +16 -0
  148. data/spec/integration/client_authentication_options_spec.rb +92 -28
  149. data/spec/integration/client_construction_spec.rb +1 -0
  150. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +9 -5
  151. data/spec/integration/connect_single_rs_name_spec.rb +5 -2
  152. data/spec/integration/connection_pool_populator_spec.rb +4 -2
  153. data/spec/integration/connection_spec.rb +7 -4
  154. data/spec/integration/crud_spec.rb +4 -4
  155. data/spec/integration/cursor_reaping_spec.rb +54 -18
  156. data/spec/integration/docs_examples_spec.rb +6 -0
  157. data/spec/integration/fork_reconnect_spec.rb +56 -1
  158. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  159. data/spec/integration/heartbeat_events_spec.rb +4 -23
  160. data/spec/integration/ocsp_connectivity_spec.rb +26 -0
  161. data/spec/integration/ocsp_verifier_cache_spec.rb +188 -0
  162. data/spec/integration/ocsp_verifier_spec.rb +334 -0
  163. data/spec/integration/query_cache_spec.rb +1045 -0
  164. data/spec/integration/query_cache_transactions_spec.rb +190 -0
  165. data/spec/integration/read_concern_spec.rb +1 -1
  166. data/spec/integration/retryable_errors_spec.rb +1 -1
  167. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -0
  168. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +4 -2
  169. data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +3 -3
  170. data/spec/integration/retryable_writes/shared/performs_no_retries.rb +2 -2
  171. data/spec/integration/sdam_error_handling_spec.rb +122 -15
  172. data/spec/integration/sdam_events_spec.rb +80 -6
  173. data/spec/integration/sdam_prose_spec.rb +64 -0
  174. data/spec/integration/server_monitor_spec.rb +25 -1
  175. data/spec/integration/server_selection_spec.rb +36 -0
  176. data/spec/integration/size_limit_spec.rb +23 -5
  177. data/spec/integration/srv_monitoring_spec.rb +38 -3
  178. data/spec/integration/srv_spec.rb +56 -0
  179. data/spec/integration/ssl_uri_options_spec.rb +2 -2
  180. data/spec/integration/transactions_examples_spec.rb +17 -7
  181. data/spec/integration/zlib_compression_spec.rb +25 -0
  182. data/spec/lite_spec_helper.rb +20 -9
  183. data/spec/mongo/address_spec.rb +1 -1
  184. data/spec/mongo/auth/aws/request_region_spec.rb +42 -0
  185. data/spec/mongo/auth/aws/request_spec.rb +76 -0
  186. data/spec/mongo/auth/scram_spec.rb +1 -1
  187. data/spec/mongo/auth/user_spec.rb +1 -1
  188. data/spec/mongo/bulk_write_spec.rb +2 -2
  189. data/spec/mongo/caching_cursor_spec.rb +70 -0
  190. data/spec/mongo/client_construction_spec.rb +386 -3
  191. data/spec/mongo/client_encryption_spec.rb +16 -10
  192. data/spec/mongo/client_spec.rb +85 -3
  193. data/spec/mongo/cluster/topology/replica_set_spec.rb +53 -10
  194. data/spec/mongo/cluster/topology/sharded_spec.rb +1 -1
  195. data/spec/mongo/cluster/topology/single_spec.rb +19 -8
  196. data/spec/mongo/cluster/topology/unknown_spec.rb +1 -1
  197. data/spec/mongo/cluster/topology_spec.rb +1 -1
  198. data/spec/mongo/cluster_spec.rb +37 -35
  199. data/spec/mongo/collection/view/change_stream_resume_spec.rb +7 -7
  200. data/spec/mongo/collection/view/explainable_spec.rb +87 -4
  201. data/spec/mongo/collection/view/map_reduce_spec.rb +2 -0
  202. data/spec/mongo/collection/view/readable_spec.rb +36 -0
  203. data/spec/mongo/collection_spec.rb +572 -0
  204. data/spec/mongo/crypt/auto_decryption_context_spec.rb +1 -1
  205. data/spec/mongo/crypt/auto_encryption_context_spec.rb +1 -1
  206. data/spec/mongo/crypt/binary_spec.rb +1 -6
  207. data/spec/mongo/crypt/binding/binary_spec.rb +1 -6
  208. data/spec/mongo/crypt/binding/context_spec.rb +2 -7
  209. data/spec/mongo/crypt/binding/helpers_spec.rb +1 -6
  210. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +2 -7
  211. data/spec/mongo/crypt/binding/status_spec.rb +1 -6
  212. data/spec/mongo/crypt/binding/version_spec.rb +1 -6
  213. data/spec/mongo/crypt/data_key_context_spec.rb +1 -1
  214. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +1 -1
  215. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +1 -1
  216. data/spec/mongo/crypt/status_spec.rb +1 -6
  217. data/spec/mongo/database_spec.rb +353 -8
  218. data/spec/mongo/distinguishing_semaphore_spec.rb +63 -0
  219. data/spec/mongo/error/no_server_available_spec.rb +1 -1
  220. data/spec/mongo/error/operation_failure_spec.rb +40 -0
  221. data/spec/mongo/index/view_spec.rb +148 -2
  222. data/spec/mongo/logger_spec.rb +13 -11
  223. data/spec/mongo/monitoring/event/server_closed_spec.rb +1 -1
  224. data/spec/mongo/monitoring/event/server_description_changed_spec.rb +1 -4
  225. data/spec/mongo/monitoring/event/server_opening_spec.rb +1 -1
  226. data/spec/mongo/monitoring/event/topology_changed_spec.rb +1 -1
  227. data/spec/mongo/monitoring/event/topology_closed_spec.rb +1 -1
  228. data/spec/mongo/monitoring/event/topology_opening_spec.rb +1 -1
  229. data/spec/mongo/operation/delete/op_msg_spec.rb +3 -3
  230. data/spec/mongo/operation/insert/command_spec.rb +2 -2
  231. data/spec/mongo/operation/insert/op_msg_spec.rb +3 -3
  232. data/spec/mongo/operation/read_preference_op_msg_spec.rb +1 -1
  233. data/spec/mongo/operation/update/command_spec.rb +2 -2
  234. data/spec/mongo/operation/update/op_msg_spec.rb +3 -3
  235. data/spec/mongo/protocol/msg_spec.rb +10 -0
  236. data/spec/mongo/query_cache_spec.rb +280 -0
  237. data/spec/mongo/semaphore_spec.rb +51 -0
  238. data/spec/mongo/server/app_metadata_shared.rb +82 -2
  239. data/spec/mongo/server/connection_auth_spec.rb +2 -2
  240. data/spec/mongo/server/connection_pool_spec.rb +7 -3
  241. data/spec/mongo/server/connection_spec.rb +15 -8
  242. data/spec/mongo/server/description_spec.rb +18 -0
  243. data/spec/mongo/server_selector/nearest_spec.rb +23 -23
  244. data/spec/mongo/server_selector/primary_preferred_spec.rb +26 -26
  245. data/spec/mongo/server_selector/primary_spec.rb +9 -9
  246. data/spec/mongo/server_selector/secondary_preferred_spec.rb +22 -22
  247. data/spec/mongo/server_selector/secondary_spec.rb +18 -18
  248. data/spec/mongo/server_selector_spec.rb +6 -6
  249. data/spec/mongo/session_spec.rb +35 -0
  250. data/spec/mongo/socket/ssl_spec.rb +4 -4
  251. data/spec/mongo/socket_spec.rb +1 -1
  252. data/spec/mongo/uri/srv_protocol_spec.rb +64 -33
  253. data/spec/mongo/uri_option_parsing_spec.rb +11 -11
  254. data/spec/mongo/uri_spec.rb +68 -41
  255. data/spec/mongo/utils_spec.rb +39 -0
  256. data/spec/runners/auth.rb +3 -0
  257. data/spec/runners/change_streams/test.rb +3 -3
  258. data/spec/runners/cmap.rb +1 -1
  259. data/spec/runners/command_monitoring.rb +3 -34
  260. data/spec/runners/connection_string.rb +35 -124
  261. data/spec/runners/crud/context.rb +9 -5
  262. data/spec/runners/crud/operation.rb +59 -27
  263. data/spec/runners/crud/spec.rb +0 -8
  264. data/spec/runners/crud/test.rb +1 -1
  265. data/spec/runners/crud/test_base.rb +0 -19
  266. data/spec/runners/sdam.rb +2 -2
  267. data/spec/runners/server_selection.rb +242 -28
  268. data/spec/runners/transactions.rb +12 -12
  269. data/spec/runners/transactions/operation.rb +151 -25
  270. data/spec/runners/transactions/test.rb +62 -18
  271. data/spec/shared/LICENSE +20 -0
  272. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  273. data/spec/shared/lib/mrss/constraints.rb +303 -0
  274. data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
  275. data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
  276. data/spec/spec_helper.rb +3 -1
  277. data/spec/spec_tests/cmap_spec.rb +7 -3
  278. data/spec/spec_tests/command_monitoring_spec.rb +22 -12
  279. data/spec/spec_tests/crud_spec.rb +1 -1
  280. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +4 -9
  281. data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +66 -0
  282. data/spec/spec_tests/data/change_streams/change-streams.yml +0 -1
  283. data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +6 -2
  284. data/spec/spec_tests/data/cmap/pool-create-min-size.yml +3 -0
  285. data/spec/spec_tests/data/connection_string/valid-warnings.yml +24 -0
  286. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.yml +15 -0
  287. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +4 -3
  288. data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -0
  289. data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +96 -0
  290. data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +88 -0
  291. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +83 -0
  292. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +116 -0
  293. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +86 -0
  294. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +115 -0
  295. data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +168 -0
  296. data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +162 -0
  297. data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +229 -0
  298. data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +87 -0
  299. data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +1 -3
  300. data/spec/spec_tests/data/sdam_monitoring/standalone.yml +2 -2
  301. data/spec/spec_tests/data/sdam_monitoring/standalone_repeated.yml +2 -2
  302. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +2 -2
  303. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +2 -2
  304. data/spec/spec_tests/data/uri_options/auth-options.yml +25 -0
  305. data/spec/spec_tests/data/uri_options/compression-options.yml +6 -3
  306. data/spec/spec_tests/data/uri_options/read-preference-options.yml +24 -0
  307. data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +1 -0
  308. data/spec/spec_tests/data/uri_options/tls-options.yml +160 -4
  309. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +9 -1
  310. data/spec/spec_tests/max_staleness_spec.rb +4 -142
  311. data/spec/spec_tests/retryable_reads_spec.rb +2 -2
  312. data/spec/spec_tests/sdam_integration_spec.rb +13 -0
  313. data/spec/spec_tests/sdam_monitoring_spec.rb +1 -2
  314. data/spec/spec_tests/server_selection_spec.rb +4 -116
  315. data/spec/spec_tests/uri_options_spec.rb +31 -33
  316. data/spec/stress/cleanup_spec.rb +17 -2
  317. data/spec/stress/connection_pool_stress_spec.rb +10 -8
  318. data/spec/stress/fork_reconnect_stress_spec.rb +1 -1
  319. data/spec/support/certificates/atlas-ocsp-ca.crt +28 -0
  320. data/spec/support/certificates/atlas-ocsp.crt +41 -0
  321. data/spec/support/client_registry.rb +1 -0
  322. data/spec/support/client_registry_macros.rb +11 -2
  323. data/spec/support/cluster_config.rb +4 -0
  324. data/spec/support/common_shortcuts.rb +45 -0
  325. data/spec/support/constraints.rb +6 -253
  326. data/spec/support/event_subscriber.rb +123 -33
  327. data/spec/support/keyword_struct.rb +26 -0
  328. data/spec/support/matchers.rb +16 -0
  329. data/spec/support/ocsp +1 -0
  330. data/spec/support/session_registry.rb +52 -0
  331. data/spec/support/shared/server_selector.rb +13 -1
  332. data/spec/support/spec_config.rb +60 -13
  333. data/spec/support/spec_setup.rb +1 -1
  334. data/spec/support/utils.rb +84 -1
  335. metadata +1027 -937
  336. metadata.gz.sig +0 -0
  337. data/lib/mongo/server_selector/selectable.rb +0 -560
  338. data/spec/runners/sdam_monitoring.rb +0 -89
  339. data/spec/support/lite_constraints.rb +0 -141
metadata.gz.sig CHANGED
Binary file
@@ -1,560 +0,0 @@
1
- # Copyright (C) 2014-2020 MongoDB Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- module Mongo
16
- module ServerSelector
17
-
18
- # Provides common behavior for filtering a list of servers by server mode or tag set.
19
- #
20
- # @since 2.0.0
21
- module Selectable
22
-
23
- # Initialize the server selector.
24
- #
25
- # @example Initialize the selector.
26
- # Mongo::ServerSelector::Secondary.new(:tag_sets => [{'dc' => 'nyc'}])
27
- #
28
- # @example Initialize the preference with no options.
29
- # Mongo::ServerSelector::Secondary.new
30
- #
31
- # @param [ Hash ] options The server preference options.
32
- #
33
- # @option options [ Integer ] :local_threshold The local threshold boundary for
34
- # nearest selection in seconds.
35
- # @option options [ Integer ] max_staleness The maximum replication lag,
36
- # in seconds, that a secondary can suffer and still be eligible for a read.
37
- # A value of -1 is treated identically to nil, which is to not
38
- # have a maximum staleness.
39
- # @option options [ Hash | nil ] hedge A Hash specifying whether to enable hedged
40
- # reads on the server. Hedged reads are not enabled by default. When
41
- # specifying this option, it must be in the format: { enabled: true },
42
- # where the value of the :enabled key is a boolean value.
43
- #
44
- # @raise [ Error::InvalidServerPreference ] If tag sets are specified
45
- # but not allowed.
46
- #
47
- # @since 2.0.0
48
- def initialize(options = nil)
49
- options = options ? options.dup : {}
50
- if options[:max_staleness] == -1
51
- options.delete(:max_staleness)
52
- end
53
- @options = options
54
- @tag_sets = options[:tag_sets] || []
55
- @max_staleness = options[:max_staleness]
56
- @hedge = options[:hedge]
57
-
58
- validate!
59
- end
60
-
61
- # @return [ Hash ] options The options.
62
- attr_reader :options
63
-
64
- # @return [ Array ] tag_sets The tag sets used to select servers.
65
- attr_reader :tag_sets
66
-
67
- # @return [ Integer ] max_staleness The maximum replication lag, in seconds, that a
68
- # secondary can suffer and still be eligible for a read.
69
- #
70
- # @since 2.4.0
71
- attr_reader :max_staleness
72
-
73
- # @return [ Hash | nil ] hedge The document specifying whether to enable
74
- # hedged reads.
75
- attr_reader :hedge
76
-
77
- # Check equality of two server selector.
78
- #
79
- # @example Check server selector equality.
80
- # preference == other
81
- #
82
- # @param [ Object ] other The other preference.
83
- #
84
- # @return [ true, false ] Whether the objects are equal.
85
- #
86
- # @since 2.0.0
87
- def ==(other)
88
- name == other.name && hedge == other.hedge &&
89
- max_staleness == other.max_staleness && tag_sets == other.tag_sets
90
- end
91
-
92
- # Inspect the server selector.
93
- #
94
- # @example Inspect the server selector.
95
- # selector.inspect
96
- #
97
- # @return [ String ] The inspection.
98
- #
99
- # @since 2.2.0
100
- def inspect
101
- "#<#{self.class.name}:0x#{object_id} tag_sets=#{tag_sets.inspect} max_staleness=#{max_staleness.inspect} hedge=#{hedge}>"
102
- end
103
-
104
- # Select a server from the specified cluster, taking into account
105
- # mongos pinning for the specified session.
106
- #
107
- # If the session is given and has a pinned server, this server is the
108
- # only server considered for selection. If the server is of type mongos,
109
- # it is returned immediately; otherwise monitoring checks on this
110
- # server are initiated to update its status, and if the server becomes
111
- # a mongos within the server selection timeout, it is returned.
112
- #
113
- # If no session is given or the session does not have a pinned server,
114
- # normal server selection process is performed among all servers in the
115
- # specified cluster matching the preference of this server selector
116
- # object. Monitoring checks are initiated on servers in the cluster until
117
- # a suitable server is found, up to the server selection timeout.
118
- #
119
- # If a suitable server is not found within the server selection timeout,
120
- # this method raises Error::NoServerAvailable.
121
- #
122
- # @param [ Mongo::Cluster ] cluster The cluster from which to select
123
- # an eligible server.
124
- # @param [ true, false ] ping Whether to ping the server before selection.
125
- # Deprecated and ignored.
126
- # @param [ Session | nil ] session Optional session to take into account
127
- # for mongos pinning. Added in version 2.10.0.
128
- #
129
- # @return [ Mongo::Server ] A server matching the server preference.
130
- #
131
- # @raise [ Error::NoServerAvailable ] No server was found matching the
132
- # specified preference / pinning requirement in the server selection
133
- # timeout.
134
- # @raise [ Error::LintError ] An unexpected condition was detected, and
135
- # lint mode is enabled.
136
- #
137
- # @since 2.0.0
138
- def select_server(cluster, ping = nil, session = nil)
139
- server_selection_timeout = cluster.options[:server_selection_timeout] || SERVER_SELECTION_TIMEOUT
140
-
141
- # Special handling for zero timeout: if we have to select a server,
142
- # and the timeout is zero, fail immediately (since server selection
143
- # will take some non-zero amount of time in any case).
144
- if server_selection_timeout == 0
145
- msg = "Failing server selection due to zero timeout. " +
146
- " Requested #{name} in cluster: #{cluster.summary}"
147
- raise Error::NoServerAvailable.new(self, cluster, msg)
148
- end
149
-
150
- deadline = Time.now + server_selection_timeout
151
-
152
- if session && session.pinned_server
153
- if Mongo::Lint.enabled?
154
- unless cluster.sharded?
155
- raise Error::LintError, "Session has a pinned server in a non-sharded topology: #{topology}"
156
- end
157
- end
158
-
159
- if !session.in_transaction?
160
- session.unpin
161
- end
162
-
163
- if server = session.pinned_server
164
- # Here we assume that a mongos stays in the topology indefinitely.
165
- # This will no longer be the case once SRV polling is implemented.
166
-
167
- unless server.mongos?
168
- while (time_remaining = deadline - Time.now) > 0
169
- wait_for_server_selection(cluster, time_remaining)
170
- end
171
-
172
- unless server.mongos?
173
- msg = "The session being used is pinned to the server which is not a mongos: #{server.summary} " +
174
- "(after #{server_selection_timeout} seconds)"
175
- raise Error::NoServerAvailable.new(self, cluster, msg)
176
- end
177
- end
178
-
179
- return server
180
- end
181
- end
182
-
183
- if cluster.replica_set?
184
- validate_max_staleness_value_early!
185
- end
186
- if cluster.addresses.empty?
187
- if Lint.enabled?
188
- unless cluster.servers.empty?
189
- raise Error::LintError, "Cluster has no addresses but has servers: #{cluster.servers.map(&:inspect).join(', ')}"
190
- end
191
- end
192
- msg = "Cluster has no addresses, and therefore will never have a server"
193
- raise Error::NoServerAvailable.new(self, cluster, msg)
194
- end
195
- =begin Add this check in version 3.0.0
196
- unless cluster.connected?
197
- msg = 'Cluster is disconnected'
198
- raise Error::NoServerAvailable.new(self, cluster, msg)
199
- end
200
- =end
201
- loop do
202
- servers = candidates(cluster)
203
- if Lint.enabled?
204
- servers.each do |server|
205
- # It is possible for a server to have a nil average RTT here
206
- # because the ARTT comes from description which may be updated
207
- # by a background thread while server selection is running.
208
- # Currently lint mode is not a public feature, if/when this
209
- # changes (https://jira.mongodb.org/browse/RUBY-1576) the
210
- # requirement for ARTT to be not nil would need to be removed.
211
- if server.average_round_trip_time.nil?
212
- raise Error::LintError, "Server #{server.address} has nil average rtt"
213
- end
214
- end
215
- end
216
- if servers && !servers.compact.empty?
217
- unless cluster.topology.compatible?
218
- raise Error::UnsupportedFeatures, cluster.topology.compatibility_error.to_s
219
- end
220
-
221
- # This list of servers may be ordered in a specific way
222
- # by the selector (e.g. for secondary preferred, the first
223
- # server may be a secondary and the second server may be primary)
224
- # and we should take the first server here respecting the order
225
- server = servers.first
226
-
227
- if session && session.starting_transaction? && cluster.sharded?
228
- session.pin(server)
229
- end
230
-
231
- return server
232
- end
233
-
234
- cluster.scan!(false)
235
-
236
- time_remaining = deadline - Time.now
237
- if time_remaining > 0
238
- wait_for_server_selection(cluster, time_remaining)
239
-
240
- # If we wait for server selection, perform another round of
241
- # attempting to locate a suitable server. Otherwise server selection
242
- # can raise NoServerAvailable message when the diagnostics
243
- # reports an available server of the requested type.
244
- else
245
- break
246
- end
247
- end
248
-
249
- msg = "No #{name} server is available in cluster: #{cluster.summary} " +
250
- "with timeout=#{server_selection_timeout}, " +
251
- "LT=#{local_threshold_with_cluster(cluster)}"
252
- msg += server_selection_diagnostic_message(cluster)
253
- raise Error::NoServerAvailable.new(self, cluster, msg)
254
- rescue Error::NoServerAvailable => e
255
- if session && session.in_transaction? && !session.committing_transaction?
256
- e.add_label('TransientTransactionError')
257
- end
258
- if session && session.committing_transaction?
259
- e.add_label('UnknownTransactionCommitResult')
260
- end
261
- raise e
262
- end
263
-
264
- # Get the timeout for server selection.
265
- #
266
- # @example Get the server selection timeout, in seconds.
267
- # selector.server_selection_timeout
268
- #
269
- # @return [ Float ] The timeout.
270
- #
271
- # @since 2.0.0
272
- #
273
- # @deprecated This setting is now taken from the cluster options when a server is selected.
274
- # Will be removed in 3.0.
275
- def server_selection_timeout
276
- @server_selection_timeout ||=
277
- (options[:server_selection_timeout] || ServerSelector::SERVER_SELECTION_TIMEOUT)
278
- end
279
-
280
- def local_threshold_with_cluster(cluster)
281
- options[:local_threshold] || cluster.options[:local_threshold] || LOCAL_THRESHOLD
282
- end
283
-
284
- # Get the local threshold boundary for nearest selection in seconds.
285
- #
286
- # @example Get the local threshold.
287
- # selector.local_threshold
288
- #
289
- # @return [ Float ] The local threshold.
290
- #
291
- # @since 2.0.0
292
- #
293
- # @deprecated This setting is now taken from the cluster options when a server is selected.
294
- # Will be removed in 3.0.
295
- def local_threshold
296
- @local_threshold ||= (options[:local_threshold] || ServerSelector::LOCAL_THRESHOLD)
297
- end
298
-
299
- # Get the potential candidates to select from the cluster.
300
- #
301
- # @example Get the server candidates.
302
- # selectable.candidates(cluster)
303
- #
304
- # @param [ Cluster ] cluster The cluster.
305
- #
306
- # @return [ Array<Server> ] The candidate servers.
307
- #
308
- # @since 2.4.0
309
- def candidates(cluster)
310
- if cluster.single?
311
- cluster.servers.each { |server| validate_max_staleness_support!(server) }
312
- elsif cluster.sharded?
313
- local_threshold = local_threshold_with_cluster(cluster)
314
- near_servers(cluster.servers, local_threshold).each do |server|
315
- validate_max_staleness_support!(server)
316
- end
317
- else
318
- validate_max_staleness_value!(cluster) unless cluster.unknown?
319
- select(cluster.servers)
320
- end
321
- end
322
-
323
- private
324
-
325
- # Select the primary from a list of provided candidates.
326
- #
327
- # @param [ Array ] candidates List of candidate servers to select the
328
- # primary from.
329
- #
330
- # @return [ Array ] The primary.
331
- #
332
- # @since 2.0.0
333
- def primary(candidates)
334
- candidates.select do |server|
335
- server.primary?
336
- end
337
- end
338
-
339
- # Select the secondaries from a list of provided candidates.
340
- #
341
- # @param [ Array ] candidates List of candidate servers to select the
342
- # secondaries from.
343
- #
344
- # @return [ Array ] The secondary servers.
345
- #
346
- # @since 2.0.0
347
- def secondaries(candidates)
348
- matching_servers = candidates.select(&:secondary?)
349
- matching_servers = filter_stale_servers(matching_servers, primary(candidates).first)
350
- matching_servers = match_tag_sets(matching_servers) unless tag_sets.empty?
351
- # Per server selection spec the server selected MUST be a random
352
- # one matching staleness and latency requirements.
353
- # Selectors always pass the output of #secondaries to #nearest
354
- # which shuffles the server list, fulfilling this requirement.
355
- matching_servers
356
- end
357
-
358
- # Select the near servers from a list of provided candidates, taking the
359
- # local threshold into account.
360
- #
361
- # @param [ Array ] candidates List of candidate servers to select the
362
- # near servers from.
363
- # @param [ Integer ] local_threshold Local threshold. This parameter
364
- # will be required in driver version 3.0.
365
- #
366
- # @return [ Array ] The near servers.
367
- #
368
- # @since 2.0.0
369
- def near_servers(candidates = [], local_threshold = nil)
370
- return candidates if candidates.empty?
371
-
372
- # Average RTT on any server may change at any time by the server
373
- # monitor's background thread. ARTT may also become nil if the
374
- # server is marked unknown. Take a snapshot of ARTTs for the duration
375
- # of this method.
376
-
377
- candidates = candidates.map do |server|
378
- {server: server, artt: server.average_round_trip_time}
379
- end.reject do |candidate|
380
- candidate[:artt].nil?
381
- end
382
-
383
- return candidates if candidates.empty?
384
-
385
- nearest_candidate = candidates.min_by do |candidate|
386
- candidate[:artt]
387
- end
388
-
389
- # Default for legacy signarure
390
- local_threshold ||= self.local_threshold
391
-
392
- threshold = nearest_candidate[:artt] + local_threshold
393
-
394
- candidates.select do |candidate|
395
- candidate[:artt] <= threshold
396
- end.map do |candidate|
397
- candidate[:server]
398
- end.shuffle!
399
- end
400
-
401
- # Select the servers matching the defined tag sets.
402
- #
403
- # @param [ Array ] candidates List of candidate servers from which those
404
- # matching the defined tag sets should be selected.
405
- #
406
- # @return [ Array ] The servers matching the defined tag sets.
407
- #
408
- # @since 2.0.0
409
- def match_tag_sets(candidates)
410
- matches = []
411
- tag_sets.find do |tag_set|
412
- matches = candidates.select { |server| server.matches_tag_set?(tag_set) }
413
- !matches.empty?
414
- end
415
- matches || []
416
- end
417
-
418
- def filter_stale_servers(candidates, primary = nil)
419
- return candidates unless @max_staleness
420
-
421
- # last_scan is filled out by the Monitor, and can be nil if a server
422
- # had its description manually set rather than being normally updated
423
- # via the SDAM flow. We don't handle the possibility of a nil
424
- # last_scan here.
425
- if primary
426
- candidates.select do |server|
427
- validate_max_staleness_support!(server)
428
- staleness = (server.last_scan - server.last_write_date) -
429
- (primary.last_scan - primary.last_write_date) +
430
- server.cluster.heartbeat_interval
431
- staleness <= @max_staleness
432
- end
433
- else
434
- max_write_date = candidates.collect(&:last_write_date).max
435
- candidates.select do |server|
436
- validate_max_staleness_support!(server)
437
- staleness = max_write_date - server.last_write_date + server.cluster.heartbeat_interval
438
- staleness <= @max_staleness
439
- end
440
- end
441
- end
442
-
443
- def validate!
444
- if !@tag_sets.all? { |set| set.empty? } && !tags_allowed?
445
- raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_TAG_SUPPORT)
446
- elsif @max_staleness && !max_staleness_allowed?
447
- raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_MAX_STALENESS_SUPPORT)
448
- end
449
-
450
- if @hedge
451
- unless hedge_allowed?
452
- raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_HEDGE_SUPPORT)
453
- end
454
-
455
- unless @hedge.is_a?(Hash) && @hedge.key?(:enabled) &&
456
- [true, false].include?(@hedge[:enabled])
457
- raise Error::InvalidServerPreference.new(
458
- "`hedge` value (#{hedge}) is invalid - hedge must be a Hash in the " \
459
- "format { enabled: true }"
460
- )
461
- end
462
- end
463
- end
464
-
465
- def validate_max_staleness_support!(server)
466
- if @max_staleness && !server.features.max_staleness_enabled?
467
- raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_MAX_STALENESS_WITH_LEGACY_SERVER)
468
- end
469
- end
470
-
471
- def validate_max_staleness_value_early!
472
- if @max_staleness
473
- unless @max_staleness >= SMALLEST_MAX_STALENESS_SECONDS
474
- msg = "`max_staleness` value (#{@max_staleness}) is too small - it must be at least " +
475
- "`Mongo::ServerSelector::SMALLEST_MAX_STALENESS_SECONDS` (#{ServerSelector::SMALLEST_MAX_STALENESS_SECONDS})"
476
- raise Error::InvalidServerPreference.new(msg)
477
- end
478
- end
479
- end
480
-
481
- def validate_max_staleness_value!(cluster)
482
- if @max_staleness
483
- heartbeat_interval = cluster.heartbeat_interval
484
- unless @max_staleness >= [
485
- SMALLEST_MAX_STALENESS_SECONDS,
486
- min_cluster_staleness = heartbeat_interval + Cluster::IDLE_WRITE_PERIOD_SECONDS,
487
- ].max
488
- msg = "`max_staleness` value (#{@max_staleness}) is too small - it must be at least " +
489
- "`Mongo::ServerSelector::SMALLEST_MAX_STALENESS_SECONDS` (#{ServerSelector::SMALLEST_MAX_STALENESS_SECONDS}) and (the cluster's heartbeat_frequency " +
490
- "setting + `Mongo::Cluster::IDLE_WRITE_PERIOD_SECONDS`) (#{min_cluster_staleness})"
491
- raise Error::InvalidServerPreference.new(msg)
492
- end
493
- end
494
- end
495
-
496
- # Waits for server state changes in the specified cluster.
497
- #
498
- # If the cluster has a server selection semaphore, waits on that
499
- # semaphore up to the specified remaining time. Any change in server
500
- # state resulting from SDAM will immediately wake up this method and
501
- # cause it to return.
502
- #
503
- # If the cluster des not have a server selection semaphore, waits
504
- # the smaller of 0.25 seconds and the specified remaining time.
505
- # This functionality is provided for backwards compatibilty only for
506
- # applications directly invoking the server selection process.
507
- # If lint mode is enabled and the cluster does not have a server
508
- # selection semaphore, Error::LintError will be raised.
509
- #
510
- # @param [ Cluster ] cluster The cluster to wait for.
511
- # @param [ Numeric ] time_remaining Maximum time to wait, in seconds.
512
- def wait_for_server_selection(cluster, time_remaining)
513
- if cluster.server_selection_semaphore
514
- # Since the semaphore may have been signaled between us checking
515
- # the servers list earlier and the wait call below, we should not
516
- # wait for the full remaining time - wait for up to 1 second, then
517
- # recheck the state.
518
- cluster.server_selection_semaphore.wait([time_remaining, 1].min)
519
- else
520
- if Lint.enabled?
521
- raise Error::LintError, 'Waiting for server selection without having a server selection semaphore'
522
- end
523
- sleep [time_remaining, 0.25].min
524
- end
525
- end
526
-
527
- # Creates a diagnostic message when server selection fails.
528
- #
529
- # The diagnostic message includes the following information, as applicable:
530
- #
531
- # - Servers having dead monitor threads
532
- # - Cluster is disconnected
533
- #
534
- # If none of the conditions for diagnostic messages apply, an empty string
535
- # is returned.
536
- #
537
- # @param [ Cluster ] cluster The cluster on which server selection was
538
- # performed.
539
- #
540
- # @return [ String ] The diagnostic message.
541
- def server_selection_diagnostic_message(cluster)
542
- msg = ''
543
- dead_monitors = []
544
- cluster.servers_list.each do |server|
545
- thread = server.monitor.instance_variable_get('@thread')
546
- if thread.nil? || !thread.alive?
547
- dead_monitors << server
548
- end
549
- end
550
- if dead_monitors.any?
551
- msg += ". The following servers have dead monitor threads: #{dead_monitors.map(&:summary).join(', ')}"
552
- end
553
- unless cluster.connected?
554
- msg += ". The cluster is disconnected (client may have been closed)"
555
- end
556
- msg
557
- end
558
- end
559
- end
560
- end