mongo 2.20.0 → 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 (296) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -1
  3. data/Rakefile +59 -23
  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/config.rb +2 -2
  25. data/lib/mongo/crypt/auto_encrypter.rb +4 -6
  26. data/lib/mongo/crypt/binding.rb +4 -4
  27. data/lib/mongo/crypt/context.rb +20 -14
  28. data/lib/mongo/crypt/encryption_io.rb +56 -26
  29. data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
  30. data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
  31. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
  32. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
  33. data/lib/mongo/csot_timeout_holder.rb +119 -0
  34. data/lib/mongo/cursor/kill_spec.rb +5 -2
  35. data/lib/mongo/cursor/nontailable.rb +27 -0
  36. data/lib/mongo/cursor.rb +86 -24
  37. data/lib/mongo/cursor_host.rb +82 -0
  38. data/lib/mongo/database/view.rb +81 -14
  39. data/lib/mongo/database.rb +88 -18
  40. data/lib/mongo/error/operation_failure.rb +209 -204
  41. data/lib/mongo/error/server_timeout_error.rb +12 -0
  42. data/lib/mongo/error/socket_timeout_error.rb +3 -1
  43. data/lib/mongo/error/timeout_error.rb +23 -0
  44. data/lib/mongo/error.rb +2 -0
  45. data/lib/mongo/grid/fs_bucket.rb +45 -12
  46. data/lib/mongo/grid/stream/read.rb +15 -1
  47. data/lib/mongo/grid/stream/write.rb +21 -4
  48. data/lib/mongo/index/view.rb +77 -16
  49. data/lib/mongo/operation/context.rb +40 -2
  50. data/lib/mongo/operation/create_search_indexes/op_msg.rb +2 -2
  51. data/lib/mongo/operation/delete/op_msg.rb +2 -1
  52. data/lib/mongo/operation/drop_search_index/op_msg.rb +2 -2
  53. data/lib/mongo/operation/find/op_msg.rb +45 -0
  54. data/lib/mongo/operation/get_more/op_msg.rb +33 -0
  55. data/lib/mongo/operation/insert/op_msg.rb +3 -2
  56. data/lib/mongo/operation/insert/result.rb +4 -2
  57. data/lib/mongo/operation/list_collections/result.rb +1 -1
  58. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  59. data/lib/mongo/operation/op_msg_base.rb +3 -1
  60. data/lib/mongo/operation/result.rb +26 -5
  61. data/lib/mongo/operation/shared/executable.rb +12 -1
  62. data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
  63. data/lib/mongo/operation/shared/response_handling.rb +3 -3
  64. data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
  65. data/lib/mongo/operation/shared/timed.rb +52 -0
  66. data/lib/mongo/operation/shared/write.rb +4 -1
  67. data/lib/mongo/operation/update/op_msg.rb +2 -1
  68. data/lib/mongo/operation/update_search_index/op_msg.rb +2 -2
  69. data/lib/mongo/operation.rb +1 -0
  70. data/lib/mongo/protocol/message.rb +1 -4
  71. data/lib/mongo/protocol/msg.rb +2 -2
  72. data/lib/mongo/retryable/base_worker.rb +28 -3
  73. data/lib/mongo/retryable/read_worker.rb +76 -35
  74. data/lib/mongo/retryable/write_worker.rb +53 -22
  75. data/lib/mongo/retryable.rb +8 -2
  76. data/lib/mongo/server/connection.rb +11 -5
  77. data/lib/mongo/server/connection_base.rb +22 -2
  78. data/lib/mongo/server/connection_pool.rb +32 -14
  79. data/lib/mongo/server/description/features.rb +1 -1
  80. data/lib/mongo/server/description.rb +18 -5
  81. data/lib/mongo/server/monitor.rb +7 -4
  82. data/lib/mongo/server/pending_connection.rb +25 -8
  83. data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
  84. data/lib/mongo/server.rb +11 -6
  85. data/lib/mongo/server_selector/base.rb +25 -9
  86. data/lib/mongo/session.rb +78 -9
  87. data/lib/mongo/socket/ssl.rb +131 -18
  88. data/lib/mongo/socket/tcp.rb +40 -6
  89. data/lib/mongo/socket.rb +154 -25
  90. data/lib/mongo/uri/options_mapper.rb +1 -0
  91. data/lib/mongo/version.rb +1 -5
  92. data/lib/mongo.rb +1 -0
  93. data/mongo.gemspec +8 -11
  94. data/spec/atlas/atlas_connectivity_spec.rb +4 -0
  95. data/spec/atlas/operations_spec.rb +4 -0
  96. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
  97. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
  98. data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
  99. data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +67 -20
  100. data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
  101. data/spec/integration/connection_pool_populator_spec.rb +2 -0
  102. data/spec/integration/cursor_pinning_spec.rb +15 -60
  103. data/spec/integration/cursor_reaping_spec.rb +1 -1
  104. data/spec/integration/docs_examples_spec.rb +1 -1
  105. data/spec/integration/operation_failure_code_spec.rb +1 -1
  106. data/spec/integration/operation_failure_message_spec.rb +3 -3
  107. data/spec/integration/retryable_errors_spec.rb +2 -2
  108. data/spec/integration/retryable_reads_errors_spec.rb +35 -23
  109. data/spec/integration/sdam_error_handling_spec.rb +4 -1
  110. data/spec/integration/search_indexes_prose_spec.rb +4 -0
  111. data/spec/integration/server_spec.rb +4 -3
  112. data/spec/integration/transactions_api_examples_spec.rb +2 -0
  113. data/spec/kerberos/kerberos_spec.rb +4 -0
  114. data/spec/lite_spec_helper.rb +3 -11
  115. data/spec/mongo/auth/user/view_spec.rb +1 -1
  116. data/spec/mongo/caching_cursor_spec.rb +1 -1
  117. data/spec/mongo/client_encryption_spec.rb +1 -0
  118. data/spec/mongo/client_spec.rb +158 -4
  119. data/spec/mongo/collection/view/aggregation_spec.rb +14 -39
  120. data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
  121. data/spec/mongo/collection_crud_spec.rb +1 -0
  122. data/spec/mongo/collection_spec.rb +5 -6
  123. data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
  124. data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
  125. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
  126. data/spec/mongo/crypt/handle_spec.rb +1 -1
  127. data/spec/mongo/cursor_spec.rb +26 -9
  128. data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
  129. data/spec/mongo/operation/context_spec.rb +79 -0
  130. data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
  131. data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
  132. data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
  133. data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
  134. data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
  135. data/spec/mongo/operation/shared/csot/examples.rb +113 -0
  136. data/spec/mongo/query_cache_spec.rb +243 -225
  137. data/spec/mongo/retryable_spec.rb +1 -0
  138. data/spec/mongo/server/connection_spec.rb +22 -0
  139. data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
  140. data/spec/mongo/socket/ssl_spec.rb +0 -10
  141. data/spec/runners/change_streams/test.rb +2 -2
  142. data/spec/runners/crud/operation.rb +1 -1
  143. data/spec/runners/crud/verifier.rb +3 -1
  144. data/spec/runners/transactions/operation.rb +4 -6
  145. data/spec/runners/unified/ambiguous_operations.rb +13 -0
  146. data/spec/runners/unified/assertions.rb +4 -0
  147. data/spec/runners/unified/change_stream_operations.rb +14 -24
  148. data/spec/runners/unified/crud_operations.rb +82 -59
  149. data/spec/runners/unified/ddl_operations.rb +38 -7
  150. data/spec/runners/unified/grid_fs_operations.rb +37 -2
  151. data/spec/runners/unified/support_operations.rb +43 -4
  152. data/spec/runners/unified/test.rb +22 -10
  153. data/spec/runners/unified.rb +1 -1
  154. data/spec/solo/clean_exit_spec.rb +2 -0
  155. data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
  156. data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
  157. data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
  158. data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
  159. data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
  160. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
  161. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
  162. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
  163. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
  164. data/spec/spec_tests/data/client_side_encryption/fle2v2-BypassQueryAnalysis.yml +1 -0
  165. data/spec/spec_tests/data/client_side_encryption/fle2v2-Compact.yml +1 -0
  166. data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection.yml +1 -0
  167. data/spec/spec_tests/data/client_side_encryption/fle2v2-DecryptExistingData.yml +1 -0
  168. data/spec/spec_tests/data/client_side_encryption/fle2v2-Delete.yml +1 -0
  169. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml +1 -0
  170. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-jsonSchema.yml +1 -0
  171. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFieldsMap-defaults.yml +1 -0
  172. data/spec/spec_tests/data/client_side_encryption/fle2v2-FindOneAndUpdate.yml +1 -0
  173. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Indexed.yml +1 -0
  174. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Unindexed.yml +1 -0
  175. data/spec/spec_tests/data/client_side_encryption/fle2v2-MissingKey.yml +1 -0
  176. data/spec/spec_tests/data/client_side_encryption/fle2v2-NoEncryption.yml +1 -0
  177. data/spec/spec_tests/data/client_side_encryption/fle2v2-Update.yml +1 -0
  178. data/spec/spec_tests/data/client_side_encryption/fle2v2-validatorAndPartialFieldExpression.yml +2 -1
  179. data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
  180. data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
  181. data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
  182. data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
  183. data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
  184. data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
  185. data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
  186. data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
  187. data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
  188. data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
  189. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
  190. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
  191. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
  192. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
  193. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
  194. data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
  195. data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
  196. data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
  197. data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
  198. data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
  199. data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
  200. data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
  201. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
  202. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
  203. data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
  204. data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
  205. data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +6 -0
  206. data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +6 -0
  207. data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +29 -0
  208. data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
  209. data/spec/spec_tests/transactions_unified_spec.rb +2 -1
  210. data/spec/support/certificates/atlas-ocsp-ca.crt +89 -79
  211. data/spec/support/certificates/atlas-ocsp.crt +117 -122
  212. data/spec/support/certificates/retrieve-atlas-cert +1 -1
  213. data/spec/support/cluster_tools.rb +3 -3
  214. data/spec/support/common_shortcuts.rb +2 -2
  215. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
  216. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
  217. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
  218. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
  219. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
  220. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
  221. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
  222. data/spec/support/shared/session.rb +2 -2
  223. data/spec/support/spec_setup.rb +2 -2
  224. data/spec/support/utils.rb +3 -1
  225. metadata +88 -173
  226. checksums.yaml.gz.sig +0 -0
  227. data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
  228. data/spec/shared/LICENSE +0 -20
  229. data/spec/shared/bin/get-mongodb-download-url +0 -17
  230. data/spec/shared/bin/s3-copy +0 -45
  231. data/spec/shared/bin/s3-upload +0 -69
  232. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  233. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  234. data/spec/shared/lib/mrss/constraints.rb +0 -378
  235. data/spec/shared/lib/mrss/docker_runner.rb +0 -298
  236. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
  237. data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
  238. data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
  239. data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
  240. data/spec/shared/lib/mrss/session_registry.rb +0 -69
  241. data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
  242. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  243. data/spec/shared/lib/mrss/utils.rb +0 -37
  244. data/spec/shared/share/Dockerfile.erb +0 -281
  245. data/spec/shared/share/haproxy-1.conf +0 -16
  246. data/spec/shared/share/haproxy-2.conf +0 -17
  247. data/spec/shared/shlib/config.sh +0 -27
  248. data/spec/shared/shlib/distro.sh +0 -74
  249. data/spec/shared/shlib/server.sh +0 -417
  250. data/spec/shared/shlib/set_env.sh +0 -146
  251. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -241
  252. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -422
  253. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -182
  254. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -239
  255. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -235
  256. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -252
  257. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1687
  258. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -293
  259. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -905
  260. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1684
  261. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1680
  262. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1697
  263. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -329
  264. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -424
  265. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -226
  266. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -327
  267. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -319
  268. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -336
  269. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -913
  270. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -292
  271. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -518
  272. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -911
  273. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -907
  274. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -924
  275. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -325
  276. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -424
  277. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -224
  278. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -323
  279. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -319
  280. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -338
  281. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -241
  282. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -423
  283. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -182
  284. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -239
  285. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -235
  286. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -254
  287. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -241
  288. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -422
  289. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -182
  290. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -239
  291. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -235
  292. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -254
  293. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -43
  294. data/spec/support/faas/app/aws_lambda/mongodb/Gemfile.lock +0 -19
  295. data.tar.gz.sig +0 -0
  296. metadata.gz.sig +0 -3
@@ -169,6 +169,7 @@ module Mongo
169
169
  raise Error::LintError, "Trying to deliver a message over a disconnected connection (to #{address})"
170
170
  end
171
171
  buffer = serialize(message, context)
172
+ check_timeout!(context)
172
173
  ensure_connected do |socket|
173
174
  operation_id = Monitoring.next_operation_id
174
175
  started_event = command_started(address, operation_id, message.payload,
@@ -181,9 +182,10 @@ module Mongo
181
182
  result = nil
182
183
  begin
183
184
  result = add_server_diagnostics do
184
- socket.write(buffer.to_s)
185
+ socket.write(buffer.to_s, timeout: context.remaining_timeout_sec)
185
186
  if message.replyable?
186
- Protocol::Message.deserialize(socket, max_message_size, message.request_id, options)
187
+ check_timeout!(context)
188
+ Protocol::Message.deserialize(socket, max_message_size, message.request_id, options.merge(timeout: context.remaining_timeout_sec))
187
189
  else
188
190
  nil
189
191
  end
@@ -273,6 +275,24 @@ module Mongo
273
275
 
274
276
  buffer
275
277
  end
278
+
279
+ # If timeoutMS is set for the operation context, checks whether there is
280
+ # enough time left to send the corresponding message to the server
281
+ # (remaining timeout is bigger than minimum round trip time for
282
+ # the server)
283
+ #
284
+ # @param [ Mongo::Operation::Context ] context Context of the operation.
285
+ #
286
+ # @raise [ Mongo::Error::TimeoutError ] if timeout expired or there is
287
+ # not enough time to send the message to the server.
288
+ def check_timeout!(context)
289
+ return if [nil, 0].include?(context.deadline)
290
+
291
+ time_to_execute = context.remaining_timeout_sec - server.minimum_round_trip_time
292
+ if time_to_execute <= 0
293
+ raise Mongo::Error::TimeoutError
294
+ end
295
+ end
276
296
  end
277
297
  end
278
298
  end
@@ -205,11 +205,18 @@ module Mongo
205
205
 
206
206
  # The time to wait, in seconds, for a connection to become available.
207
207
  #
208
+ # @param [ Mongo::Operation:Context | nil ] context Context of the operation
209
+ # the connection is requested for, if any.
210
+ #
208
211
  # @return [ Float ] The queue wait timeout.
209
212
  #
210
213
  # @since 2.9.0
211
- def wait_timeout
212
- @wait_timeout ||= options[:wait_timeout] || DEFAULT_WAIT_TIMEOUT
214
+ def wait_timeout(context = nil)
215
+ if context&.remaining_timeout_sec.nil?
216
+ options[:wait_timeout] || DEFAULT_WAIT_TIMEOUT
217
+ else
218
+ context&.remaining_timeout_sec
219
+ end
213
220
  end
214
221
 
215
222
  # The maximum seconds a socket can remain idle since it has been
@@ -345,6 +352,10 @@ module Mongo
345
352
  # The returned connection counts toward the pool's max size. When the
346
353
  # caller is finished using the connection, the connection should be
347
354
  # checked back in via the check_in method.
355
+ # @param [ Integer | nil ] :connection_global_id The global id for the
356
+ # connection to check out.
357
+ # @param [ Mongo::Operation:Context | nil ] :context Context of the operation
358
+ # the connection is requested for, if any.
348
359
  #
349
360
  # @return [ Mongo::Server::Connection ] The checked out connection.
350
361
  # @raise [ Error::PoolClosedError ] If the pool has been closed.
@@ -352,7 +363,7 @@ module Mongo
352
363
  # and remains so for longer than the wait timeout.
353
364
  #
354
365
  # @since 2.9.0
355
- def check_out(connection_global_id: nil)
366
+ def check_out(connection_global_id: nil, context: nil)
356
367
  check_invariants
357
368
 
358
369
  publish_cmap_event(
@@ -362,7 +373,9 @@ module Mongo
362
373
  raise_if_pool_closed!
363
374
  raise_if_pool_paused_locked!
364
375
 
365
- connection = retrieve_and_connect_connection(connection_global_id)
376
+ connection = retrieve_and_connect_connection(
377
+ connection_global_id, context
378
+ )
366
379
 
367
380
  publish_cmap_event(
368
381
  Monitoring::Event::Cmap::ConnectionCheckedOut.new(@server.address, connection.id, self),
@@ -698,10 +711,13 @@ module Mongo
698
711
  # @return [ Object ] The result of the block.
699
712
  #
700
713
  # @since 2.0.0
701
- def with_connection(connection_global_id: nil)
714
+ def with_connection(connection_global_id: nil, context: nil)
702
715
  raise_if_closed!
703
716
 
704
- connection = check_out(connection_global_id: connection_global_id)
717
+ connection = check_out(
718
+ connection_global_id: connection_global_id,
719
+ context: context
720
+ )
705
721
  yield(connection)
706
722
  rescue Error::SocketError, Error::SocketTimeoutError, Error::ConnectionPerished => e
707
723
  maybe_raise_pool_cleared!(connection, e)
@@ -975,9 +991,9 @@ module Mongo
975
991
 
976
992
  # Attempts to connect (handshake and auth) the connection. If an error is
977
993
  # encountered, closes the connection and raises the error.
978
- def connect_connection(connection)
994
+ def connect_connection(connection, context = nil)
979
995
  begin
980
- connection.connect!
996
+ connection.connect!(context)
981
997
  rescue Exception
982
998
  connection.disconnect!(reason: :error)
983
999
  raise
@@ -1242,16 +1258,18 @@ module Mongo
1242
1258
 
1243
1259
  # Retrieves a connection and connects it.
1244
1260
  #
1245
- # @param [ Integer ] connection_global_id The global id for the
1261
+ # @param [ Integer | nil ] connection_global_id The global id for the
1246
1262
  # connection to check out.
1263
+ # @param [ Mongo::Operation:Context | nil ] context Context of the operation
1264
+ # the connection is requested for, if any.
1247
1265
  #
1248
1266
  # @return [ Mongo::Server::Connection ] The checked out connection.
1249
1267
  #
1250
1268
  # @raise [ Error::PoolClosedError ] If the pool has been closed.
1251
1269
  # @raise [ Timeout::Error ] If the connection pool is at maximum size
1252
1270
  # and remains so for longer than the wait timeout.
1253
- def retrieve_and_connect_connection(connection_global_id)
1254
- deadline = Utils.monotonic_time + wait_timeout
1271
+ def retrieve_and_connect_connection(connection_global_id, context = nil)
1272
+ deadline = Utils.monotonic_time + wait_timeout(context)
1255
1273
  connection = nil
1256
1274
 
1257
1275
  @lock.synchronize do
@@ -1267,7 +1285,7 @@ module Mongo
1267
1285
  connection = wait_for_connection(connection_global_id, deadline)
1268
1286
  end
1269
1287
 
1270
- connect_or_raise(connection) unless connection.connected?
1288
+ connect_or_raise(connection, context) unless connection.connected?
1271
1289
 
1272
1290
  @lock.synchronize do
1273
1291
  @checked_out_connections << connection
@@ -1327,8 +1345,8 @@ module Mongo
1327
1345
  # cannot be connected.
1328
1346
  # This method also publish corresponding event and ensures that counters
1329
1347
  # and condition variables are updated.
1330
- def connect_or_raise(connection)
1331
- connect_connection(connection)
1348
+ def connect_or_raise(connection, context)
1349
+ connect_connection(connection, context)
1332
1350
  rescue Exception
1333
1351
  # Handshake or authentication failed
1334
1352
  @lock.synchronize do
@@ -83,7 +83,7 @@ module Mongo
83
83
  # The wire protocol versions that this version of the driver supports.
84
84
  #
85
85
  # @since 2.0.0
86
- DRIVER_WIRE_VERSIONS = (6..21).freeze
86
+ DRIVER_WIRE_VERSIONS = (6..25).freeze
87
87
 
88
88
  # Create the methods for each mapping to tell if they are supported.
89
89
  #
@@ -209,8 +209,8 @@ module Mongo
209
209
  # @param [ Hash ] config The result of the hello command.
210
210
  # @param [ Float ] average_round_trip_time The moving average time (sec) the hello
211
211
  # command took to complete.
212
- # @param [ Float ] average_round_trip_time The moving average time (sec)
213
- # the ismaster call took to complete.
212
+ # @param [ Float ] minimum_round_trip_time The minimum round trip time
213
+ # of ten last hello commands.
214
214
  # @param [ true | false ] load_balancer Whether the server is treated as
215
215
  # a load balancer.
216
216
  # @param [ true | false ] force_load_balancer Whether the server is
@@ -218,7 +218,8 @@ module Mongo
218
218
  #
219
219
  # @api private
220
220
  def initialize(address, config = {}, average_round_trip_time: nil,
221
- load_balancer: false, force_load_balancer: false
221
+ minimum_round_trip_time: 0, load_balancer: false,
222
+ force_load_balancer: false
222
223
  )
223
224
  @address = address
224
225
  @config = config
@@ -226,6 +227,7 @@ module Mongo
226
227
  @force_load_balancer = !!force_load_balancer
227
228
  @features = Features.new(wire_versions, me || @address.to_s)
228
229
  @average_round_trip_time = average_round_trip_time
230
+ @minimum_round_trip_time = minimum_round_trip_time
229
231
  @last_update_time = Time.now.freeze
230
232
  @last_update_monotime = Utils.monotonic_time
231
233
 
@@ -302,6 +304,10 @@ module Mongo
302
304
  # @return [ Float ] The moving average time the hello call took to complete.
303
305
  attr_reader :average_round_trip_time
304
306
 
307
+ # @return [ Float ] The minimum time from the ten last hello calls took
308
+ # to complete.
309
+ attr_reader :minimum_round_trip_time
310
+
305
311
  # Returns whether this server is an arbiter, per the SDAM spec.
306
312
  #
307
313
  # @example Is the server an arbiter?
@@ -723,8 +729,7 @@ module Mongo
723
729
 
724
730
  # @api private
725
731
  def ok?
726
- config[Operation::Result::OK] &&
727
- config[Operation::Result::OK] == 1 || false
732
+ config[Operation::Result::OK] == 1
728
733
  end
729
734
 
730
735
  # Get the range of supported wire versions for the server.
@@ -802,6 +807,14 @@ module Mongo
802
807
  !!(address.to_s.downcase != me.downcase if me)
803
808
  end
804
809
 
810
+ # Whether this description is from a mongocryptd server.
811
+ #
812
+ # @return [ true, false ] Whether this description is from a mongocryptd
813
+ # server.
814
+ def mongocryptd?
815
+ ok? && config['iscryptd'] == true
816
+ end
817
+
805
818
  # opTime in lastWrite subdocument of the hello response.
806
819
  #
807
820
  # @return [ BSON::Timestamp ] The timestamp.
@@ -237,8 +237,11 @@ module Mongo
237
237
  @sdam_mutex.synchronize do
238
238
  old_description = server.description
239
239
 
240
- new_description = Description.new(server.address, result,
241
- average_round_trip_time: server.round_trip_time_averager.average_round_trip_time
240
+ new_description = Description.new(
241
+ server.address,
242
+ result,
243
+ average_round_trip_time: server.round_trip_time_calculator.average_round_trip_time,
244
+ minimum_round_trip_time: server.round_trip_time_calculator.minimum_round_trip_time
242
245
  )
243
246
 
244
247
  server.cluster.run_sdam_flow(server.description, new_description, awaited: awaited, scan_error: scan_error)
@@ -306,7 +309,7 @@ module Mongo
306
309
  end
307
310
 
308
311
  if @connection
309
- result = server.round_trip_time_averager.measure do
312
+ result = server.round_trip_time_calculator.measure do
310
313
  begin
311
314
  doc = @connection.check_document
312
315
  cmd = Protocol::Query.new(
@@ -323,7 +326,7 @@ module Mongo
323
326
  else
324
327
  connection = Connection.new(server.address, options)
325
328
  connection.connect!
326
- result = server.round_trip_time_averager.measure do
329
+ result = server.round_trip_time_calculator.measure do
327
330
  connection.handshake!
328
331
  end
329
332
  @connection = connection
@@ -110,6 +110,24 @@ module Mongo
110
110
 
111
111
  private
112
112
 
113
+ # Sends the hello command to the server, then receive and deserialize
114
+ # the response.
115
+ #
116
+ # This method is extracted to be mocked in the tests.
117
+ #
118
+ # @param [ Protocol::Message ] Command that should be sent to a server
119
+ # for handshake purposes.
120
+ #
121
+ # @return [ Mongo::Protocol::Reply ] Deserialized server response.
122
+ def get_handshake_response(hello_command)
123
+ @server.round_trip_time_calculator.measure do
124
+ add_server_diagnostics do
125
+ socket.write(hello_command.serialize.to_s)
126
+ Protocol::Message.deserialize(socket, Protocol::Message::MAX_MESSAGE_SIZE)
127
+ end
128
+ end
129
+ end
130
+
113
131
  # @param [ BSON::Document | nil ] speculative_auth_doc The document to
114
132
  # provide in speculativeAuthenticate field of handshake command.
115
133
  #
@@ -131,12 +149,7 @@ module Mongo
131
149
  doc = nil
132
150
  @server.handle_handshake_failure! do
133
151
  begin
134
- response = @server.round_trip_time_averager.measure do
135
- add_server_diagnostics do
136
- socket.write(hello_command.serialize.to_s)
137
- Protocol::Message.deserialize(socket, Protocol::Message::MAX_MESSAGE_SIZE)
138
- end
139
- end
152
+ response = get_handshake_response(hello_command)
140
153
  result = Operation::Result.new([response])
141
154
  result.validate!
142
155
  doc = result.documents.first
@@ -155,7 +168,11 @@ module Mongo
155
168
  doc['serviceId'] ||= "fake:#{rand(2**32-1)+1}"
156
169
  end
157
170
 
158
- post_handshake(doc, @server.round_trip_time_averager.average_round_trip_time)
171
+ post_handshake(
172
+ doc,
173
+ @server.round_trip_time_calculator.average_round_trip_time,
174
+ @server.round_trip_time_calculator.minimum_round_trip_time
175
+ )
159
176
 
160
177
  doc
161
178
  end
@@ -205,7 +222,7 @@ module Mongo
205
222
  #
206
223
  # @return [ Server::Description ] The server description calculated from
207
224
  # the handshake response for this particular connection.
208
- def post_handshake(response, average_rtt)
225
+ def post_handshake(response, average_rtt, minimum_rtt)
209
226
  if response["ok"] == 1
210
227
  # Auth mechanism is entirely dependent on the contents of
211
228
  # hello response *for this connection*.
@@ -18,20 +18,30 @@
18
18
  module Mongo
19
19
  class Server
20
20
  # @api private
21
- class RoundTripTimeAverager
21
+ class RoundTripTimeCalculator
22
22
 
23
23
  # The weighting factor (alpha) for calculating the average moving
24
24
  # round trip time.
25
25
  RTT_WEIGHT_FACTOR = 0.2.freeze
26
26
  private_constant :RTT_WEIGHT_FACTOR
27
27
 
28
+ RTT_SAMPLES_FOR_MINIMUM = 10
29
+ private_constant :RTT_SAMPLES_FOR_MINIMUM
30
+
31
+ MIN_SAMPLES = 3
32
+ private_constant :MIN_SAMPLES
33
+
28
34
  def initialize
29
35
  @last_round_trip_time = nil
30
36
  @average_round_trip_time = nil
37
+ @minimum_round_trip_time = 0
38
+ @lock = Mutex.new
39
+ @rtts = []
31
40
  end
32
41
 
33
42
  attr_reader :last_round_trip_time
34
43
  attr_reader :average_round_trip_time
44
+ attr_reader :minimum_round_trip_time
35
45
 
36
46
  def measure
37
47
  start = Utils.monotonic_time
@@ -44,14 +54,17 @@ module Mongo
44
54
  rescue Error, Error::AuthError => exc
45
55
  # For other errors, RTT is valid.
46
56
  end
47
- last_round_trip_time = Utils.monotonic_time - start
57
+ last_rtt = Utils.monotonic_time - start
48
58
 
49
59
  # If hello fails, we need to return the last round trip time
50
60
  # because it is used in the heartbeat failed SDAM event,
51
61
  # but we must not update the round trip time recorded in the server.
52
62
  unless exc
53
- @last_round_trip_time = last_round_trip_time
54
- update_average_round_trip_time
63
+ @last_round_trip_time = last_rtt
64
+ @lock.synchronize do
65
+ update_average_round_trip_time
66
+ update_minimum_round_trip_time
67
+ end
55
68
  end
56
69
 
57
70
  if exc
@@ -61,9 +74,6 @@ module Mongo
61
74
  end
62
75
  end
63
76
 
64
- private
65
-
66
- # This method is separate for testing purposes.
67
77
  def update_average_round_trip_time
68
78
  @average_round_trip_time = if average_round_trip_time
69
79
  RTT_WEIGHT_FACTOR * last_round_trip_time + (1 - RTT_WEIGHT_FACTOR) * average_round_trip_time
@@ -71,6 +81,14 @@ module Mongo
71
81
  last_round_trip_time
72
82
  end
73
83
  end
84
+
85
+ def update_minimum_round_trip_time
86
+ @rtts.push(last_round_trip_time) unless last_round_trip_time.nil?
87
+ @minimum_round_trip_time = 0 and return if @rtts.size < MIN_SAMPLES
88
+
89
+ @rtts.shift if @rtts.size > RTT_SAMPLES_FOR_MINIMUM
90
+ @minimum_round_trip_time = @rtts.compact.min
91
+ end
74
92
  end
75
93
  end
76
94
  end
data/lib/mongo/server.rb CHANGED
@@ -80,7 +80,7 @@ module Mongo
80
80
  include Id
81
81
  end
82
82
  @scan_semaphore = DistinguishingSemaphore.new
83
- @round_trip_time_averager = RoundTripTimeAverager.new
83
+ @round_trip_time_calculator = RoundTripTimeCalculator.new
84
84
  @description = Description.new(address, {},
85
85
  load_balancer: !!@options[:load_balancer],
86
86
  force_load_balancer: force_load_balancer?,
@@ -197,6 +197,7 @@ module Mongo
197
197
  :max_message_size,
198
198
  :tags,
199
199
  :average_round_trip_time,
200
+ :minimum_round_trip_time,
200
201
  :mongos?,
201
202
  :other?,
202
203
  :primary?,
@@ -228,9 +229,9 @@ module Mongo
228
229
  # @api private
229
230
  attr_reader :scan_semaphore
230
231
 
231
- # @return [ RoundTripTimeAverager ] Round trip time averager object.
232
+ # @return [ RoundTripTimeCalculator ] Round trip time calculator object.
232
233
  # @api private
233
- attr_reader :round_trip_time_averager
234
+ attr_reader :round_trip_time_calculator
234
235
 
235
236
  # Is this server equal to another?
236
237
  #
@@ -490,8 +491,12 @@ module Mongo
490
491
  # @return [ Object ] The result of the block execution.
491
492
  #
492
493
  # @since 2.3.0
493
- def with_connection(connection_global_id: nil, &block)
494
- pool.with_connection(connection_global_id: connection_global_id, &block)
494
+ def with_connection(connection_global_id: nil, context: nil, &block)
495
+ pool.with_connection(
496
+ connection_global_id: connection_global_id,
497
+ context: context,
498
+ &block
499
+ )
495
500
  end
496
501
 
497
502
  # Handle handshake failure.
@@ -697,5 +702,5 @@ require 'mongo/server/connection'
697
702
  require 'mongo/server/connection_pool'
698
703
  require 'mongo/server/description'
699
704
  require 'mongo/server/monitor'
700
- require 'mongo/server/round_trip_time_averager'
705
+ require 'mongo/server/round_trip_time_calculator'
701
706
  require 'mongo/server/push_monitor'
@@ -33,11 +33,11 @@ module Mongo
33
33
  #
34
34
  # @option options [ Integer ] :local_threshold The local threshold boundary for
35
35
  # nearest selection in seconds.
36
- # @option options [ Integer ] max_staleness The maximum replication lag,
36
+ # @option options [ Integer ] :max_staleness The maximum replication lag,
37
37
  # in seconds, that a secondary can suffer and still be eligible for a read.
38
38
  # A value of -1 is treated identically to nil, which is to not
39
39
  # have a maximum staleness.
40
- # @option options [ Hash | nil ] hedge A Hash specifying whether to enable hedged
40
+ # @option options [ Hash | nil ] :hedge A Hash specifying whether to enable hedged
41
41
  # reads on the server. Hedged reads are not enabled by default. When
42
42
  # specifying this option, it must be in the format: { enabled: true },
43
43
  # where the value of the :enabled key is a boolean value.
@@ -168,6 +168,8 @@ module Mongo
168
168
  # be selected from only if no other servers are available. This is
169
169
  # used to avoid selecting the same server twice in a row when
170
170
  # retrying a command.
171
+ # @param [ Float | nil ] :timeout Timeout in seconds for the operation,
172
+ # if any.
171
173
  #
172
174
  # @return [ Mongo::Server ] A server matching the server preference.
173
175
  #
@@ -178,21 +180,35 @@ module Mongo
178
180
  # lint mode is enabled.
179
181
  #
180
182
  # @since 2.0.0
181
- def select_server(cluster, ping = nil, session = nil, write_aggregation: false, deprioritized: [])
182
- select_server_impl(cluster, ping, session, write_aggregation, deprioritized).tap do |server|
183
+ def select_server(
184
+ cluster,
185
+ ping = nil,
186
+ session = nil,
187
+ write_aggregation: false,
188
+ deprioritized: [],
189
+ timeout: nil
190
+ )
191
+ select_server_impl(cluster, ping, session, write_aggregation, deprioritized, timeout).tap do |server|
183
192
  if Lint.enabled? && !server.pool.ready?
184
193
  raise Error::LintError, 'Server selector returning a server with a pool which is not ready'
185
194
  end
186
195
  end
187
196
  end
188
197
 
189
- # Parameters and return values are the same as for select_server.
190
- private def select_server_impl(cluster, ping, session, write_aggregation, deprioritized)
198
+ # Parameters and return values are the same as for select_server, only
199
+ # the +timeout+ param is renamed to +csot_timeout+.
200
+ private def select_server_impl(cluster, ping, session, write_aggregation, deprioritized, csot_timeout)
191
201
  if cluster.topology.is_a?(Cluster::Topology::LoadBalanced)
192
202
  return cluster.servers.first
193
203
  end
194
204
 
195
- server_selection_timeout = cluster.options[:server_selection_timeout] || SERVER_SELECTION_TIMEOUT
205
+ timeout = cluster.options[:server_selection_timeout] || SERVER_SELECTION_TIMEOUT
206
+
207
+ server_selection_timeout = if csot_timeout && csot_timeout > 0
208
+ [timeout, csot_timeout].min
209
+ else
210
+ timeout
211
+ end
196
212
 
197
213
  # Special handling for zero timeout: if we have to select a server,
198
214
  # and the timeout is zero, fail immediately (since server selection
@@ -638,9 +654,9 @@ module Mongo
638
654
  # state resulting from SDAM will immediately wake up this method and
639
655
  # cause it to return.
640
656
  #
641
- # If the cluster des not have a server selection semaphore, waits
657
+ # If the cluster does not have a server selection semaphore, waits
642
658
  # the smaller of 0.25 seconds and the specified remaining time.
643
- # This functionality is provided for backwards compatibilty only for
659
+ # This functionality is provided for backwards compatibility only for
644
660
  # applications directly invoking the server selection process.
645
661
  # If lint mode is enabled and the cluster does not have a server
646
662
  # selection semaphore, Error::LintError will be raised.