mongo 2.19.1 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -1
  3. data/Rakefile +83 -174
  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/topology/base.rb +16 -0
  13. data/lib/mongo/cluster.rb +41 -5
  14. data/lib/mongo/collection/helpers.rb +1 -1
  15. data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
  16. data/lib/mongo/collection/view/aggregation.rb +33 -99
  17. data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
  18. data/lib/mongo/collection/view/change_stream.rb +80 -27
  19. data/lib/mongo/collection/view/iterable.rb +92 -60
  20. data/lib/mongo/collection/view/map_reduce.rb +25 -8
  21. data/lib/mongo/collection/view/readable.rb +79 -30
  22. data/lib/mongo/collection/view/writable.rb +109 -48
  23. data/lib/mongo/collection/view.rb +44 -3
  24. data/lib/mongo/collection.rb +185 -26
  25. data/lib/mongo/config.rb +2 -2
  26. data/lib/mongo/crypt/auto_encrypter.rb +4 -6
  27. data/lib/mongo/crypt/binding.rb +4 -4
  28. data/lib/mongo/crypt/context.rb +20 -14
  29. data/lib/mongo/crypt/encryption_io.rb +56 -26
  30. data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
  31. data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
  32. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
  33. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
  34. data/lib/mongo/csot_timeout_holder.rb +119 -0
  35. data/lib/mongo/cursor/kill_spec.rb +5 -2
  36. data/lib/mongo/cursor/nontailable.rb +27 -0
  37. data/lib/mongo/cursor.rb +86 -24
  38. data/lib/mongo/cursor_host.rb +82 -0
  39. data/lib/mongo/database/view.rb +81 -14
  40. data/lib/mongo/database.rb +88 -18
  41. data/lib/mongo/error/operation_failure.rb +209 -204
  42. data/lib/mongo/error/server_timeout_error.rb +12 -0
  43. data/lib/mongo/error/socket_timeout_error.rb +3 -1
  44. data/lib/mongo/error/timeout_error.rb +23 -0
  45. data/lib/mongo/error/transactions_not_supported.rb +34 -0
  46. data/lib/mongo/error.rb +3 -0
  47. data/lib/mongo/grid/fs_bucket.rb +48 -9
  48. data/lib/mongo/grid/stream/read.rb +15 -1
  49. data/lib/mongo/grid/stream/write.rb +21 -4
  50. data/lib/mongo/index/view.rb +77 -16
  51. data/lib/mongo/monitoring/event/secure.rb +1 -1
  52. data/lib/mongo/operation/context.rb +40 -2
  53. data/lib/mongo/operation/create_search_indexes/op_msg.rb +31 -0
  54. data/lib/mongo/operation/create_search_indexes.rb +15 -0
  55. data/lib/mongo/operation/delete/op_msg.rb +2 -1
  56. data/lib/mongo/operation/drop_search_index/op_msg.rb +33 -0
  57. data/lib/mongo/operation/drop_search_index.rb +15 -0
  58. data/lib/mongo/operation/find/op_msg.rb +45 -0
  59. data/lib/mongo/operation/get_more/op_msg.rb +33 -0
  60. data/lib/mongo/operation/insert/op_msg.rb +3 -2
  61. data/lib/mongo/operation/insert/result.rb +4 -2
  62. data/lib/mongo/operation/list_collections/result.rb +1 -1
  63. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  64. data/lib/mongo/operation/op_msg_base.rb +3 -1
  65. data/lib/mongo/operation/result.rb +26 -5
  66. data/lib/mongo/operation/shared/executable.rb +55 -28
  67. data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
  68. data/lib/mongo/operation/shared/response_handling.rb +25 -27
  69. data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
  70. data/lib/mongo/operation/shared/specifiable.rb +7 -0
  71. data/lib/mongo/operation/shared/timed.rb +52 -0
  72. data/lib/mongo/operation/shared/write.rb +4 -1
  73. data/lib/mongo/operation/update/op_msg.rb +2 -1
  74. data/lib/mongo/operation/update_search_index/op_msg.rb +34 -0
  75. data/lib/mongo/operation/update_search_index.rb +15 -0
  76. data/lib/mongo/operation.rb +4 -0
  77. data/lib/mongo/protocol/message.rb +1 -4
  78. data/lib/mongo/protocol/msg.rb +2 -2
  79. data/lib/mongo/retryable/base_worker.rb +28 -3
  80. data/lib/mongo/retryable/read_worker.rb +78 -36
  81. data/lib/mongo/retryable/write_worker.rb +59 -25
  82. data/lib/mongo/retryable.rb +8 -2
  83. data/lib/mongo/search_index/view.rb +232 -0
  84. data/lib/mongo/server/app_metadata/environment.rb +64 -9
  85. data/lib/mongo/server/app_metadata.rb +5 -4
  86. data/lib/mongo/server/connection.rb +11 -5
  87. data/lib/mongo/server/connection_base.rb +22 -2
  88. data/lib/mongo/server/connection_pool.rb +32 -14
  89. data/lib/mongo/server/description/features.rb +2 -1
  90. data/lib/mongo/server/description.rb +18 -5
  91. data/lib/mongo/server/monitor.rb +7 -4
  92. data/lib/mongo/server/pending_connection.rb +25 -8
  93. data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
  94. data/lib/mongo/server.rb +11 -6
  95. data/lib/mongo/server_selector/base.rb +54 -12
  96. data/lib/mongo/session/server_session/dirtyable.rb +52 -0
  97. data/lib/mongo/session/server_session.rb +3 -0
  98. data/lib/mongo/session/session_pool.rb +12 -18
  99. data/lib/mongo/session.rb +110 -9
  100. data/lib/mongo/socket/ssl.rb +131 -18
  101. data/lib/mongo/socket/tcp.rb +40 -6
  102. data/lib/mongo/socket.rb +154 -25
  103. data/lib/mongo/uri/options_mapper.rb +1 -0
  104. data/lib/mongo/uri.rb +0 -4
  105. data/lib/mongo/version.rb +1 -5
  106. data/lib/mongo.rb +2 -0
  107. data/mongo.gemspec +9 -18
  108. data/spec/atlas/atlas_connectivity_spec.rb +9 -9
  109. data/spec/atlas/operations_spec.rb +5 -5
  110. data/spec/faas/ruby-sam-app/Gemfile +9 -0
  111. data/spec/faas/ruby-sam-app/mongodb/Gemfile +4 -0
  112. data/spec/faas/ruby-sam-app/mongodb/app.rb +149 -0
  113. data/spec/faas/ruby-sam-app/template.yaml +48 -0
  114. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
  115. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
  116. data/spec/integration/client_side_encryption/corpus_spec.rb +10 -2
  117. data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
  118. data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +67 -20
  119. data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
  120. data/spec/integration/connection_pool_populator_spec.rb +2 -0
  121. data/spec/integration/cursor_pinning_spec.rb +15 -60
  122. data/spec/integration/cursor_reaping_spec.rb +1 -1
  123. data/spec/integration/docs_examples_spec.rb +1 -1
  124. data/spec/integration/find_options_spec.rb +227 -0
  125. data/spec/integration/operation_failure_code_spec.rb +1 -1
  126. data/spec/integration/operation_failure_message_spec.rb +3 -3
  127. data/spec/integration/retryable_errors_spec.rb +2 -2
  128. data/spec/integration/retryable_reads_errors_spec.rb +196 -31
  129. data/spec/integration/retryable_writes_errors_spec.rb +156 -0
  130. data/spec/integration/sdam_error_handling_spec.rb +4 -1
  131. data/spec/integration/search_indexes_prose_spec.rb +172 -0
  132. data/spec/integration/server_spec.rb +4 -3
  133. data/spec/integration/transactions_api_examples_spec.rb +2 -0
  134. data/spec/kerberos/kerberos_spec.rb +4 -0
  135. data/spec/lite_spec_helper.rb +34 -20
  136. data/spec/mongo/auth/user/view_spec.rb +1 -1
  137. data/spec/mongo/caching_cursor_spec.rb +1 -1
  138. data/spec/mongo/client_encryption_spec.rb +1 -0
  139. data/spec/mongo/client_spec.rb +158 -4
  140. data/spec/mongo/cluster_spec.rb +36 -0
  141. data/spec/mongo/collection/view/aggregation_spec.rb +20 -40
  142. data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
  143. data/spec/mongo/collection/view/explainable_spec.rb +2 -0
  144. data/spec/mongo/collection_crud_spec.rb +2 -1
  145. data/spec/mongo/collection_spec.rb +5 -6
  146. data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
  147. data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
  148. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
  149. data/spec/mongo/crypt/handle_spec.rb +1 -1
  150. data/spec/mongo/cursor_spec.rb +26 -9
  151. data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
  152. data/spec/mongo/operation/context_spec.rb +79 -0
  153. data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
  154. data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
  155. data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
  156. data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
  157. data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
  158. data/spec/mongo/operation/insert_spec.rb +1 -1
  159. data/spec/mongo/operation/shared/csot/examples.rb +113 -0
  160. data/spec/mongo/query_cache_spec.rb +243 -225
  161. data/spec/mongo/retryable/write_worker_spec.rb +39 -0
  162. data/spec/mongo/retryable_spec.rb +1 -0
  163. data/spec/mongo/server/app_metadata/environment_spec.rb +135 -0
  164. data/spec/mongo/server/app_metadata_spec.rb +12 -2
  165. data/spec/mongo/server/connection_spec.rb +26 -0
  166. data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
  167. data/spec/mongo/session/session_pool_spec.rb +1 -16
  168. data/spec/mongo/session_transaction_spec.rb +15 -0
  169. data/spec/mongo/socket/ssl_spec.rb +0 -10
  170. data/spec/mongo/uri_spec.rb +0 -9
  171. data/spec/runners/change_streams/test.rb +2 -2
  172. data/spec/runners/crud/operation.rb +1 -1
  173. data/spec/runners/crud/test.rb +0 -8
  174. data/spec/runners/crud/verifier.rb +3 -1
  175. data/spec/runners/crud.rb +1 -1
  176. data/spec/runners/transactions/operation.rb +4 -6
  177. data/spec/runners/transactions/test.rb +12 -3
  178. data/spec/runners/unified/ambiguous_operations.rb +13 -0
  179. data/spec/runners/unified/assertions.rb +20 -3
  180. data/spec/runners/unified/change_stream_operations.rb +14 -24
  181. data/spec/runners/unified/crud_operations.rb +82 -47
  182. data/spec/runners/unified/ddl_operations.rb +38 -7
  183. data/spec/runners/unified/grid_fs_operations.rb +37 -2
  184. data/spec/runners/unified/search_index_operations.rb +63 -0
  185. data/spec/runners/unified/support_operations.rb +46 -9
  186. data/spec/runners/unified/test.rb +33 -12
  187. data/spec/runners/unified.rb +1 -1
  188. data/spec/solo/clean_exit_spec.rb +2 -0
  189. data/spec/spec_helper.rb +1 -1
  190. data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
  191. data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
  192. data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
  193. data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
  194. data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
  195. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
  196. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
  197. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
  198. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
  199. data/spec/spec_tests/data/client_side_encryption/explain.yml +2 -2
  200. data/spec/spec_tests/data/client_side_encryption/fle2v2-BypassQueryAnalysis.yml +1 -0
  201. data/spec/spec_tests/data/client_side_encryption/fle2v2-Compact.yml +1 -0
  202. data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection.yml +1 -0
  203. data/spec/spec_tests/data/client_side_encryption/fle2v2-DecryptExistingData.yml +1 -0
  204. data/spec/spec_tests/data/client_side_encryption/fle2v2-Delete.yml +1 -0
  205. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml +1 -0
  206. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-jsonSchema.yml +1 -0
  207. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFieldsMap-defaults.yml +1 -0
  208. data/spec/spec_tests/data/client_side_encryption/fle2v2-FindOneAndUpdate.yml +1 -0
  209. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Indexed.yml +1 -0
  210. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Unindexed.yml +1 -0
  211. data/spec/spec_tests/data/client_side_encryption/fle2v2-MissingKey.yml +1 -0
  212. data/spec/spec_tests/data/client_side_encryption/fle2v2-NoEncryption.yml +1 -0
  213. data/spec/spec_tests/data/client_side_encryption/fle2v2-Update.yml +1 -0
  214. data/spec/spec_tests/data/client_side_encryption/fle2v2-validatorAndPartialFieldExpression.yml +2 -1
  215. data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
  216. data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
  217. data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
  218. data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
  219. data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
  220. data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
  221. data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
  222. data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
  223. data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
  224. data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
  225. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
  226. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
  227. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
  228. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
  229. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
  230. data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
  231. data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
  232. data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
  233. data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
  234. data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
  235. data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
  236. data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
  237. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
  238. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
  239. data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
  240. data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
  241. data/spec/spec_tests/data/connection_string/invalid-uris.yml +0 -10
  242. data/spec/spec_tests/data/connection_string/valid-options.yml +13 -0
  243. data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +6 -0
  244. data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +6 -0
  245. data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +377 -0
  246. data/spec/spec_tests/data/index_management/createSearchIndex.yml +64 -0
  247. data/spec/spec_tests/data/index_management/createSearchIndexes.yml +86 -0
  248. data/spec/spec_tests/data/index_management/dropSearchIndex.yml +43 -0
  249. data/spec/spec_tests/data/index_management/listSearchIndexes.yml +91 -0
  250. data/spec/spec_tests/data/index_management/updateSearchIndex.yml +46 -0
  251. data/spec/spec_tests/data/retryable_writes/unified/bulkWrite-serverErrors.yml +3 -6
  252. data/spec/spec_tests/data/retryable_writes/unified/insertOne-serverErrors.yml +3 -6
  253. data/spec/spec_tests/data/run_command_unified/runCommand.yml +319 -0
  254. data/spec/spec_tests/data/sessions_unified/driver-sessions-dirty-session-errors.yml +351 -0
  255. data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +1 -1
  256. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +7 -7
  257. data/spec/spec_tests/data/unified/valid-pass/poc-sessions.yml +3 -4
  258. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-convenient-api.yml +1 -1
  259. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-mongos-pin-auto.yml +1 -1
  260. data/spec/spec_tests/data/unified/valid-pass/poc-transactions.yml +3 -3
  261. data/spec/spec_tests/index_management_unified_spec.rb +13 -0
  262. data/spec/spec_tests/run_command_unified_spec.rb +13 -0
  263. data/spec/spec_tests/sdam_unified_spec.rb +2 -0
  264. data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
  265. data/spec/spec_tests/transactions_unified_spec.rb +2 -1
  266. data/spec/support/certificates/atlas-ocsp-ca.crt +89 -79
  267. data/spec/support/certificates/atlas-ocsp.crt +117 -122
  268. data/spec/support/certificates/retrieve-atlas-cert +1 -1
  269. data/spec/support/cluster_tools.rb +3 -3
  270. data/spec/support/common_shortcuts.rb +2 -2
  271. data/spec/support/constraints.rb +6 -0
  272. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
  273. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
  274. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
  275. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
  276. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
  277. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
  278. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
  279. data/spec/support/ocsp +1 -1
  280. data/spec/support/recording_logger.rb +27 -0
  281. data/spec/support/shared/session.rb +2 -2
  282. data/spec/support/spec_config.rb +5 -0
  283. data/spec/support/spec_setup.rb +2 -2
  284. data/spec/support/utils.rb +3 -1
  285. metadata +1329 -1368
  286. checksums.yaml.gz.sig +0 -0
  287. data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
  288. data/spec/shared/LICENSE +0 -20
  289. data/spec/shared/bin/get-mongodb-download-url +0 -17
  290. data/spec/shared/bin/s3-copy +0 -45
  291. data/spec/shared/bin/s3-upload +0 -69
  292. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  293. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  294. data/spec/shared/lib/mrss/constraints.rb +0 -378
  295. data/spec/shared/lib/mrss/docker_runner.rb +0 -295
  296. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
  297. data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
  298. data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
  299. data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
  300. data/spec/shared/lib/mrss/session_registry.rb +0 -69
  301. data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
  302. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  303. data/spec/shared/lib/mrss/utils.rb +0 -37
  304. data/spec/shared/share/Dockerfile.erb +0 -330
  305. data/spec/shared/share/haproxy-1.conf +0 -16
  306. data/spec/shared/share/haproxy-2.conf +0 -17
  307. data/spec/shared/shlib/config.sh +0 -27
  308. data/spec/shared/shlib/distro.sh +0 -74
  309. data/spec/shared/shlib/server.sh +0 -416
  310. data/spec/shared/shlib/set_env.sh +0 -169
  311. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -241
  312. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -422
  313. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -182
  314. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -239
  315. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -235
  316. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -252
  317. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1687
  318. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -293
  319. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -905
  320. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1684
  321. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1680
  322. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1697
  323. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -329
  324. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -424
  325. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -226
  326. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -327
  327. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -319
  328. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -336
  329. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -913
  330. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -292
  331. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -518
  332. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -911
  333. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -907
  334. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -924
  335. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -325
  336. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -424
  337. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -224
  338. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -323
  339. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -319
  340. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -338
  341. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -241
  342. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -423
  343. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -182
  344. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -239
  345. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -235
  346. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -254
  347. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -241
  348. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -422
  349. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -182
  350. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -239
  351. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -235
  352. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -254
  353. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -43
  354. data/spec/spec_tests/data/cmap/pool-clear-interrupt-immediately.yml +0 -49
  355. data.tar.gz.sig +0 -0
  356. metadata.gz.sig +0 -2
@@ -59,6 +59,12 @@ module Mongo
59
59
  @file_id = @options.delete(:file_id)
60
60
  @options.freeze
61
61
  @open = true
62
+ @timeout_holder = CsotTimeoutHolder.new(
63
+ operation_timeouts: {
64
+ operation_timeout_ms: options[:timeout_ms],
65
+ inherited_timeout_ms: fs.database.timeout_ms
66
+ }
67
+ )
62
68
  end
63
69
 
64
70
  # Iterate through chunk data streamed from the FSBucket.
@@ -178,7 +184,11 @@ module Mongo
178
184
  # @since 2.1.0
179
185
  def file_info
180
186
  @file_info ||= begin
181
- doc = options[:file_info_doc] || fs.files_collection.find(_id: file_id).first
187
+ doc = options[:file_info_doc] ||
188
+ fs.files_collection.find(
189
+ { _id: file_id },
190
+ { timeout_ms: @timeout_holder.remaining_timeout_ms! }
191
+ ).first
182
192
  if doc
183
193
  File::Info.new(Options::Mapper.transform(doc, File::Info::MAPPINGS.invert))
184
194
  else
@@ -209,6 +219,10 @@ module Mongo
209
219
  else
210
220
  options
211
221
  end
222
+ if @timeout_holder.csot?
223
+ opts[:timeout_ms] = @timeout_holder.remaining_timeout_ms!
224
+ opts[:timeout_mode] = :cursor_lifetime
225
+ end
212
226
 
213
227
  fs.chunks_collection.find({ :files_id => file_id }, opts).sort(:n => 1)
214
228
  end
@@ -83,6 +83,12 @@ module Mongo
83
83
  @options.freeze
84
84
  @filename = @options[:filename]
85
85
  @open = true
86
+ @timeout_holder = CsotTimeoutHolder.new(
87
+ operation_timeouts: {
88
+ operation_timeout_ms: options[:timeout_ms],
89
+ inherited_timeout_ms: fs.database.timeout_ms
90
+ }
91
+ )
86
92
  end
87
93
 
88
94
  # Write to the GridFS bucket from the source stream or a string.
@@ -107,7 +113,12 @@ module Mongo
107
113
  end
108
114
  chunks = File::Chunk.split(io, file_info, @n)
109
115
  @n += chunks.size
110
- chunks_collection.insert_many(chunks) unless chunks.empty?
116
+ unless chunks.empty?
117
+ chunks_collection.insert_many(
118
+ chunks,
119
+ timeout_ms: @timeout_holder.remaining_timeout_ms!
120
+ )
121
+ end
111
122
  self
112
123
  end
113
124
 
@@ -124,7 +135,10 @@ module Mongo
124
135
  def close
125
136
  ensure_open!
126
137
  update_length
127
- files_collection.insert_one(file_info, @options)
138
+ files_collection.insert_one(
139
+ file_info,
140
+ @options.merge(timeout_ms: @timeout_holder.remaining_timeout_ms!)
141
+ )
128
142
  @open = false
129
143
  file_id
130
144
  end
@@ -166,7 +180,10 @@ module Mongo
166
180
  #
167
181
  # @since 2.1.0
168
182
  def abort
169
- fs.chunks_collection.find({ :files_id => file_id }, @options).delete_many
183
+ fs.chunks_collection.find(
184
+ { :files_id => file_id },
185
+ @options.merge(timeout_ms: @timeout_holder.remaining_timeout_ms!)
186
+ ).delete_many
170
187
  (@open = false) || true
171
188
  end
172
189
 
@@ -200,7 +217,7 @@ module Mongo
200
217
  end
201
218
 
202
219
  def ensure_indexes!
203
- fs.send(:ensure_indexes!)
220
+ fs.send(:ensure_indexes!, @timeout_holder)
204
221
  end
205
222
 
206
223
  def ensure_open!
@@ -15,6 +15,8 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
 
18
+ require 'mongo/cursor/nontailable'
19
+
18
20
  module Mongo
19
21
  module Index
20
22
 
@@ -25,6 +27,8 @@ module Mongo
25
27
  extend Forwardable
26
28
  include Enumerable
27
29
  include Retryable
30
+ include Mongo::CursorHost
31
+ include Cursor::NonTailable
28
32
 
29
33
  # @return [ Collection ] collection The indexes collection.
30
34
  attr_reader :collection
@@ -33,6 +37,12 @@ module Mongo
33
37
  # when sending the listIndexes command.
34
38
  attr_reader :batch_size
35
39
 
40
+ # @return [ Integer | nil | The timeout_ms value that was passed as an
41
+ # option to the view.
42
+ #
43
+ # @api private
44
+ attr_reader :operation_timeout_ms
45
+
36
46
  def_delegators :@collection, :cluster, :database, :read_preference, :write_concern, :client
37
47
  def_delegators :cluster, :next_primary
38
48
 
@@ -90,7 +100,7 @@ module Mongo
90
100
  # @since 2.0.0
91
101
  def drop_one(name, options = {})
92
102
  raise Error::MultiIndexDrop.new if name == Index::ALL
93
- drop_by_name(name, comment: options[:comment])
103
+ drop_by_name(name, options)
94
104
  end
95
105
 
96
106
  # Drop all indexes on the collection.
@@ -107,7 +117,7 @@ module Mongo
107
117
  #
108
118
  # @since 2.0.0
109
119
  def drop_all(options = {})
110
- drop_by_name(Index::ALL, comment: options[:comment])
120
+ drop_by_name(Index::ALL, options)
111
121
  end
112
122
 
113
123
  # Creates an index on the collection.
@@ -161,7 +171,7 @@ module Mongo
161
171
  if session = @options[:session]
162
172
  create_options[:session] = session
163
173
  end
164
- %i(commit_quorum session comment).each do |key|
174
+ %i(commit_quorum session comment timeout_ms max_time_ms).each do |key|
165
175
  if value = options.delete(key)
166
176
  create_options[key] = value
167
177
  end
@@ -210,7 +220,7 @@ module Mongo
210
220
  options = models.pop
211
221
  end
212
222
 
213
- client.send(:with_session, @options.merge(options)) do |session|
223
+ client.with_session(@options.merge(options)) do |session|
214
224
  server = next_primary(nil, session)
215
225
 
216
226
  indexes = normalize_models(models, server)
@@ -229,8 +239,12 @@ module Mongo
229
239
  write_concern: write_concern,
230
240
  comment: options[:comment],
231
241
  }
232
-
233
- Operation::CreateIndex.new(spec).execute(server, context: Operation::Context.new(client: client, session: session))
242
+ context = Operation::Context.new(
243
+ client: client,
244
+ session: session,
245
+ operation_timeouts: operation_timeouts(options)
246
+ )
247
+ Operation::CreateIndex.new(spec).execute(server, context: context)
234
248
  end
235
249
  end
236
250
 
@@ -263,9 +277,15 @@ module Mongo
263
277
  #
264
278
  # @since 2.0.0
265
279
  def each(&block)
266
- session = client.send(:get_session, @options)
267
- cursor = read_with_retry_cursor(session, ServerSelector.primary, self) do |server|
268
- send_initial_query(server, session)
280
+ session = client.get_session(@options)
281
+ context = Operation::Context.new(
282
+ client: client,
283
+ session: session,
284
+ operation_timeouts: operation_timeouts(@options)
285
+ )
286
+
287
+ cursor = read_with_retry_cursor(session, ServerSelector.primary, self, context: context) do |server|
288
+ send_initial_query(server, session, context)
269
289
  end
270
290
  if block_given?
271
291
  cursor.each do |doc|
@@ -283,22 +303,53 @@ module Mongo
283
303
  #
284
304
  # @param [ Collection ] collection The collection.
285
305
  # @param [ Hash ] options Options for getting a list of indexes.
286
- # Only relevant for when the listIndexes command is used with server
287
- # versions >=2.8.
288
306
  #
289
307
  # @option options [ Integer ] :batch_size The batch size for results
290
308
  # returned from the listIndexes command.
309
+ # @option options [ :cursor_lifetime | :iteration ] :timeout_mode How to interpret
310
+ # :timeout_ms (whether it applies to the lifetime of the cursor, or per
311
+ # iteration).
312
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
313
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
314
+ # The default value is unset which means the value is inherited from
315
+ # the collection or the database or the client.
291
316
  #
292
317
  # @since 2.0.0
293
318
  def initialize(collection, options = {})
294
319
  @collection = collection
320
+ @operation_timeout_ms = options.delete(:timeout_ms)
321
+
322
+ validate_timeout_mode!(options)
323
+
295
324
  @batch_size = options[:batch_size]
296
325
  @options = options
297
326
  end
298
327
 
328
+ # The timeout_ms value to use for this operation; either specified as an
329
+ # option to the view, or inherited from the collection.
330
+ #
331
+ # @return [ Integer | nil ] the timeout_ms for this operation
332
+ def timeout_ms
333
+ operation_timeout_ms || collection.timeout_ms
334
+ end
335
+
336
+ # @return [ Hash ] timeout_ms value set on the operation level (if any),
337
+ # and/or timeout_ms that is set on collection/database/client level (if any).
338
+ #
339
+ # @api private
340
+ def operation_timeouts(opts = {})
341
+ {}.tap do |result|
342
+ if opts[:timeout_ms] || operation_timeout_ms
343
+ result[:operation_timeout_ms] = opts.delete(:timeout_ms) || operation_timeout_ms
344
+ else
345
+ result[:inherited_timeout_ms] = collection.timeout_ms
346
+ end
347
+ end
348
+ end
349
+
299
350
  private
300
351
 
301
- def drop_by_name(name, comment: nil)
352
+ def drop_by_name(name, opts = {})
302
353
  client.send(:with_session, @options) do |session|
303
354
  spec = {
304
355
  db_name: database.name,
@@ -307,9 +358,14 @@ module Mongo
307
358
  session: session,
308
359
  write_concern: write_concern,
309
360
  }
310
- spec[:comment] = comment unless comment.nil?
361
+ spec[:comment] = opts[:comment] unless opts[:comment].nil?
311
362
  server = next_primary(nil, session)
312
- Operation::DropIndex.new(spec).execute(server, context: Operation::Context.new(client: client, session: session))
363
+ context = Operation::Context.new(
364
+ client: client,
365
+ session: session,
366
+ operation_timeouts: operation_timeouts(opts)
367
+ )
368
+ Operation::DropIndex.new(spec).execute(server, context: context)
313
369
  end
314
370
  end
315
371
 
@@ -347,8 +403,13 @@ module Mongo
347
403
  end
348
404
  end
349
405
 
350
- def send_initial_query(server, session)
351
- initial_query_op(session).execute(server, context: Operation::Context.new(client: client, session: session))
406
+ def send_initial_query(server, session, context)
407
+ if server.load_balancer?
408
+ connection = server.pool.check_out(context: context)
409
+ initial_query_op(session).execute_with_connection(connection, context: context)
410
+ else
411
+ initial_query_op(session).execute(server, context: context)
412
+ end
352
413
  end
353
414
  end
354
415
  end
@@ -58,7 +58,7 @@ module Mongo
58
58
  # According to Command Monitoring spec,for hello/legacy hello commands
59
59
  # when speculativeAuthenticate is present, their commands AND replies
60
60
  # MUST be redacted from the events.
61
- # See https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#security
61
+ # See https://github.com/mongodb/specifications/blob/master/source/command-logging-and-monitoring/command-logging-and-monitoring.rst#security
62
62
  true
63
63
  else
64
64
  false
@@ -34,8 +34,15 @@ module Mongo
34
34
  # operations.
35
35
  #
36
36
  # @api private
37
- class Context
38
- def initialize(client: nil, session: nil, connection_global_id: nil, options: nil)
37
+ class Context < CsotTimeoutHolder
38
+ def initialize(
39
+ client: nil,
40
+ session: nil,
41
+ connection_global_id: nil,
42
+ operation_timeouts: {},
43
+ view: nil,
44
+ options: nil
45
+ )
39
46
  if options
40
47
  if client
41
48
  raise ArgumentError, 'Client and options cannot both be specified'
@@ -52,14 +59,33 @@ module Mongo
52
59
 
53
60
  @client = client
54
61
  @session = session
62
+ @view = view
55
63
  @connection_global_id = connection_global_id
56
64
  @options = options
65
+ super(session: session, operation_timeouts: operation_timeouts)
57
66
  end
58
67
 
59
68
  attr_reader :client
60
69
  attr_reader :session
70
+ attr_reader :view
61
71
  attr_reader :options
62
72
 
73
+ # Returns a new Operation::Context with the deadline refreshed
74
+ # and relative to the current moment.
75
+ #
76
+ # @return [ Operation::Context ] the refreshed context
77
+ def refresh(connection_global_id: @connection_global_id, timeout_ms: nil, view: nil)
78
+ operation_timeouts = @operation_timeouts
79
+ operation_timeouts = operation_timeouts.merge(operation_timeout_ms: timeout_ms) if timeout_ms
80
+
81
+ self.class.new(client: client,
82
+ session: session,
83
+ connection_global_id: connection_global_id,
84
+ operation_timeouts: operation_timeouts,
85
+ view: view || self.view,
86
+ options: options)
87
+ end
88
+
63
89
  def connection_global_id
64
90
  @connection_global_id || session&.pinned_connection_global_id
65
91
  end
@@ -122,10 +148,18 @@ module Mongo
122
148
  client&.encrypter&.encrypt? || false
123
149
  end
124
150
 
151
+ def encrypt(db_name, cmd)
152
+ encrypter.encrypt(db_name, cmd, self)
153
+ end
154
+
125
155
  def decrypt?
126
156
  !!client&.encrypter
127
157
  end
128
158
 
159
+ def decrypt(cmd)
160
+ encrypter.decrypt(cmd, self)
161
+ end
162
+
129
163
  def encrypter
130
164
  if client&.encrypter
131
165
  client.encrypter
@@ -133,6 +167,10 @@ module Mongo
133
167
  raise Error::InternalDriverError, 'Encrypter should only be accessed when encryption is to be performed'
134
168
  end
135
169
  end
170
+
171
+ def inspect
172
+ "#<#{self.class} connection_global_id=#{connection_global_id.inspect} deadline=#{deadline.inspect} options=#{options.inspect} operation_timeouts=#{operation_timeouts.inspect}>"
173
+ end
136
174
  end
137
175
  end
138
176
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongo
4
+ module Operation
5
+ class CreateSearchIndexes
6
+ # A MongoDB createSearchIndexes operation sent as an op message.
7
+ #
8
+ # @api private
9
+ class OpMsg < OpMsgBase
10
+ include ExecutableTransactionLabel
11
+
12
+ private
13
+
14
+ # Returns the command to send to the database, describing the
15
+ # desired createSearchIndexes operation.
16
+ #
17
+ # @param [ Connection ] _connection the connection that will receive the
18
+ # command
19
+ #
20
+ # @return [ Hash ] the selector
21
+ def selector(_connection)
22
+ {
23
+ createSearchIndexes: coll_name,
24
+ :$db => db_name,
25
+ indexes: indexes,
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mongo/operation/create_search_indexes/op_msg'
4
+
5
+ module Mongo
6
+ module Operation
7
+ # A MongoDB createSearchIndexes command operation.
8
+ #
9
+ # @api private
10
+ class CreateSearchIndexes
11
+ include Specifiable
12
+ include OpMsgExecutable
13
+ end
14
+ end
15
+ end
@@ -49,7 +49,8 @@ module Mongo
49
49
 
50
50
  def message(connection)
51
51
  section = Protocol::Msg::Section1.new(IDENTIFIER, send(IDENTIFIER))
52
- Protocol::Msg.new(flags, {}, command(connection), section)
52
+ cmd = apply_relevant_timeouts_to(command(connection), connection)
53
+ Protocol::Msg.new(flags, {}, cmd, section)
53
54
  end
54
55
  end
55
56
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongo
4
+ module Operation
5
+ class DropSearchIndex
6
+ # A MongoDB createSearchIndexes operation sent as an op message.
7
+ #
8
+ # @api private
9
+ class OpMsg < OpMsgBase
10
+ include ExecutableTransactionLabel
11
+
12
+ private
13
+
14
+ # Returns the command to send to the database, describing the
15
+ # desired dropSearchIndex operation.
16
+ #
17
+ # @param [ Connection ] _connection the connection that will receive the
18
+ # command
19
+ #
20
+ # @return [ Hash ] the selector
21
+ def selector(_connection)
22
+ {
23
+ dropSearchIndex: coll_name,
24
+ :$db => db_name,
25
+ }.tap do |sel|
26
+ sel[:id] = index_id if index_id
27
+ sel[:name] = index_name if index_name
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mongo/operation/drop_search_index/op_msg'
4
+
5
+ module Mongo
6
+ module Operation
7
+ # A MongoDB dropSearchIndex command operation.
8
+ #
9
+ # @api private
10
+ class DropSearchIndex
11
+ include Specifiable
12
+ include OpMsgExecutable
13
+ end
14
+ end
15
+ end
@@ -31,6 +31,51 @@ module Mongo
31
31
 
32
32
  private
33
33
 
34
+ # Applies the relevant CSOT timeouts for a find command.
35
+ # Considers the cursor type and timeout mode and will add (or omit) a
36
+ # maxTimeMS field accordingly.
37
+ def apply_relevant_timeouts_to(spec, connection)
38
+ with_max_time(connection) do |max_time_sec|
39
+ timeout_ms = max_time_sec ? (max_time_sec * 1_000).to_i : nil
40
+ apply_find_timeouts_to(spec, timeout_ms) unless connection.description.mongocryptd?
41
+ end
42
+ end
43
+
44
+ def apply_find_timeouts_to(spec, timeout_ms)
45
+ view = context&.view
46
+ return spec unless view
47
+
48
+ case view.cursor_type
49
+ when nil # non-tailable
50
+ if view.timeout_mode == :cursor_lifetime
51
+ spec[:maxTimeMS] = timeout_ms || view.options[:max_time_ms]
52
+ else # timeout_mode == :iterable
53
+ # drivers MUST honor the timeoutMS option for the initial command
54
+ # but MUST NOT append a maxTimeMS field to the command sent to the
55
+ # server
56
+ if !timeout_ms && view.options[:max_time_ms]
57
+ spec[:maxTimeMS] = view.options[:max_time_ms]
58
+ end
59
+ end
60
+
61
+ when :tailable
62
+ # If timeoutMS is set, drivers...MUST NOT append a maxTimeMS field to any commands.
63
+ if !timeout_ms && view.options[:max_time_ms]
64
+ spec[:maxTimeMS] = view.options[:max_time_ms]
65
+ end
66
+
67
+ when :tailable_await
68
+ # The server supports the maxTimeMS option for the original command.
69
+ if timeout_ms || view.options[:max_time_ms]
70
+ spec[:maxTimeMS] = timeout_ms || view.options[:max_time_ms]
71
+ end
72
+ end
73
+
74
+ spec.tap do |spc|
75
+ spc.delete(:maxTimeMS) if spc[:maxTimeMS].nil?
76
+ end
77
+ end
78
+
34
79
  def selector(connection)
35
80
  # The mappings are BSON::Documents and as such store keys as
36
81
  # strings, the spec here has symbol keys.
@@ -28,6 +28,39 @@ module Mongo
28
28
  include ExecutableTransactionLabel
29
29
  include PolymorphicResult
30
30
  include CommandBuilder
31
+
32
+ private
33
+
34
+ # Applies the relevant CSOT timeouts for a getMore command.
35
+ # Considers the cursor type and timeout mode and will add (or omit) a
36
+ # maxTimeMS field accordingly.
37
+ def apply_relevant_timeouts_to(spec, connection)
38
+ with_max_time(connection) do |max_time_sec|
39
+ timeout_ms = max_time_sec ? (max_time_sec * 1_000).to_i : nil
40
+ apply_get_more_timeouts_to(spec, timeout_ms)
41
+ end
42
+ end
43
+
44
+ def apply_get_more_timeouts_to(spec, timeout_ms)
45
+ view = context&.view
46
+ return spec unless view
47
+
48
+ if view.cursor_type == :tailable_await
49
+ # If timeoutMS is set, drivers MUST apply it to the original operation.
50
+ # Drivers MUST also apply the original timeoutMS value to each next
51
+ # call on the resulting cursor but MUST NOT use it to derive a
52
+ # maxTimeMS value for getMore commands. Helpers for operations that
53
+ # create tailable awaitData cursors MUST also support the
54
+ # maxAwaitTimeMS option. Drivers MUST error if this option is set,
55
+ # timeoutMS is set to a non-zero value, and maxAwaitTimeMS is greater
56
+ # than or equal to timeoutMS. If this option is set, drivers MUST use
57
+ # it as the maxTimeMS field on getMore commands.
58
+ max_await_time_ms = view.respond_to?(:max_await_time_ms) ? view.max_await_time_ms : nil
59
+ spec[:maxTimeMS] = max_await_time_ms if max_await_time_ms
60
+ end
61
+
62
+ spec
63
+ end
31
64
  end
32
65
  end
33
66
  end
@@ -35,7 +35,7 @@ module Mongo
35
35
 
36
36
  def get_result(connection, context, options = {})
37
37
  # This is a Mongo::Operation::Insert::Result
38
- Result.new(*dispatch_message(connection, context), @ids)
38
+ Result.new(*dispatch_message(connection, context), @ids, context: context)
39
39
  end
40
40
 
41
41
  def selector(connection)
@@ -49,7 +49,8 @@ module Mongo
49
49
 
50
50
  def message(connection)
51
51
  section = Protocol::Msg::Section1.new(IDENTIFIER, send(IDENTIFIER))
52
- Protocol::Msg.new(flags, {}, command(connection), section)
52
+ cmd = apply_relevant_timeouts_to(command(connection), connection)
53
+ Protocol::Msg.new(flags, {}, cmd, section)
53
54
  end
54
55
  end
55
56
  end
@@ -47,11 +47,13 @@ module Mongo
47
47
  # Global id of the connection on which the operation that
48
48
  # this result is for was performed.
49
49
  # @param [ Array<Object> ] ids The ids of the inserted documents.
50
+ # @param [ Operation::Context | nil ] context the operation context that
51
+ # was active when this result was produced.
50
52
  #
51
53
  # @since 2.0.0
52
54
  # @api private
53
- def initialize(replies, connection_description, connection_global_id, ids)
54
- super(replies, connection_description, connection_global_id)
55
+ def initialize(replies, connection_description, connection_global_id, ids, context: nil)
56
+ super(replies, connection_description, connection_global_id, context: context)
55
57
  @inserted_ids = ids
56
58
  end
57
59
 
@@ -85,7 +85,7 @@ module Mongo
85
85
  if successful?
86
86
  self
87
87
  else
88
- raise Error::OperationFailure.new(
88
+ raise operation_failure_class.new(
89
89
  parser.message,
90
90
  self,
91
91
  code: parser.code,
@@ -108,7 +108,7 @@ module Mongo
108
108
  # @example Validate the result.
109
109
  # result.validate!
110
110
  #
111
- # @raise [ Error::OperationFailure ] If an error is in the result.
111
+ # @raise [ Error::OperationFailure::Family ] If an error is in the result.
112
112
  #
113
113
  # @return [ Result ] The result if verification passed.
114
114
  #
@@ -22,11 +22,13 @@ module Mongo
22
22
  include Specifiable
23
23
  include Executable
24
24
  include SessionsSupported
25
+ include Timed
25
26
 
26
27
  private
27
28
 
28
29
  def message(connection)
29
- Protocol::Msg.new(flags, options(connection), command(connection))
30
+ cmd = apply_relevant_timeouts_to(command(connection), connection)
31
+ Protocol::Msg.new(flags, options(connection), cmd)
30
32
  end
31
33
  end
32
34
  end