mongo 2.20.0 → 2.21.0

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 281c66c9e5d92b0eb8040c342bb0dfcf554c9b5420ec803bc68748472d74a1ae
4
- data.tar.gz: 423f31b24accb3ce674ea28a7aa8fcaf028730eb1370187c23f5304ba30698f6
3
+ metadata.gz: 5e7f3e9918313d274cc9e065268b75d760d24491b959f7b04cdad49dd0ff38f4
4
+ data.tar.gz: 5071ce689f3c0027ce39c93cd662b355235a2b1728f6308c716eecbaa7b55420
5
5
  SHA512:
6
- metadata.gz: 4f414d30bf15f7c32ac9181e25e707caa80447975690fc6c0eb9d8fa37a784f8c4d21125b385d5a6d7efdb4bd751ee2c9c4bea313adbf78d20de3b019c25ac8a
7
- data.tar.gz: 7a83ba71f6a36d886769d755fb5ea45e6d1fae37bd92b490c58e9f643f51c25d5a489ed79928d67975f067d258c738f54cc3e5caecca6eb0bad2e2bf49d81613
6
+ metadata.gz: d8c716a1754d4d2c704a3dd8ed6fcdc5815a0818168598fbe885886f6962f07182333ce8a68ada32cf0bd5d4664d102c301d97e611bac5a126201b6c3e986597
7
+ data.tar.gz: 1365727e6aa93fa15ab46c058f6d3d553a16e8f06b400f915f37c326f9a3393cbf90c6a585a37c8e9a5b9f8e625fcf8443adc487bb0b29b617ffdf71c9991b75
data/README.md CHANGED
@@ -5,7 +5,43 @@ MongoDB Ruby Driver
5
5
 
6
6
  The officially supported Ruby driver for [MongoDB](https://www.mongodb.org/).
7
7
 
8
- The Ruby driver supports Ruby 2.5-3.0 and JRuby 9.2.
8
+ The Ruby driver supports Ruby 2.7-3.3 and JRuby 9.3-9.4.
9
+
10
+ ## Installation
11
+
12
+ Install via RubyGems, either via the command-line for ad-hoc uses:
13
+
14
+ $ gem install mongo
15
+
16
+ Or via a Gemfile for more general use:
17
+
18
+ gem 'mongo'
19
+
20
+ ### Release Integrity
21
+
22
+ Each release of the MongoDB Ruby driver after version 2.20.0 has been automatically built and signed using the team's GPG key.
23
+
24
+ To verify the driver's gem file:
25
+
26
+ 1. [Download the GPG key](https://pgp.mongodb.com/ruby-driver.asc).
27
+ 2. Import the key into your GPG keyring with `gpg --import ruby-driver.asc`.
28
+ 3. Download the gem file (if you don't already have it). You can download it from RubyGems with `gem fetch mongo`, or you can download it from the [releases page](https://github.com/mongodb/mongo-ruby-driver/releases) on GitHub.
29
+ 4. Download the corresponding detached signature file from the [same release](https://github.com/mongodb/mongo-ruby-driver/releases). Look at the bottom of the release that corresponds to the gem file, under the 'Assets' list, for a `.sig` file with the same version number as the gem you wish to install.
30
+ 5. Verify the gem with `gpg --verify mongo-X.Y.Z.gem.sig mongo-X.Y.Z.gem` (replacing `X.Y.Z` with the actual version number).
31
+
32
+ You are looking for text like "Good signature from "MongoDB Ruby Driver Release Signing Key <packaging@mongodb.com>" in the output. If you see that, the signature was found to correspond to the given gem file.
33
+
34
+ (Note that other output, like "This key is not certified with a trusted signature!", is related to *web of trust* and depends on how strongly you, personally, trust the `ruby-driver.asc` key that you downloaded from us. To learn more, see https://www.gnupg.org/gph/en/manual/x334.html)
35
+
36
+ ### Why not use RubyGems' gem-signing functionality?
37
+
38
+ RubyGems' own gem signing is problematic, most significantly because there is no established chain of trust related to the keys used to sign gems. RubyGems' own documentation admits that "this method of signing gems is not widely used" (see https://guides.rubygems.org/security/). Discussions about this in the RubyGems community have been off-and-on for more than a decade, and while a solution will eventually arrive, we have settled on using GPG instead for the following reasons:
39
+
40
+ 1. Many of the other driver teams at MongoDB are using GPG to sign their product releases. Consistency with the other teams means that we can reuse existing tooling for our own product releases.
41
+ 2. GPG is widely available and has existing tools and procedures for dealing with web of trust (though they are admittedly quite arcane and intimidating to the uninitiated, unfortunately).
42
+
43
+ Ultimately, most users do not bother to verify gems, and will not be impacted by our choice of GPG over RubyGems' native method.
44
+
9
45
 
10
46
  ## Documentation
11
47
 
@@ -17,6 +53,9 @@ API documentation for the most recent release can be found
17
53
  To build API documentation for the master branch, check out the
18
54
  repository locally and run `rake docs`.
19
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
+
20
59
  ## Support
21
60
 
22
61
  Commercial support for the driver is available through the
data/Rakefile CHANGED
@@ -2,17 +2,12 @@
2
2
  # rubocop:todo all
3
3
 
4
4
  require 'bundler'
5
- require 'bundler/gem_tasks'
6
5
  require 'rspec/core/rake_task'
7
- # TODO move the mongo require into the individual tasks that actually need it
8
- require 'mongo'
9
6
 
10
7
  ROOT = File.expand_path(File.join(File.dirname(__FILE__)))
11
8
 
12
9
  $: << File.join(ROOT, 'spec/shared/lib')
13
10
 
14
- require 'mrss/spec_organizer'
15
-
16
11
  CLASSIFIERS = [
17
12
  [%r,^mongo/server,, :unit_server],
18
13
  [%r,^mongo,, :unit],
@@ -26,15 +21,12 @@ CLASSIFIERS = [
26
21
  [%r,^spec_tests,, :spec],
27
22
  ]
28
23
 
29
- RUN_PRIORITY = %i(
24
+ RUN_PRIORITY = (ENV['RUN_PRIORITY'] || %(
30
25
  tx_examples
31
26
  unit unit_server
32
27
  integration sdam_integration cursor_reaping query_cache
33
28
  spec spec_sdam_integration
34
- )
35
-
36
- tasks = Rake.application.instance_variable_get('@tasks')
37
- tasks['release:do'] = tasks.delete('release')
29
+ )).split.map(&:to_sym)
38
30
 
39
31
  RSpec::Core::RakeTask.new(:spec) do |t|
40
32
  #t.rspec_opts = "--profile 5" if ENV['CI']
@@ -42,9 +34,61 @@ end
42
34
 
43
35
  task :default => ['spec:prepare', :spec]
44
36
 
37
+ # stands in for the Bundler-provided `build` task, which builds the
38
+ # gem for this project. Our release process builds the gems in a
39
+ # particular way, in a GitHub action. This task is just to help remind
40
+ # developers of that fact.
41
+ task :build do
42
+ abort <<~WARNING
43
+ `rake build` does nothing in this project. The gem must be built via
44
+ the `Driver Release` action on GitHub, which is triggered manually when
45
+ a new release is ready.
46
+ WARNING
47
+ end
48
+
49
+ # `rake version` is used by the deployment system so get the release version
50
+ # of the product beng deployed. It must do nothing more than just print the
51
+ # product version number.
52
+ #
53
+ # See the mongodb-labs/driver-github-tools/ruby/publish Github action.
54
+ desc "Print the current value of Mongo::VERSION"
55
+ task :version do
56
+ require 'mongo/version'
57
+
58
+ puts Mongo::VERSION
59
+ end
60
+
61
+ # overrides the default Bundler-provided `release` task, which also
62
+ # builds the gem. Our release process assumes the gem has already
63
+ # been built (and signed via GPG), so we just need `rake release` to
64
+ # push the gem to rubygems.
65
+ task :release do
66
+ require 'mongo/version'
67
+
68
+ if ENV['GITHUB_ACTION'].nil?
69
+ abort <<~WARNING
70
+ `rake release` must be invoked from the `Driver Release` GitHub action,
71
+ and must not be invoked locally. This ensures the gem is properly signed
72
+ and distributed by the appropriate user.
73
+
74
+ Note that it is the `rubygems/release-gem@v1` step in the `Driver Release`
75
+ action that invokes this task. Do not rename or remove this task, or the
76
+ release-gem step will fail. Reimplement this task with caution.
77
+
78
+ mongo-#{Mongo::VERSION}.gem was NOT pushed to RubyGems.
79
+ WARNING
80
+ end
81
+
82
+ system 'gem', 'push', "mongo-#{Mongo::VERSION}.gem"
83
+ end
84
+
85
+ task :mongo do
86
+ require 'mongo'
87
+ end
88
+
45
89
  namespace :spec do
46
90
  desc 'Creates necessary user accounts in the cluster'
47
- task :prepare do
91
+ task prepare: :mongo do
48
92
  $: << File.join(File.dirname(__FILE__), 'spec')
49
93
 
50
94
  require 'support/utils'
@@ -53,7 +97,7 @@ namespace :spec do
53
97
  end
54
98
 
55
99
  desc 'Waits for sessions to be available in the deployment'
56
- task :wait_for_sessions do
100
+ task wait_for_sessions: :mongo do
57
101
  $: << File.join(File.dirname(__FILE__), 'spec')
58
102
 
59
103
  require 'support/utils'
@@ -77,7 +121,7 @@ namespace :spec do
77
121
  end
78
122
 
79
123
  desc 'Prints configuration used by the test suite'
80
- task :config do
124
+ task config: :mongo do
81
125
  $: << File.join(File.dirname(__FILE__), 'spec')
82
126
 
83
127
  # Since this task is usually used for troubleshooting of test suite
@@ -90,6 +134,8 @@ namespace :spec do
90
134
  end
91
135
 
92
136
  def spec_organizer
137
+ require 'mrss/spec_organizer'
138
+
93
139
  Mrss::SpecOrganizer.new(
94
140
  root: ROOT,
95
141
  classifiers: CLASSIFIERS,
@@ -109,16 +155,6 @@ namespace :spec do
109
155
  end
110
156
  end
111
157
 
112
- namespace :release do
113
- task :check_private_key do
114
- unless File.exist?('gem-private_key.pem')
115
- raise "No private key present, cannot release"
116
- end
117
- end
118
- end
119
-
120
- task :release => ['release:check_private_key', 'release:do']
121
-
122
158
  desc 'Build and validate the evergreen config'
123
159
  task eg: %w[ eg:build eg:validate ]
124
160
 
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.