mongo 2.20.1 → 2.21.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 (246) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/Rakefile +2 -2
  4. data/lib/mongo/address.rb +22 -3
  5. data/lib/mongo/auth/aws/credentials_retriever.rb +70 -17
  6. data/lib/mongo/auth/base.rb +1 -1
  7. data/lib/mongo/bulk_write.rb +35 -2
  8. data/lib/mongo/client.rb +38 -6
  9. data/lib/mongo/client_encryption.rb +6 -3
  10. data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -1
  11. data/lib/mongo/cluster/sdam_flow.rb +20 -7
  12. data/lib/mongo/cluster.rb +14 -4
  13. data/lib/mongo/collection/helpers.rb +1 -1
  14. data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
  15. data/lib/mongo/collection/view/aggregation.rb +33 -99
  16. data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
  17. data/lib/mongo/collection/view/change_stream.rb +80 -27
  18. data/lib/mongo/collection/view/iterable.rb +76 -60
  19. data/lib/mongo/collection/view/map_reduce.rb +25 -8
  20. data/lib/mongo/collection/view/readable.rb +79 -30
  21. data/lib/mongo/collection/view/writable.rb +109 -48
  22. data/lib/mongo/collection/view.rb +43 -3
  23. data/lib/mongo/collection.rb +158 -23
  24. data/lib/mongo/crypt/auto_encrypter.rb +4 -6
  25. data/lib/mongo/crypt/binding.rb +4 -4
  26. data/lib/mongo/crypt/context.rb +20 -14
  27. data/lib/mongo/crypt/encryption_io.rb +56 -26
  28. data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
  29. data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
  30. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
  31. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
  32. data/lib/mongo/csot_timeout_holder.rb +119 -0
  33. data/lib/mongo/cursor/kill_spec.rb +5 -2
  34. data/lib/mongo/cursor/nontailable.rb +27 -0
  35. data/lib/mongo/cursor.rb +86 -24
  36. data/lib/mongo/cursor_host.rb +82 -0
  37. data/lib/mongo/database/view.rb +81 -14
  38. data/lib/mongo/database.rb +88 -18
  39. data/lib/mongo/error/operation_failure.rb +209 -204
  40. data/lib/mongo/error/server_timeout_error.rb +12 -0
  41. data/lib/mongo/error/socket_timeout_error.rb +3 -1
  42. data/lib/mongo/error/timeout_error.rb +23 -0
  43. data/lib/mongo/error.rb +2 -0
  44. data/lib/mongo/grid/fs_bucket.rb +45 -12
  45. data/lib/mongo/grid/stream/read.rb +15 -1
  46. data/lib/mongo/grid/stream/write.rb +21 -4
  47. data/lib/mongo/index/view.rb +77 -16
  48. data/lib/mongo/operation/context.rb +40 -2
  49. data/lib/mongo/operation/create_search_indexes/op_msg.rb +2 -2
  50. data/lib/mongo/operation/delete/op_msg.rb +2 -1
  51. data/lib/mongo/operation/drop_search_index/op_msg.rb +2 -2
  52. data/lib/mongo/operation/find/op_msg.rb +45 -0
  53. data/lib/mongo/operation/get_more/op_msg.rb +33 -0
  54. data/lib/mongo/operation/insert/op_msg.rb +3 -2
  55. data/lib/mongo/operation/insert/result.rb +4 -2
  56. data/lib/mongo/operation/list_collections/result.rb +1 -1
  57. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  58. data/lib/mongo/operation/op_msg_base.rb +3 -1
  59. data/lib/mongo/operation/result.rb +26 -5
  60. data/lib/mongo/operation/shared/executable.rb +12 -1
  61. data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
  62. data/lib/mongo/operation/shared/response_handling.rb +3 -3
  63. data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
  64. data/lib/mongo/operation/shared/timed.rb +52 -0
  65. data/lib/mongo/operation/shared/write.rb +4 -1
  66. data/lib/mongo/operation/update/op_msg.rb +2 -1
  67. data/lib/mongo/operation/update_search_index/op_msg.rb +2 -2
  68. data/lib/mongo/operation.rb +1 -0
  69. data/lib/mongo/protocol/message.rb +1 -4
  70. data/lib/mongo/protocol/msg.rb +2 -2
  71. data/lib/mongo/retryable/read_worker.rb +69 -29
  72. data/lib/mongo/retryable/write_worker.rb +49 -18
  73. data/lib/mongo/retryable.rb +8 -2
  74. data/lib/mongo/server/connection.rb +11 -5
  75. data/lib/mongo/server/connection_base.rb +22 -2
  76. data/lib/mongo/server/connection_pool.rb +32 -14
  77. data/lib/mongo/server/description/features.rb +1 -1
  78. data/lib/mongo/server/description.rb +18 -5
  79. data/lib/mongo/server/monitor.rb +7 -4
  80. data/lib/mongo/server/pending_connection.rb +7 -3
  81. data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
  82. data/lib/mongo/server.rb +11 -6
  83. data/lib/mongo/server_selector/base.rb +25 -9
  84. data/lib/mongo/session.rb +78 -9
  85. data/lib/mongo/socket/ssl.rb +109 -17
  86. data/lib/mongo/socket/tcp.rb +40 -6
  87. data/lib/mongo/socket.rb +154 -25
  88. data/lib/mongo/uri/options_mapper.rb +1 -0
  89. data/lib/mongo/version.rb +1 -1
  90. data/lib/mongo.rb +1 -0
  91. data/spec/atlas/atlas_connectivity_spec.rb +4 -0
  92. data/spec/atlas/operations_spec.rb +4 -0
  93. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
  94. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
  95. data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
  96. data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +66 -22
  97. data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
  98. data/spec/integration/connection_pool_populator_spec.rb +2 -0
  99. data/spec/integration/cursor_pinning_spec.rb +15 -60
  100. data/spec/integration/cursor_reaping_spec.rb +1 -1
  101. data/spec/integration/docs_examples_spec.rb +1 -1
  102. data/spec/integration/operation_failure_code_spec.rb +1 -1
  103. data/spec/integration/operation_failure_message_spec.rb +3 -3
  104. data/spec/integration/retryable_errors_spec.rb +2 -2
  105. data/spec/integration/sdam_error_handling_spec.rb +2 -1
  106. data/spec/integration/search_indexes_prose_spec.rb +4 -0
  107. data/spec/integration/server_spec.rb +4 -3
  108. data/spec/integration/transactions_api_examples_spec.rb +2 -0
  109. data/spec/kerberos/kerberos_spec.rb +4 -0
  110. data/spec/lite_spec_helper.rb +3 -1
  111. data/spec/mongo/auth/user/view_spec.rb +1 -1
  112. data/spec/mongo/caching_cursor_spec.rb +1 -1
  113. data/spec/mongo/client_encryption_spec.rb +1 -0
  114. data/spec/mongo/client_spec.rb +158 -4
  115. data/spec/mongo/collection/view/aggregation_spec.rb +14 -39
  116. data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
  117. data/spec/mongo/collection_spec.rb +5 -6
  118. data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
  119. data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
  120. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
  121. data/spec/mongo/crypt/handle_spec.rb +1 -1
  122. data/spec/mongo/cursor_spec.rb +26 -9
  123. data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
  124. data/spec/mongo/operation/context_spec.rb +79 -0
  125. data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
  126. data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
  127. data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
  128. data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
  129. data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
  130. data/spec/mongo/operation/shared/csot/examples.rb +113 -0
  131. data/spec/mongo/query_cache_spec.rb +243 -225
  132. data/spec/mongo/retryable_spec.rb +1 -0
  133. data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
  134. data/spec/mongo/socket/ssl_spec.rb +0 -10
  135. data/spec/runners/change_streams/test.rb +2 -2
  136. data/spec/runners/crud/operation.rb +1 -1
  137. data/spec/runners/crud/verifier.rb +3 -1
  138. data/spec/runners/transactions/operation.rb +4 -6
  139. data/spec/runners/unified/ambiguous_operations.rb +13 -0
  140. data/spec/runners/unified/assertions.rb +4 -0
  141. data/spec/runners/unified/change_stream_operations.rb +14 -24
  142. data/spec/runners/unified/crud_operations.rb +82 -59
  143. data/spec/runners/unified/ddl_operations.rb +38 -7
  144. data/spec/runners/unified/grid_fs_operations.rb +37 -2
  145. data/spec/runners/unified/support_operations.rb +43 -4
  146. data/spec/runners/unified/test.rb +22 -10
  147. data/spec/runners/unified.rb +1 -1
  148. data/spec/solo/clean_exit_spec.rb +2 -0
  149. data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
  150. data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
  151. data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
  152. data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
  153. data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
  154. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
  155. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
  156. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
  157. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
  158. data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
  159. data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
  160. data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
  161. data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
  162. data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
  163. data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
  164. data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
  165. data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
  166. data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
  167. data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
  168. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
  169. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
  170. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
  171. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
  172. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
  173. data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
  174. data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
  175. data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
  176. data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
  177. data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
  178. data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
  179. data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
  180. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
  181. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
  182. data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
  183. data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
  184. data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +4 -0
  185. data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +4 -0
  186. data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +29 -0
  187. data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
  188. data/spec/support/certificates/atlas-ocsp-ca.crt +81 -83
  189. data/spec/support/certificates/atlas-ocsp.crt +107 -107
  190. data/spec/support/cluster_tools.rb +3 -3
  191. data/spec/support/common_shortcuts.rb +2 -2
  192. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
  193. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
  194. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
  195. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
  196. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
  197. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
  198. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
  199. data/spec/support/shared/session.rb +2 -2
  200. data/spec/support/spec_setup.rb +2 -2
  201. data/spec/support/utils.rb +3 -1
  202. metadata +78 -91
  203. data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
  204. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -242
  205. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -423
  206. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -183
  207. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -240
  208. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -236
  209. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -253
  210. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1688
  211. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -294
  212. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -906
  213. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1685
  214. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1681
  215. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1698
  216. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -330
  217. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -425
  218. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -227
  219. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -328
  220. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -320
  221. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -337
  222. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -914
  223. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -293
  224. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -519
  225. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -912
  226. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -908
  227. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -925
  228. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -326
  229. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -425
  230. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -225
  231. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -324
  232. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -320
  233. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -339
  234. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -242
  235. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -424
  236. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -183
  237. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -240
  238. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -236
  239. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -255
  240. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -242
  241. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -423
  242. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -183
  243. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -240
  244. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -236
  245. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -255
  246. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a641cd6128fd246b0ac9999f00167631548206573a22989968f2a7a132bc0ae
4
- data.tar.gz: d5526d1ca34219ac644191f1e2c7177877c70063cc5a97992379e8e86065d0ca
3
+ metadata.gz: 5e7f3e9918313d274cc9e065268b75d760d24491b959f7b04cdad49dd0ff38f4
4
+ data.tar.gz: 5071ce689f3c0027ce39c93cd662b355235a2b1728f6308c716eecbaa7b55420
5
5
  SHA512:
6
- metadata.gz: 4c23fd9abff5c29517b2cf0c0094bedfbbe667a96f2494b36e6465d8bbfbe113cd08f05e72d15b6db17ef35a211c4aaa040c20dc99eb65417c3c3690b7712c59
7
- data.tar.gz: 54ffbc332168455337aa4de863db0ca179084a35c271e9f21dbfe2425556bd00e02b2fd46a5c2581aa15d5e9a11b84d9a0c231889774adb129f2ad38b997f4f4
6
+ metadata.gz: d8c716a1754d4d2c704a3dd8ed6fcdc5815a0818168598fbe885886f6962f07182333ce8a68ada32cf0bd5d4664d102c301d97e611bac5a126201b6c3e986597
7
+ data.tar.gz: 1365727e6aa93fa15ab46c058f6d3d553a16e8f06b400f915f37c326f9a3393cbf90c6a585a37c8e9a5b9f8e625fcf8443adc487bb0b29b617ffdf71c9991b75
data/README.md CHANGED
@@ -53,6 +53,9 @@ API documentation for the most recent release can be found
53
53
  To build API documentation for the master branch, check out the
54
54
  repository locally and run `rake docs`.
55
55
 
56
+ High-level driver documentation including tutorials and the reference that were in the docs folder can now be found
57
+ at the docs-ruby repository, [here](https://github.com/mongodb/docs-ruby)
58
+
56
59
  ## Support
57
60
 
58
61
  Commercial support for the driver is available through the
data/Rakefile CHANGED
@@ -21,12 +21,12 @@ CLASSIFIERS = [
21
21
  [%r,^spec_tests,, :spec],
22
22
  ]
23
23
 
24
- RUN_PRIORITY = %i(
24
+ RUN_PRIORITY = (ENV['RUN_PRIORITY'] || %(
25
25
  tx_examples
26
26
  unit unit_server
27
27
  integration sdam_integration cursor_reaping query_cache
28
28
  spec spec_sdam_integration
29
- )
29
+ )).split.map(&:to_sym)
30
30
 
31
31
  RSpec::Core::RakeTask.new(:spec) do |t|
32
32
  #t.rspec_opts = "--profile 5" if ENV['CI']
data/lib/mongo/address.rb CHANGED
@@ -178,6 +178,9 @@ module Mongo
178
178
  # @param [ Hash ] opts The options.
179
179
  #
180
180
  # @option opts [ Float ] :connect_timeout Connect timeout.
181
+ # @option opts [ Boolean ] :csot Whether the client-side operation timeout
182
+ # should be considered when connecting the socket. This option influences
183
+ # only what errors will be raised if timeout expires.
181
184
  # @option opts [ true | false ] :ssl Whether to use SSL.
182
185
  # @option opts [ String ] :ssl_ca_cert
183
186
  # Same as the corresponding Client/Socket::SSL option.
@@ -214,11 +217,12 @@ module Mongo
214
217
  # @since 2.0.0
215
218
  # @api private
216
219
  def socket(socket_timeout, opts = {})
220
+ csot = !!opts[:csot]
217
221
  opts = {
218
222
  connect_timeout: Server::CONNECT_TIMEOUT,
219
223
  }.update(options).update(Hash[opts.map { |k, v| [k.to_sym, v] }])
220
224
 
221
- map_exceptions do
225
+ map_exceptions(csot) do
222
226
  if seed.downcase =~ Unix::MATCH
223
227
  specific_address = Unix.new(seed.downcase)
224
228
  return specific_address.socket(socket_timeout, opts)
@@ -281,11 +285,26 @@ module Mongo
281
285
  end
282
286
  end
283
287
 
284
- def map_exceptions
288
+ # Maps some errors to different ones, mostly low-level errors to driver
289
+ # level errors
290
+ #
291
+ # @param [ Boolean ] csot Whether the client-side operation timeout
292
+ # should be considered when connecting the socket.
293
+ def map_exceptions(csot)
285
294
  begin
286
295
  yield
287
296
  rescue Errno::ETIMEDOUT => e
288
- raise Error::SocketTimeoutError, "#{e.class}: #{e} (for #{self})"
297
+ if csot
298
+ raise Error::TimeoutError, "#{e.class}: #{e} (for #{self})"
299
+ else
300
+ raise Error::SocketTimeoutError, "#{e.class}: #{e} (for #{self})"
301
+ end
302
+ rescue Error::SocketTimeoutError => e
303
+ if csot
304
+ raise Error::TimeoutError, "#{e.class}: #{e} (for #{self})"
305
+ else
306
+ raise e
307
+ end
289
308
  rescue IOError, SystemCallError => e
290
309
  raise Error::SocketError, "#{e.class}: #{e} (for #{self})"
291
310
  rescue OpenSSL::SSL::SSLError => e
@@ -69,20 +69,24 @@ module Mongo
69
69
  # Retrieves a valid set of credentials, if possible, or raises
70
70
  # Auth::InvalidConfiguration.
71
71
  #
72
+ # @param [ CsotTimeoutHolder | nil ] timeout_holder CSOT timeout, if any.
73
+ #
72
74
  # @return [ Auth::Aws::Credentials ] A valid set of credentials.
73
75
  #
74
76
  # @raise Auth::InvalidConfiguration if a source contains an invalid set
75
77
  # of credentials.
76
78
  # @raise Auth::Aws::CredentialsNotFound if credentials could not be
77
79
  # retrieved from any source.
78
- def credentials
80
+ # @raise Error::TimeoutError if credentials cannot be retrieved within
81
+ # the timeout defined on the operation context.
82
+ def credentials(timeout_holder = nil)
79
83
  credentials = credentials_from_user(user)
80
84
  return credentials unless credentials.nil?
81
85
 
82
86
  credentials = credentials_from_environment
83
87
  return credentials unless credentials.nil?
84
88
 
85
- credentials = @credentials_cache.fetch { obtain_credentials_from_endpoints }
89
+ credentials = @credentials_cache.fetch { obtain_credentials_from_endpoints(timeout_holder) }
86
90
  return credentials unless credentials.nil?
87
91
 
88
92
  raise Auth::Aws::CredentialsNotFound
@@ -127,17 +131,21 @@ module Mongo
127
131
 
128
132
  # Returns credentials from the AWS metadata endpoints.
129
133
  #
134
+ # @param [ CsotTimeoutHolder ] timeout_holder CSOT timeout.
135
+ #
130
136
  # @return [ Auth::Aws::Credentials | nil ] A set of credentials, or nil
131
137
  # if retrieval failed or the obtained credentials are invalid.
132
138
  #
133
139
  # @raise Auth::InvalidConfiguration if a source contains an invalid set
134
140
  # of credentials.
135
- def obtain_credentials_from_endpoints
136
- if (credentials = web_identity_credentials) && credentials_valid?(credentials, 'Web identity token')
141
+ # @ raise Error::TimeoutError if credentials cannot be retrieved within
142
+ # the timeout defined on the operation context.
143
+ def obtain_credentials_from_endpoints(timeout_holder = nil)
144
+ if (credentials = web_identity_credentials(timeout_holder)) && credentials_valid?(credentials, 'Web identity token')
137
145
  credentials
138
- elsif (credentials = ecs_metadata_credentials) && credentials_valid?(credentials, 'ECS task metadata')
146
+ elsif (credentials = ecs_metadata_credentials(timeout_holder)) && credentials_valid?(credentials, 'ECS task metadata')
139
147
  credentials
140
- elsif (credentials = ec2_metadata_credentials) && credentials_valid?(credentials, 'EC2 instance metadata')
148
+ elsif (credentials = ec2_metadata_credentials(timeout_holder)) && credentials_valid?(credentials, 'EC2 instance metadata')
141
149
  credentials
142
150
  end
143
151
  end
@@ -145,21 +153,26 @@ module Mongo
145
153
  # Returns credentials from the EC2 metadata endpoint. The credentials
146
154
  # could be empty, partial or invalid.
147
155
  #
156
+ # @param [ CsotTimeoutHolder ] timeout_holder CSOT timeout.
157
+ #
148
158
  # @return [ Auth::Aws::Credentials | nil ] A set of credentials, or nil
149
159
  # if retrieval failed.
150
- def ec2_metadata_credentials
160
+ # @ raise Error::TimeoutError if credentials cannot be retrieved within
161
+ # the timeout.
162
+ def ec2_metadata_credentials(timeout_holder = nil)
163
+ timeout_holder&.check_timeout!
151
164
  http = Net::HTTP.new('169.254.169.254')
152
165
  req = Net::HTTP::Put.new('/latest/api/token',
153
166
  # The TTL is required in order to obtain the metadata token.
154
167
  {'x-aws-ec2-metadata-token-ttl-seconds' => '30'})
155
- resp = ::Timeout.timeout(METADATA_TIMEOUT) do
168
+ resp = with_timeout(timeout_holder) do
156
169
  http.request(req)
157
170
  end
158
171
  if resp.code != '200'
159
172
  return nil
160
173
  end
161
174
  metadata_token = resp.body
162
- resp = ::Timeout.timeout(METADATA_TIMEOUT) do
175
+ resp = with_timeout(timeout_holder) do
163
176
  http_get(http, '/latest/meta-data/iam/security-credentials', metadata_token)
164
177
  end
165
178
  if resp.code != '200'
@@ -167,7 +180,7 @@ module Mongo
167
180
  end
168
181
  role_name = resp.body
169
182
  escaped_role_name = CGI.escape(role_name).gsub('+', '%20')
170
- resp = ::Timeout.timeout(METADATA_TIMEOUT) do
183
+ resp = with_timeout(timeout_holder) do
171
184
  http_get(http, "/latest/meta-data/iam/security-credentials/#{escaped_role_name}", metadata_token)
172
185
  end
173
186
  if resp.code != '200'
@@ -189,7 +202,17 @@ module Mongo
189
202
  return nil
190
203
  end
191
204
 
192
- def ecs_metadata_credentials
205
+ # Returns credentials from the ECS metadata endpoint. The credentials
206
+ # could be empty, partial or invalid.
207
+ #
208
+ # @param [ CsotTimeoutHolder | nil ] timeout_holder CSOT timeout.
209
+ #
210
+ # @return [ Auth::Aws::Credentials | nil ] A set of credentials, or nil
211
+ # if retrieval failed.
212
+ # @ raise Error::TimeoutError if credentials cannot be retrieved within
213
+ # the timeout defined on the operation context.
214
+ def ecs_metadata_credentials(timeout_holder = nil)
215
+ timeout_holder&.check_timeout!
193
216
  relative_uri = ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI']
194
217
  if relative_uri.nil? || relative_uri.empty?
195
218
  return nil
@@ -203,7 +226,7 @@ module Mongo
203
226
  # a leading slash must be added by the driver, but this is not
204
227
  # in fact needed.
205
228
  req = Net::HTTP::Get.new(relative_uri)
206
- resp = ::Timeout.timeout(METADATA_TIMEOUT) do
229
+ resp = with_timeout(timeout_holder) do
207
230
  http.request(req)
208
231
  end
209
232
  if resp.code != '200'
@@ -225,13 +248,15 @@ module Mongo
225
248
  # inside EKS. See https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html
226
249
  # for further details.
227
250
  #
251
+ # @param [ CsotTimeoutHolder | nil ] timeout_holder CSOT timeout.
252
+ #
228
253
  # @return [ Auth::Aws::Credentials | nil ] A set of credentials, or nil
229
254
  # if retrieval failed.
230
- def web_identity_credentials
255
+ def web_identity_credentials(timeout_holder = nil)
231
256
  web_identity_token, role_arn, role_session_name = prepare_web_identity_inputs
232
257
  return nil if web_identity_token.nil?
233
258
  response = request_web_identity_credentials(
234
- web_identity_token, role_arn, role_session_name
259
+ web_identity_token, role_arn, role_session_name, timeout_holder
235
260
  )
236
261
  return if response.nil?
237
262
  credentials_from_web_identity_response(response)
@@ -266,10 +291,15 @@ module Mongo
266
291
  # that the caller is assuming.
267
292
  # @param [ String ] role_session_name An identifier for the assumed
268
293
  # role session.
294
+ # @param [ CsotTimeoutHolder | nil ] timeout_holder CSOT timeout.
269
295
  #
270
296
  # @return [ Net::HTTPResponse | nil ] AWS API response if successful,
271
297
  # otherwise nil.
272
- def request_web_identity_credentials(token, role_arn, role_session_name)
298
+ #
299
+ # @ raise Error::TimeoutError if credentials cannot be retrieved within
300
+ # the timeout defined on the operation context.
301
+ def request_web_identity_credentials(token, role_arn, role_session_name, timeout_holder)
302
+ timeout_holder&.check_timeout!
273
303
  uri = URI('https://sts.amazonaws.com/')
274
304
  params = {
275
305
  'Action' => 'AssumeRoleWithWebIdentity',
@@ -281,8 +311,10 @@ module Mongo
281
311
  uri.query = ::URI.encode_www_form(params)
282
312
  req = Net::HTTP::Post.new(uri)
283
313
  req['Accept'] = 'application/json'
284
- resp = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |https|
285
- https.request(req)
314
+ resp = with_timeout(timeout_holder) do
315
+ Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |https|
316
+ https.request(req)
317
+ end
286
318
  end
287
319
  if resp.code != '200'
288
320
  return nil
@@ -351,6 +383,27 @@ module Mongo
351
383
 
352
384
  true
353
385
  end
386
+
387
+ # Execute the given block considering the timeout defined on the context,
388
+ # or the default timeout value.
389
+ #
390
+ # We use +Timeout.timeout+ here because there is no other acceptable easy
391
+ # way to time limit http requests.
392
+ #
393
+ # @param [ CsotTimeoutHolder | nil ] timeout_holder CSOT timeout.
394
+ #
395
+ # @ raise Error::TimeoutError if deadline exceeded.
396
+ def with_timeout(timeout_holder)
397
+ timeout = timeout_holder&.remaining_timeout_sec! || METADATA_TIMEOUT
398
+ exception_class = if timeout_holder&.csot?
399
+ Error::TimeoutError
400
+ else
401
+ nil
402
+ end
403
+ ::Timeout.timeout(timeout, exception_class) do
404
+ yield
405
+ end
406
+ end
354
407
  end
355
408
  end
356
409
  end
@@ -117,7 +117,7 @@ module Mongo
117
117
  else
118
118
  nil
119
119
  end
120
- result = Operation::Result.new(reply, connection.description, connection_global_id)
120
+ result = Operation::Result.new(reply, connection.description, connection_global_id, context: context)
121
121
  connection.update_cluster_time(result)
122
122
  reply_document
123
123
  end
@@ -60,10 +60,15 @@ module Mongo
60
60
  result_combiner = ResultCombiner.new
61
61
  operations = op_combiner.combine
62
62
  validate_requests!
63
+ deadline = calculate_deadline
63
64
 
64
- client.send(:with_session, @options) do |session|
65
- context = Operation::Context.new(client: client, session: session)
65
+ client.with_session(@options) do |session|
66
66
  operations.each do |operation|
67
+ context = Operation::Context.new(
68
+ client: client,
69
+ session: session,
70
+ operation_timeouts: { operation_timeout_ms: op_timeout_ms(deadline) }
71
+ )
67
72
  if single_statement?(operation)
68
73
  write_concern = write_concern(session)
69
74
  write_with_retry(write_concern, context: context) do |connection, txn_num, context|
@@ -124,6 +129,9 @@ module Mongo
124
129
  @collection = collection
125
130
  @requests = requests
126
131
  @options = options || {}
132
+ if @options[:timeout_ms] && @options[:timeout_ms] < 0
133
+ raise ArgumentError, "timeout_ms options must be non-negative integer"
134
+ end
127
135
  end
128
136
 
129
137
  # Is the bulk write ordered?
@@ -162,6 +170,31 @@ module Mongo
162
170
  :update_one,
163
171
  :insert_one ].freeze
164
172
 
173
+ # @return [ Float | nil ] Deadline for the batch of operations, if set.
174
+ def calculate_deadline
175
+ timeout_ms = @options[:timeout_ms] || collection.timeout_ms
176
+ return nil if timeout_ms.nil?
177
+
178
+ if timeout_ms == 0
179
+ 0
180
+ else
181
+ Utils.monotonic_time + (timeout_ms / 1_000.0)
182
+ end
183
+ end
184
+
185
+ # @param [ Float | nil ] deadline Deadline for the batch of operations.
186
+ #
187
+ # @return [ Integer | nil ] Timeout in milliseconds for the next operation.
188
+ def op_timeout_ms(deadline)
189
+ return nil if deadline.nil?
190
+
191
+ if deadline == 0
192
+ 0
193
+ else
194
+ ((deadline - Utils.monotonic_time) * 1_000).to_i
195
+ end
196
+ end
197
+
165
198
  def single_statement?(operation)
166
199
  SINGLE_STATEMENT_OPS.include?(operation.keys.first)
167
200
  end
data/lib/mongo/client.rb CHANGED
@@ -111,6 +111,7 @@ module Mongo
111
111
  :ssl_verify_certificate,
112
112
  :ssl_verify_hostname,
113
113
  :ssl_verify_ocsp_endpoint,
114
+ :timeout_ms,
114
115
  :truncate_logs,
115
116
  :user,
116
117
  :wait_queue_timeout,
@@ -349,7 +350,8 @@ module Mongo
349
350
  # @option options [ Integer ] :server_selection_timeout The timeout in seconds
350
351
  # for selecting a server for an operation.
351
352
  # @option options [ Float ] :socket_timeout The timeout, in seconds, to
352
- # execute operations on a socket.
353
+ # execute operations on a socket. This option is deprecated, use
354
+ # :timeout_ms instead.
353
355
  # @option options [ Integer ] :srv_max_hosts The maximum number of mongoses
354
356
  # that the driver will communicate with for sharded topologies. If this
355
357
  # option is 0, then there will be no maximum number of mongoses. If the
@@ -413,11 +415,15 @@ module Mongo
413
415
  # @option options [ true, false ] :ssl_verify_hostname Whether to perform peer hostname
414
416
  # validation. This setting overrides :ssl_verify with respect to whether hostname validation
415
417
  # is performed.
418
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
419
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
420
+ # The default value is unset which means the feature is not enabled.
416
421
  # @option options [ true, false ] :truncate_logs Whether to truncate the
417
422
  # logs at the default 250 characters.
418
423
  # @option options [ String ] :user The user name.
419
424
  # @option options [ Float ] :wait_queue_timeout The time to wait, in
420
425
  # seconds, in the connection pool for a connection to be checked in.
426
+ # This option is deprecated, use :timeout_ms instead.
421
427
  # @option options [ Array<Hash> ] :wrapping_libraries Information about
422
428
  # libraries such as ODMs that are wrapping the driver, to be added to
423
429
  # metadata sent to the server. Specify the lower level libraries first.
@@ -425,7 +431,7 @@ module Mongo
425
431
  # @option options [ Hash ] :write Deprecated. Equivalent to :write_concern
426
432
  # option.
427
433
  # @option options [ Hash ] :write_concern The write concern options.
428
- # Can be :w => Integer|String, :wtimeout => Integer (in milliseconds),
434
+ # Can be :w => Integer|String, :wtimeout => Integer (in milliseconds, deprecated),
429
435
  # :j => Boolean, :fsync => Boolean.
430
436
  # @option options [ Integer ] :zlib_compression_level The Zlib compression level to use, if using compression.
431
437
  # See Ruby's Zlib module for valid levels.
@@ -934,8 +940,11 @@ module Mongo
934
940
  # See https://mongodb.com/docs/manual/reference/command/listDatabases/
935
941
  # for more information and usage.
936
942
  # @option opts [ Session ] :session The session to use.
937
- # @option options [ Object ] :comment A user-provided
943
+ # @option opts [ Object ] :comment A user-provided
938
944
  # comment to attach to this command.
945
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
946
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
947
+ # The default value is unset which means the feature is not enabled.
939
948
  #
940
949
  # @return [ Array<String> ] The names of the databases.
941
950
  #
@@ -955,7 +964,12 @@ module Mongo
955
964
  #
956
965
  # @option opts [ true, false ] :authorized_databases A flag that determines
957
966
  # which databases are returned based on user privileges when access control
958
- # is enabled
967
+ # is enabled.
968
+ # @option opts [ Object ] :comment A user-provided
969
+ # comment to attach to this command.
970
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
971
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
972
+ # The default value is unset which means the feature is not enabled.
959
973
  #
960
974
  # See https://mongodb.com/docs/manual/reference/command/listDatabases/
961
975
  # for more information and usage.
@@ -1095,7 +1109,7 @@ module Mongo
1095
1109
  return use(Database::ADMIN).watch(pipeline, options) unless database.name == Database::ADMIN
1096
1110
 
1097
1111
  view_options = options.dup
1098
- view_options[:await_data] = true if options[:max_await_time_ms]
1112
+ view_options[:cursor_type] = :tailable_await if options[:max_await_time_ms]
1099
1113
 
1100
1114
  Mongo::Collection::View::ChangeStream.new(
1101
1115
  Mongo::Collection::View.new(self["#{Database::COMMAND}.aggregate"], {}, view_options),
@@ -1185,6 +1199,22 @@ module Mongo
1185
1199
  @encrypted_fields_map ||= @options.fetch(:auto_encryption_options, {})[:encrypted_fields_map]
1186
1200
  end
1187
1201
 
1202
+ # @return [ Integer | nil ] Value of timeout_ms option if set.
1203
+ # @api private
1204
+ def timeout_ms
1205
+ @options[:timeout_ms]
1206
+ end
1207
+
1208
+ # @return [ Float | nil ] Value of timeout_ms option converted to seconds.
1209
+ # @api private
1210
+ def timeout_sec
1211
+ if timeout_ms.nil?
1212
+ nil
1213
+ else
1214
+ timeout_ms / 1_000.0
1215
+ end
1216
+ end
1217
+
1188
1218
  private
1189
1219
 
1190
1220
  # Create a new encrypter object using the client's auto encryption options
@@ -1230,6 +1260,8 @@ module Mongo
1230
1260
  # @option options [ true | false ] :implicit When no session is passed in,
1231
1261
  # whether to create an implicit session.
1232
1262
  # @option options [ Session ] :session The session to validate and return.
1263
+ # @option options [ Operation::Context | nil ] :context Context of the
1264
+ # operation the session is used for.
1233
1265
  #
1234
1266
  # @return [ Session ] A session object.
1235
1267
  #
@@ -1242,7 +1274,7 @@ module Mongo
1242
1274
  return options[:session].validate!(self)
1243
1275
  end
1244
1276
 
1245
- cluster.validate_session_support!
1277
+ cluster.validate_session_support!(timeout: timeout_sec)
1246
1278
 
1247
1279
  options = {implicit: true}.update(options)
1248
1280
 
@@ -40,6 +40,9 @@ module Mongo
40
40
  # should be hashes of TLS connection options. The options are equivalent
41
41
  # to TLS connection options of Mongo::Client.
42
42
  # @see Mongo::Client#initialize for list of TLS options.
43
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
44
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
45
+ # The default value is unset which means the feature is disabled.
43
46
  #
44
47
  # @raise [ ArgumentError ] If required options are missing or incorrectly
45
48
  # formatted.
@@ -131,7 +134,7 @@ module Mongo
131
134
  # {'$and' => [{'$gt' => ['$field', 10]}, {'$lt' => ['$field', 20]}}
132
135
  # )
133
136
  # {$and: [{$gt: [<fieldpath>, <value1>]}, {$lt: [<fieldpath>, <value2>]}]
134
- # Only supported when queryType is "rangePreview" and algorithm is "RangePreview".
137
+ # Only supported when queryType is "range" and algorithm is "Range".
135
138
  # @note: The Range algorithm is experimental only. It is not intended
136
139
  # for public use. It is subject to breaking changes.
137
140
  #
@@ -143,11 +146,11 @@ module Mongo
143
146
  # @option options [ String ] :key_alt_name The alternate name for the
144
147
  # encryption key.
145
148
  # @option options [ String ] :algorithm The algorithm used to encrypt the
146
- # expression. The only allowed value is "RangePreview"
149
+ # expression. The only allowed value is "Range"
147
150
  # @option options [ Integer | nil ] :contention_factor Contention factor
148
151
  # to be applied If not provided, it defaults to a value of 0.
149
152
  # @option options [ String | nil ] query_type Query type to be applied.
150
- # The only allowed value is "rangePreview".
153
+ # The only allowed value is "range".
151
154
  #
152
155
  # @note The :key_id and :key_alt_name options are mutually exclusive. Only
153
156
  # one is required to perform explicit encryption.
@@ -194,7 +194,12 @@ module Mongo
194
194
  server_api: server.options[:server_api],
195
195
  connection_global_id: kill_spec.connection_global_id,
196
196
  }
197
- op.execute(server, context: Operation::Context.new(options: options))
197
+ if connection = kill_spec.connection
198
+ op.execute_with_connection(connection, context: Operation::Context.new(options: options))
199
+ connection.connection_pool.check_in(connection)
200
+ else
201
+ op.execute(server, context: Operation::Context.new(options: options))
202
+ end
198
203
 
199
204
  if session = kill_spec.session
200
205
  if session.implicit?
@@ -116,8 +116,12 @@ class Mongo::Cluster
116
116
  log_warn(
117
117
  "Server #{updated_desc.address.to_s} has an incorrect replica set name '#{updated_desc.replica_set_name}'; expected '#{topology.replica_set_name}'"
118
118
  )
119
- @updated_desc = ::Mongo::Server::Description.new(updated_desc.address,
120
- {}, average_round_trip_time: updated_desc.average_round_trip_time)
119
+ @updated_desc = ::Mongo::Server::Description.new(
120
+ updated_desc.address,
121
+ {},
122
+ average_round_trip_time: updated_desc.average_round_trip_time,
123
+ minimum_round_trip_time: updated_desc.minimum_round_trip_time
124
+ )
121
125
  update_server_descriptions
122
126
  end
123
127
  end
@@ -233,8 +237,12 @@ class Mongo::Cluster
233
237
  end
234
238
 
235
239
  if stale_primary?
236
- @updated_desc = ::Mongo::Server::Description.new(updated_desc.address,
237
- {}, average_round_trip_time: updated_desc.average_round_trip_time)
240
+ @updated_desc = ::Mongo::Server::Description.new(
241
+ updated_desc.address,
242
+ {},
243
+ average_round_trip_time: updated_desc.average_round_trip_time,
244
+ minimum_round_trip_time: updated_desc.minimum_round_trip_time
245
+ )
238
246
  update_server_descriptions
239
247
  check_if_has_primary
240
248
  return
@@ -270,9 +278,14 @@ class Mongo::Cluster
270
278
  servers_list.each do |server|
271
279
  if server.address != updated_desc.address
272
280
  if server.primary?
273
- server.update_description(::Mongo::Server::Description.new(
274
- server.address, {},
275
- average_round_trip_time: server.description.average_round_trip_time))
281
+ server.update_description(
282
+ ::Mongo::Server::Description.new(
283
+ server.address,
284
+ {},
285
+ average_round_trip_time: server.description.average_round_trip_time,
286
+ minimum_round_trip_time: updated_desc.minimum_round_trip_time
287
+ )
288
+ )
276
289
  end
277
290
  end
278
291
  end
data/lib/mongo/cluster.rb CHANGED
@@ -779,12 +779,19 @@ module Mongo
779
779
  # Deprecated and ignored.
780
780
  # @param [ Session | nil ] session Optional session to take into account
781
781
  # for mongos pinning.
782
+ # @param [ Float | nil ] :timeout Timeout in seconds for the operation,
783
+ # if any.
782
784
  #
783
785
  # @return [ Mongo::Server ] A primary server.
784
786
  #
785
787
  # @since 2.0.0
786
- def next_primary(ping = nil, session = nil)
787
- ServerSelector.primary.select_server(self, nil, session)
788
+ def next_primary(ping = nil, session = nil, timeout: nil)
789
+ ServerSelector.primary.select_server(
790
+ self,
791
+ nil,
792
+ session,
793
+ timeout: timeout
794
+ )
788
795
  end
789
796
 
790
797
  # Get the connection pool for the server.
@@ -974,8 +981,11 @@ module Mongo
974
981
  # any servers and doesn't find any servers for the duration of
975
982
  # server selection timeout.
976
983
  #
984
+ # @param [ Float | nil ] :timeout Timeout for the validation. Since the
985
+ # validation process involves server selection,
986
+ #
977
987
  # @api private
978
- def validate_session_support!
988
+ def validate_session_support!(timeout: nil)
979
989
  if topology.is_a?(Topology::LoadBalanced)
980
990
  return
981
991
  end
@@ -993,7 +1003,7 @@ module Mongo
993
1003
  # No data bearing servers known - perform server selection to try to
994
1004
  # get a response from at least one of them, to return an accurate
995
1005
  # assessment of whether sessions are currently supported.
996
- ServerSelector.get(mode: :primary_preferred).select_server(self)
1006
+ ServerSelector.get(mode: :primary_preferred).select_server(self, timeout: timeout)
997
1007
  @state_change_lock.synchronize do
998
1008
  @sdam_flow_lock.synchronize do
999
1009
  unless topology.logical_session_timeout
@@ -30,7 +30,7 @@ module Mongo
30
30
  # @return [ Result ] The result of the execution.
31
31
  def do_drop(operation, session, context)
32
32
  operation.execute(next_primary(nil, session), context: context)
33
- rescue Error::OperationFailure => ex
33
+ rescue Error::OperationFailure::Family => ex
34
34
  # NamespaceNotFound
35
35
  if ex.code == 26 || ex.code.nil? && ex.message =~ /ns not found/
36
36
  false