mongo 2.8.0 → 2.9.0.rc0

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 (276) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +12 -0
  5. data/lib/mongo.rb +15 -1
  6. data/lib/mongo/address/ipv6.rb +0 -2
  7. data/lib/mongo/auth/scram/conversation.rb +0 -3
  8. data/lib/mongo/bulk_write/result_combiner.rb +12 -2
  9. data/lib/mongo/client.rb +59 -6
  10. data/lib/mongo/cluster.rb +19 -8
  11. data/lib/mongo/cluster/reapers/cursor_reaper.rb +0 -2
  12. data/lib/mongo/cluster/reapers/socket_reaper.rb +12 -9
  13. data/lib/mongo/collection.rb +1 -1
  14. data/lib/mongo/collection/view/aggregation.rb +5 -1
  15. data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
  16. data/lib/mongo/collection/view/change_stream.rb +30 -10
  17. data/lib/mongo/collection/view/iterable.rb +13 -6
  18. data/lib/mongo/collection/view/map_reduce.rb +12 -10
  19. data/lib/mongo/collection/view/readable.rb +19 -14
  20. data/lib/mongo/cursor.rb +12 -8
  21. data/lib/mongo/database.rb +10 -7
  22. data/lib/mongo/database/view.rb +18 -11
  23. data/lib/mongo/error.rb +2 -2
  24. data/lib/mongo/error/connection_check_out_timeout.rb +49 -0
  25. data/lib/mongo/error/operation_failure.rb +9 -9
  26. data/lib/mongo/error/parser.rb +25 -3
  27. data/lib/mongo/error/pool_closed_error.rb +43 -0
  28. data/lib/mongo/error/sdam_error_detection.rb +18 -0
  29. data/lib/mongo/grid/file/chunk.rb +0 -2
  30. data/lib/mongo/grid/fs_bucket.rb +26 -12
  31. data/lib/mongo/grid/stream/read.rb +36 -21
  32. data/lib/mongo/index/view.rb +11 -7
  33. data/lib/mongo/logger.rb +0 -2
  34. data/lib/mongo/monitoring.rb +31 -0
  35. data/lib/mongo/monitoring/cmap_log_subscriber.rb +53 -0
  36. data/lib/mongo/monitoring/event.rb +1 -0
  37. data/lib/mongo/monitoring/event/cmap.rb +25 -0
  38. data/lib/mongo/monitoring/event/cmap/base.rb +28 -0
  39. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +78 -0
  40. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +56 -0
  41. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +63 -0
  42. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +64 -0
  43. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +103 -0
  44. data/lib/mongo/monitoring/event/cmap/connection_created.rb +64 -0
  45. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +64 -0
  46. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +57 -0
  47. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +57 -0
  48. data/lib/mongo/monitoring/event/cmap/pool_created.rb +63 -0
  49. data/lib/mongo/monitoring/event/command_started.rb +12 -3
  50. data/lib/mongo/monitoring/publishable.rb +10 -2
  51. data/lib/mongo/operation.rb +0 -1
  52. data/lib/mongo/operation/find/legacy/result.rb +1 -0
  53. data/lib/mongo/operation/list_collections/result.rb +7 -1
  54. data/lib/mongo/operation/result.rb +10 -1
  55. data/lib/mongo/operation/shared/executable.rb +15 -0
  56. data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +29 -0
  57. data/lib/mongo/operation/shared/specifiable.rb +0 -16
  58. data/lib/mongo/operation/update/legacy/result.rb +1 -0
  59. data/lib/mongo/protocol/compressed.rb +0 -2
  60. data/lib/mongo/protocol/msg.rb +25 -2
  61. data/lib/mongo/retryable.rb +171 -33
  62. data/lib/mongo/server.rb +26 -7
  63. data/lib/mongo/server/app_metadata.rb +0 -2
  64. data/lib/mongo/server/connectable.rb +8 -2
  65. data/lib/mongo/server/connection.rb +83 -13
  66. data/lib/mongo/server/connection_base.rb +1 -1
  67. data/lib/mongo/server/connection_pool.rb +439 -43
  68. data/lib/mongo/server/monitor/connection.rb +4 -1
  69. data/lib/mongo/session.rb +37 -5
  70. data/lib/mongo/session/session_pool.rb +2 -2
  71. data/lib/mongo/socket.rb +0 -2
  72. data/lib/mongo/socket/ssl.rb +0 -2
  73. data/lib/mongo/uri.rb +127 -66
  74. data/lib/mongo/uri/srv_protocol.rb +35 -13
  75. data/lib/mongo/version.rb +1 -1
  76. data/spec/README.md +190 -63
  77. data/spec/integration/change_stream_spec.rb +64 -0
  78. data/spec/integration/command_spec.rb +0 -7
  79. data/spec/integration/error_detection_spec.rb +39 -0
  80. data/spec/integration/read_concern.rb +83 -0
  81. data/spec/integration/retryable_writes_spec.rb +6 -50
  82. data/spec/integration/sdam_error_handling_spec.rb +60 -7
  83. data/spec/integration/ssl_uri_options_spec.rb +24 -0
  84. data/spec/integration/step_down_spec.rb +197 -0
  85. data/spec/lite_spec_helper.rb +4 -0
  86. data/spec/mongo/client_construction_spec.rb +42 -17
  87. data/spec/mongo/client_spec.rb +32 -1
  88. data/spec/mongo/cluster/socket_reaper_spec.rb +2 -2
  89. data/spec/mongo/cluster_spec.rb +36 -2
  90. data/spec/mongo/collection/view/aggregation_spec.rb +2 -0
  91. data/spec/mongo/collection/view/change_stream_spec.rb +28 -28
  92. data/spec/mongo/collection/view/readable_spec.rb +1 -1
  93. data/spec/mongo/collection/view_spec.rb +3 -1
  94. data/spec/mongo/cursor_spec.rb +5 -5
  95. data/spec/mongo/error/parser_spec.rb +61 -1
  96. data/spec/mongo/grid/stream/read_spec.rb +2 -2
  97. data/spec/mongo/monitoring/event/cmap/connection_check_out_failed_spec.rb +23 -0
  98. data/spec/mongo/monitoring/event/cmap/connection_check_out_started_spec.rb +19 -0
  99. data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +23 -0
  100. data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +23 -0
  101. data/spec/mongo/monitoring/event/cmap/connection_closed_spec.rb +27 -0
  102. data/spec/mongo/monitoring/event/cmap/connection_created_spec.rb +24 -0
  103. data/spec/mongo/monitoring/event/cmap/connection_ready_spec.rb +24 -0
  104. data/spec/mongo/monitoring/event/cmap/pool_cleared_spec.rb +19 -0
  105. data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +19 -0
  106. data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +26 -0
  107. data/spec/mongo/operation/delete/bulk_spec.rb +1 -6
  108. data/spec/mongo/operation/delete/command_spec.rb +1 -1
  109. data/spec/mongo/operation/delete/op_msg_spec.rb +1 -1
  110. data/spec/mongo/operation/delete_spec.rb +4 -4
  111. data/spec/mongo/operation/insert/bulk_spec.rb +1 -1
  112. data/spec/mongo/operation/insert/command_spec.rb +1 -1
  113. data/spec/mongo/operation/insert/op_msg_spec.rb +1 -1
  114. data/spec/mongo/operation/update/bulk_spec.rb +1 -1
  115. data/spec/mongo/operation/update/command_spec.rb +2 -2
  116. data/spec/mongo/operation/update/op_msg_spec.rb +2 -2
  117. data/spec/mongo/protocol/msg_spec.rb +11 -0
  118. data/spec/mongo/retryable_spec.rb +78 -25
  119. data/spec/mongo/server/connection_pool_spec.rb +661 -126
  120. data/spec/mongo/server/connection_spec.rb +55 -7
  121. data/spec/mongo/server_spec.rb +5 -0
  122. data/spec/mongo/uri/srv_protocol_spec.rb +135 -2
  123. data/spec/mongo/uri_option_parsing_spec.rb +511 -0
  124. data/spec/mongo/uri_spec.rb +42 -6
  125. data/spec/spec_helper.rb +1 -84
  126. data/spec/spec_tests/cmap_spec.rb +50 -0
  127. data/spec/spec_tests/command_monitoring_spec.rb +7 -18
  128. data/spec/spec_tests/crud_spec.rb +3 -49
  129. data/spec/spec_tests/data/cmap/connection-must-have-id.yml +21 -0
  130. data/spec/spec_tests/data/cmap/connection-must-order-ids.yml +21 -0
  131. data/spec/spec_tests/data/cmap/pool-checkin-destroy-closed.yml +24 -0
  132. data/spec/spec_tests/data/cmap/pool-checkin-destroy-stale.yml +24 -0
  133. data/spec/spec_tests/data/cmap/pool-checkin-make-available.yml +21 -0
  134. data/spec/spec_tests/data/cmap/pool-checkin.yml +18 -0
  135. data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +13 -0
  136. data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +28 -0
  137. data/spec/spec_tests/data/cmap/pool-checkout-multiple.yml +34 -0
  138. data/spec/spec_tests/data/cmap/pool-checkout-no-idle.yml +31 -0
  139. data/spec/spec_tests/data/cmap/pool-checkout-no-stale.yml +29 -0
  140. data/spec/spec_tests/data/cmap/pool-close-destroy-conns.yml +26 -0
  141. data/spec/spec_tests/data/cmap/pool-close.yml +11 -0
  142. data/spec/spec_tests/data/cmap/pool-create-max-size.yml +56 -0
  143. data/spec/spec_tests/data/cmap/pool-create-min-size.yml +27 -0
  144. data/spec/spec_tests/data/cmap/pool-create-with-options.yml +20 -0
  145. data/spec/spec_tests/data/cmap/pool-create.yml +12 -0
  146. data/spec/spec_tests/data/cmap/wait-queue-fairness.yml +94 -0
  147. data/spec/spec_tests/data/cmap/wait-queue-timeout.yml +41 -0
  148. data/spec/spec_tests/data/retryable_reads/aggregate-serverErrors.yml +157 -0
  149. data/spec/spec_tests/data/retryable_reads/aggregate.yml +87 -0
  150. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +149 -0
  151. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +61 -0
  152. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +149 -0
  153. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +65 -0
  154. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +153 -0
  155. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +61 -0
  156. data/spec/spec_tests/data/retryable_reads/count-serverErrors.yml +150 -0
  157. data/spec/spec_tests/data/retryable_reads/count.yml +64 -0
  158. data/spec/spec_tests/data/retryable_reads/countDocuments-serverErrors.yml +150 -0
  159. data/spec/spec_tests/data/retryable_reads/countDocuments.yml +64 -0
  160. data/spec/spec_tests/data/retryable_reads/distinct-serverErrors.yml +156 -0
  161. data/spec/spec_tests/data/retryable_reads/distinct.yml +71 -0
  162. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors.yml +148 -0
  163. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount.yml +62 -0
  164. data/spec/spec_tests/data/retryable_reads/find-serverErrors.yml +160 -0
  165. data/spec/spec_tests/data/retryable_reads/find.yml +86 -0
  166. data/spec/spec_tests/data/retryable_reads/findOne-serverErrors.yml +154 -0
  167. data/spec/spec_tests/data/retryable_reads/findOne.yml +68 -0
  168. data/spec/spec_tests/data/retryable_reads/gridfs-download-serverErrors.yml +173 -0
  169. data/spec/spec_tests/data/retryable_reads/gridfs-download.yml +79 -0
  170. data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName-serverErrors.yml +174 -0
  171. data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName.yml +79 -0
  172. data/spec/spec_tests/data/retryable_reads/listCollectionNames-serverErrors.yml +143 -0
  173. data/spec/spec_tests/data/retryable_reads/listCollectionNames.yml +59 -0
  174. data/spec/spec_tests/data/retryable_reads/listCollectionObjects-serverErrors.yml +144 -0
  175. data/spec/spec_tests/data/retryable_reads/listCollectionObjects.yml +59 -0
  176. data/spec/spec_tests/data/retryable_reads/listCollections-serverErrors.yml +143 -0
  177. data/spec/spec_tests/data/retryable_reads/listCollections.yml +59 -0
  178. data/spec/spec_tests/data/retryable_reads/listDatabaseNames-serverErrors.yml +143 -0
  179. data/spec/spec_tests/data/retryable_reads/listDatabaseNames.yml +59 -0
  180. data/spec/spec_tests/data/retryable_reads/listDatabaseObjects-serverErrors.yml +144 -0
  181. data/spec/spec_tests/data/retryable_reads/listDatabaseObjects.yml +59 -0
  182. data/spec/spec_tests/data/retryable_reads/listDatabases-serverErrors.yml +144 -0
  183. data/spec/spec_tests/data/retryable_reads/listDatabases.yml +59 -0
  184. data/spec/spec_tests/data/retryable_reads/listIndexNames-serverErrors.yml +144 -0
  185. data/spec/spec_tests/data/retryable_reads/listIndexNames.yml +60 -0
  186. data/spec/spec_tests/data/retryable_reads/listIndexes-serverErrors.yml +145 -0
  187. data/spec/spec_tests/data/retryable_reads/listIndexes.yml +60 -0
  188. data/spec/spec_tests/data/retryable_reads/mapReduce.yml +60 -0
  189. data/spec/spec_tests/data/retryable_writes/bulkWrite-serverErrors.yml +10 -7
  190. data/spec/spec_tests/data/retryable_writes/bulkWrite.yml +15 -22
  191. data/spec/spec_tests/data/retryable_writes/deleteMany.yml +22 -0
  192. data/spec/spec_tests/data/retryable_writes/deleteOne-serverErrors.yml +8 -7
  193. data/spec/spec_tests/data/retryable_writes/deleteOne.yml +5 -8
  194. data/spec/spec_tests/data/retryable_writes/findOneAndDelete-serverErrors.yml +8 -7
  195. data/spec/spec_tests/data/retryable_writes/findOneAndDelete.yml +5 -8
  196. data/spec/spec_tests/data/retryable_writes/findOneAndReplace-serverErrors.yml +8 -7
  197. data/spec/spec_tests/data/retryable_writes/findOneAndReplace.yml +5 -8
  198. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-serverErrors.yml +8 -7
  199. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate.yml +5 -8
  200. data/spec/spec_tests/data/retryable_writes/insertMany-serverErrors.yml +8 -7
  201. data/spec/spec_tests/data/retryable_writes/insertMany.yml +5 -8
  202. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +10 -45
  203. data/spec/spec_tests/data/retryable_writes/insertOne.yml +5 -8
  204. data/spec/spec_tests/data/retryable_writes/replaceOne-serverErrors.yml +8 -7
  205. data/spec/spec_tests/data/retryable_writes/replaceOne.yml +5 -8
  206. data/spec/spec_tests/data/retryable_writes/updateMany.yml +27 -0
  207. data/spec/spec_tests/data/retryable_writes/updateOne-serverErrors.yml +8 -7
  208. data/spec/spec_tests/data/retryable_writes/updateOne.yml +5 -14
  209. data/spec/spec_tests/data/transactions/abort.yml +7 -2
  210. data/spec/spec_tests/data/transactions/bulk.yml +7 -2
  211. data/spec/spec_tests/data/transactions/causal-consistency.yml +11 -4
  212. data/spec/spec_tests/data/transactions/commit.yml +11 -4
  213. data/spec/spec_tests/data/transactions/count.yml +64 -0
  214. data/spec/spec_tests/data/transactions/delete.yml +7 -2
  215. data/spec/spec_tests/data/transactions/error-labels.yml +8 -2
  216. data/spec/spec_tests/data/transactions/errors.yml +7 -2
  217. data/spec/spec_tests/data/transactions/findOneAndDelete.yml +7 -2
  218. data/spec/spec_tests/data/transactions/findOneAndReplace.yml +7 -2
  219. data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +7 -2
  220. data/spec/spec_tests/data/transactions/insert.yml +9 -2
  221. data/spec/spec_tests/data/transactions/isolation.yml +7 -2
  222. data/spec/spec_tests/data/transactions/read-concern.yml +15 -6
  223. data/spec/spec_tests/data/transactions/read-pref.yml +7 -2
  224. data/spec/spec_tests/data/transactions/reads.yml +8 -48
  225. data/spec/spec_tests/data/transactions/retryable-abort.yml +7 -2
  226. data/spec/spec_tests/data/transactions/retryable-commit.yml +7 -2
  227. data/spec/spec_tests/data/transactions/retryable-writes.yml +7 -2
  228. data/spec/spec_tests/data/transactions/run-command.yml +7 -2
  229. data/spec/spec_tests/data/transactions/transaction-options.yml +7 -2
  230. data/spec/spec_tests/data/transactions/update.yml +7 -2
  231. data/spec/spec_tests/data/transactions/write-concern.yml +7 -2
  232. data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -1
  233. data/spec/spec_tests/data/transactions_api/callback-commits.yml +6 -1
  234. data/spec/spec_tests/data/transactions_api/callback-retry.yml +6 -1
  235. data/spec/spec_tests/data/transactions_api/commit-retry.yml +6 -1
  236. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +6 -3
  237. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +6 -1
  238. data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +6 -1
  239. data/spec/spec_tests/data/transactions_api/commit.yml +6 -1
  240. data/spec/spec_tests/data/transactions_api/transaction-options.yml +6 -1
  241. data/spec/spec_tests/retryable_reads_spec.rb +11 -0
  242. data/spec/spec_tests/retryable_writes_spec.rb +4 -69
  243. data/spec/spec_tests/transactions_api_spec.rb +42 -37
  244. data/spec/spec_tests/transactions_spec.rb +42 -33
  245. data/spec/support/authorization.rb +12 -0
  246. data/spec/support/change_streams/operation.rb +1 -1
  247. data/spec/support/client_registry.rb +20 -0
  248. data/spec/support/cluster_config.rb +16 -15
  249. data/spec/support/cluster_tools.rb +346 -0
  250. data/spec/support/cmap.rb +367 -0
  251. data/spec/support/cmap/verifier.rb +46 -0
  252. data/spec/support/command_monitoring.rb +4 -6
  253. data/spec/support/common_shortcuts.rb +6 -0
  254. data/spec/support/connection_string.rb +2 -2
  255. data/spec/support/crud.rb +171 -184
  256. data/spec/support/crud/operation.rb +43 -0
  257. data/spec/support/crud/outcome.rb +53 -0
  258. data/spec/support/crud/read.rb +102 -12
  259. data/spec/support/crud/requirement.rb +69 -0
  260. data/spec/support/crud/spec.rb +68 -0
  261. data/spec/support/crud/test.rb +141 -0
  262. data/spec/support/crud/verifier.rb +96 -18
  263. data/spec/support/crud/write.rb +18 -3
  264. data/spec/support/event_subscriber.rb +15 -0
  265. data/spec/support/primary_socket.rb +2 -2
  266. data/spec/support/spec_config.rb +89 -20
  267. data/spec/support/transactions.rb +2 -306
  268. data/spec/support/transactions/operation.rb +7 -7
  269. data/spec/support/transactions/spec.rb +28 -0
  270. data/spec/support/transactions/test.rb +191 -0
  271. data/spec/support/utils.rb +123 -0
  272. metadata +202 -9
  273. metadata.gz.sig +0 -0
  274. data/lib/mongo/server/connection_pool/queue.rb +0 -359
  275. data/spec/mongo/server/connection_pool/queue_spec.rb +0 -353
  276. data/spec/support/transactions/verifier.rb +0 -97
@@ -0,0 +1,43 @@
1
+ # Copyright (C) 2019 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Error
17
+
18
+ # Exception raised if an operation is attempted on a closed connection pool.
19
+ #
20
+ # @since 2.9.0
21
+ class PoolClosedError < Error
22
+
23
+ # @return [ Mongo::Address ] address The address of the server the
24
+ # pool's connections connect to.
25
+ #
26
+ # @since 2.9.0
27
+ attr_reader :address
28
+
29
+ # Instantiate the new exception.
30
+ #
31
+ # @example Instantiate the exception.
32
+ # Mongo::Error::PoolClosedError.new(address)
33
+ #
34
+ # @since 2.9.0
35
+ # @api private
36
+ def initialize(address)
37
+ @address = address
38
+
39
+ super("Attempted to use a connection pool which has been closed (for #{address})")
40
+ end
41
+ end
42
+ end
43
+ end
@@ -14,6 +14,9 @@ module Mongo
14
14
  # @api private
15
15
  NODE_RECOVERING_CODES = [11600, 11602, 13436, 189, 91].freeze
16
16
 
17
+ # @api private
18
+ NODE_SHUTTING_DOWN_CODES = [11600, 91].freeze
19
+
17
20
  # Whether the error is a "not master" error, or one of its variants.
18
21
  #
19
22
  # See https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-master-and-node-is-recovering.
@@ -49,6 +52,21 @@ module Mongo
49
52
  false
50
53
  end
51
54
  end
55
+
56
+ # Whether the error is a "node is shutting down" type error.
57
+ #
58
+ # See https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-master-and-node-is-recovering.
59
+ #
60
+ # @return [ true | false ] Whether the error is a node is shutting down.
61
+ #
62
+ # @since 2.9.0
63
+ def node_shutting_down?
64
+ if code && NODE_SHUTTING_DOWN_CODES.include?(code)
65
+ true
66
+ else
67
+ false
68
+ end
69
+ end
52
70
  end
53
71
  end
54
72
  end
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'stringio'
16
-
17
15
  module Mongo
18
16
  module Grid
19
17
  class File
@@ -147,6 +147,7 @@ module Mongo
147
147
  # size.
148
148
  # @option options [ String ] :write The write concern.
149
149
  # @option options [ String ] :read The read preference.
150
+ # @option options [ Session ] :session The session to use.
150
151
  #
151
152
  # @since 2.0.0
152
153
  def initialize(database, options = {})
@@ -207,17 +208,24 @@ module Mongo
207
208
  # fs.open_download_stream(id)
208
209
  #
209
210
  # @param [ BSON::ObjectId, Object ] id The id of the file to read.
211
+ # @param [ Hash ] options The options.
212
+ #
213
+ # @option options [ BSON::Document ] :file_info_doc For internal
214
+ # driver use only. A BSON document to use as file information.
210
215
  #
211
216
  # @return [ Stream::Read ] The stream to read from.
212
217
  #
213
218
  # @yieldparam [ Hash ] The read stream.
214
219
  #
215
220
  # @since 2.1.0
216
- def open_download_stream(id)
217
- read_stream(id).tap do |stream|
221
+ def open_download_stream(id, options = nil)
222
+ read_stream(id, options).tap do |stream|
218
223
  if block_given?
219
- yield stream
220
- stream.close
224
+ begin
225
+ yield stream
226
+ ensure
227
+ stream.close
228
+ end
221
229
  end
222
230
  end
223
231
  end
@@ -283,16 +291,15 @@ module Mongo
283
291
  skip = revision
284
292
  sort = { 'uploadDate' => Mongo::Index::ASCENDING }
285
293
  end
286
- file_doc = files_collection.find({ filename: filename} ,
287
- projection: { _id: 1 },
294
+ file_info_doc = files_collection.find({ filename: filename} ,
288
295
  sort: sort,
289
296
  skip: skip,
290
297
  limit: -1).first
291
- unless file_doc
298
+ unless file_info_doc
292
299
  raise Error::FileNotFound.new(filename, :filename) unless opts[:revision]
293
300
  raise Error::InvalidFileRevision.new(filename, opts[:revision])
294
301
  end
295
- open_download_stream(file_doc[:_id], &block)
302
+ open_download_stream(file_info_doc[:_id], file_info_doc: file_info_doc, &block)
296
303
  end
297
304
 
298
305
  # Downloads the contents of the stored file specified by filename and by the
@@ -356,8 +363,11 @@ module Mongo
356
363
  def open_upload_stream(filename, opts = {})
357
364
  write_stream(filename, opts).tap do |stream|
358
365
  if block_given?
359
- yield stream
360
- stream.close
366
+ begin
367
+ yield stream
368
+ ensure
369
+ stream.close
370
+ end
361
371
  end
362
372
  end
363
373
  end
@@ -428,8 +438,12 @@ module Mongo
428
438
 
429
439
  private
430
440
 
431
- def read_stream(id)
432
- Stream.get(self, Stream::READ_MODE, { file_id: id }.merge!(options))
441
+ # @param [ Hash ] opts The options.
442
+ #
443
+ # @option opts [ BSON::Document ] :file_info_doc For internal
444
+ # driver use only. A BSON document to use as file information.
445
+ def read_stream(id, opts = nil)
446
+ Stream.get(self, Stream::READ_MODE, { file_id: id }.update(options).update(opts || {}))
433
447
  end
434
448
 
435
449
  def write_stream(filename, opts)
@@ -46,11 +46,15 @@ module Mongo
46
46
  # @param [ FSBucket ] fs The GridFS bucket object.
47
47
  # @param [ Hash ] options The read stream options.
48
48
  #
49
+ # @option options [ BSON::Document ] :file_info_doc For internal
50
+ # driver use only. A BSON document to use as file information.
51
+ #
49
52
  # @since 2.1.0
50
53
  def initialize(fs, options)
51
54
  @fs = fs
52
55
  @options = options.dup
53
56
  @file_id = @options.delete(:file_id)
57
+ @options.freeze
54
58
  @open = true
55
59
  end
56
60
 
@@ -70,15 +74,19 @@ module Mongo
70
74
  # @since 2.1.0
71
75
  def each
72
76
  ensure_readable!
73
- num_chunks = (file_info.length + file_info.chunk_size - 1) / file_info.chunk_size
74
- view.each_with_index.reduce(0) do |length_read, (doc, index)|
75
- chunk = Grid::File::Chunk.new(doc)
76
- validate!(index, num_chunks, chunk, length_read)
77
- data = chunk.data.data
78
- yield data
79
- length_read += data.size
80
- end if block_given?
81
- view.to_enum
77
+ info = file_info
78
+ num_chunks = (info.length + info.chunk_size - 1) / info.chunk_size
79
+ if block_given?
80
+ view.each_with_index.reduce(0) do |length_read, (doc, index)|
81
+ chunk = Grid::File::Chunk.new(doc)
82
+ validate!(index, num_chunks, chunk, length_read)
83
+ data = chunk.data.data
84
+ yield data
85
+ length_read += data.size
86
+ end
87
+ else
88
+ view.to_enum
89
+ end
82
90
  end
83
91
 
84
92
  # Read all file data.
@@ -97,18 +105,19 @@ module Mongo
97
105
 
98
106
  # Close the read stream.
99
107
  #
108
+ # If the stream is already closed, this method does nothing.
109
+ #
100
110
  # @example Close the stream.
101
111
  # stream.close
102
112
  #
103
113
  # @return [ BSON::ObjectId, Object ] The file id.
104
114
  #
105
- # @raise [ Error::ClosedStream ] If the stream is already closed.
106
- #
107
115
  # @since 2.1.0
108
116
  def close
109
- ensure_open!
110
- view.close_query
111
- @open = false
117
+ if @open
118
+ view.close_query
119
+ @open = false
120
+ end
112
121
  file_id
113
122
  end
114
123
 
@@ -136,18 +145,24 @@ module Mongo
136
145
  @read_preference ||= options[:read] || fs.read_preference
137
146
  end
138
147
 
139
- # Get the files collection file information document for the file being read.
148
+ # Get the files collection file information document for the file
149
+ # being read.
140
150
  #
141
- # @example Get the file info document.
142
- # stream.file_info
151
+ # @note The file information is cached in the stream. Subsequent
152
+ # calls to file_info will return the same information that the
153
+ # first call returned, and will not query the database again.
143
154
  #
144
- # @return [ Hash ] The file info document.
155
+ # @return [ File::Info ] The file information object.
145
156
  #
146
157
  # @since 2.1.0
147
158
  def file_info
148
- doc = fs.files_collection.find(_id: file_id).first
149
- if doc
150
- @file_info ||= File::Info.new(Options::Mapper.transform(doc, File::Info::MAPPINGS.invert))
159
+ @file_info ||= begin
160
+ doc = options[:file_info_doc] || fs.files_collection.find(_id: file_id).first
161
+ if doc
162
+ File::Info.new(Options::Mapper.transform(doc, File::Info::MAPPINGS.invert))
163
+ else
164
+ nil
165
+ end
151
166
  end
152
167
  end
153
168
 
@@ -21,6 +21,7 @@ module Mongo
21
21
  class View
22
22
  extend Forwardable
23
23
  include Enumerable
24
+ include Retryable
24
25
 
25
26
  # @return [ Collection ] collection The indexes collection.
26
27
  attr_reader :collection
@@ -190,14 +191,17 @@ module Mongo
190
191
  #
191
192
  # @since 2.0.0
192
193
  def each(&block)
193
- server = next_primary(false)
194
194
  session = client.send(:get_session, @options)
195
- result = send_initial_query(server, session)
196
- cursor = Cursor.new(self, result, server, session: session)
197
- cursor.each do |doc|
198
- yield doc
199
- end if block_given?
200
- cursor.to_enum
195
+ cursor = read_with_retry_cursor(session, ServerSelector.get(mode: :primary), self) do |server|
196
+ send_initial_query(server, session)
197
+ end
198
+ if block_given?
199
+ cursor.each do |doc|
200
+ yield doc
201
+ end
202
+ else
203
+ cursor.to_enum
204
+ end
201
205
  end
202
206
 
203
207
  # Create the new index view.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'logger'
16
-
17
15
  module Mongo
18
16
 
19
17
  # Provides ability to log messages.
@@ -25,6 +25,11 @@ module Mongo
25
25
  # @since 2.1.0
26
26
  COMMAND = 'Command'.freeze
27
27
 
28
+ # The connection pool topic.
29
+ #
30
+ # @since 2.9.0
31
+ CONNECTION_POOL = 'ConnectionPool'.freeze
32
+
28
33
  # Server closed topic.
29
34
  #
30
35
  # @since 2.4.0
@@ -218,6 +223,9 @@ module Mongo
218
223
  end
219
224
  end
220
225
  subscribe(COMMAND, CommandLogSubscriber.new(options))
226
+ # CMAP events are not logged by default because this will create
227
+ # log entries for every operation performed by the driver.
228
+ #subscribe(CONNECTION_POOL, CmapLogSubscriber.new(options))
221
229
  subscribe(SERVER_OPENING, ServerOpeningLogSubscriber.new(options))
222
230
  subscribe(SERVER_CLOSED, ServerClosedLogSubscriber.new(options))
223
231
  subscribe(SERVER_DESCRIPTION_CHANGED, ServerDescriptionChangedLogSubscriber.new(options))
@@ -235,8 +243,24 @@ module Mongo
235
243
  options[:monitoring] != false
236
244
  end
237
245
 
246
+ # Publish an event.
247
+ #
248
+ # This method is used for event types which only have a single event
249
+ # in them.
250
+ #
251
+ # @param [ String ] topic The event topic.
252
+ # @param [ Event ] event The event to publish.
253
+ #
254
+ # @since 2.9.0
255
+ def published(topic, event)
256
+ subscribers_for(topic).each{ |subscriber| subscriber.published(event) }
257
+ end
258
+
238
259
  # Publish a started event.
239
260
  #
261
+ # This method is used for event types which have the started/succeeded/failed
262
+ # events in them, such as command and heartbeat events.
263
+ #
240
264
  # @example Publish a started event.
241
265
  # monitoring.started(COMMAND, event)
242
266
  #
@@ -250,6 +274,9 @@ module Mongo
250
274
 
251
275
  # Publish a succeeded event.
252
276
  #
277
+ # This method is used for event types which have the started/succeeded/failed
278
+ # events in them, such as command and heartbeat events.
279
+ #
253
280
  # @example Publish a succeeded event.
254
281
  # monitoring.succeeded(COMMAND, event)
255
282
  #
@@ -263,6 +290,9 @@ module Mongo
263
290
 
264
291
  # Publish a failed event.
265
292
  #
293
+ # This method is used for event types which have the started/succeeded/failed
294
+ # events in them, such as command and heartbeat events.
295
+ #
266
296
  # @example Publish a failed event.
267
297
  # monitoring.failed(COMMAND, event)
268
298
  #
@@ -288,6 +318,7 @@ end
288
318
  require 'mongo/monitoring/event'
289
319
  require 'mongo/monitoring/publishable'
290
320
  require 'mongo/monitoring/command_log_subscriber'
321
+ require 'mongo/monitoring/cmap_log_subscriber'
291
322
  require 'mongo/monitoring/sdam_log_subscriber'
292
323
  require 'mongo/monitoring/server_description_changed_log_subscriber'
293
324
  require 'mongo/monitoring/server_closed_log_subscriber'
@@ -0,0 +1,53 @@
1
+ # Copyright (C) 2019 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the 'License');
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an 'AS IS' BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Monitoring
17
+
18
+ # Subscribes to CMAP events and logs them.
19
+ #
20
+ # @since 2.9.0
21
+ class CmapLogSubscriber
22
+ include Loggable
23
+
24
+ # @return [ Hash ] options The options.
25
+ #
26
+ # @since 2.9.0
27
+ attr_reader :options
28
+
29
+ # Create the new log subscriber.
30
+ #
31
+ # @example Create the log subscriber.
32
+ # CmapLogSubscriber.new
33
+ #
34
+ # @param [ Hash ] options The options.
35
+ #
36
+ # @option options [ Logger ] :logger An optional custom logger.
37
+ #
38
+ # @since 2.9.0
39
+ def initialize(options = {})
40
+ @options = options
41
+ end
42
+
43
+ # Handle a CMAP event.
44
+ #
45
+ # @param [ Event ] event The event.
46
+ #
47
+ # @since 2.9.0
48
+ def published(event)
49
+ log_debug("EVENT: #{event.summary}") if logger.debug?
50
+ end
51
+ end
52
+ end
53
+ end
@@ -17,6 +17,7 @@ require 'mongo/monitoring/event/secure'
17
17
  require 'mongo/monitoring/event/command_started'
18
18
  require 'mongo/monitoring/event/command_succeeded'
19
19
  require 'mongo/monitoring/event/command_failed'
20
+ require 'mongo/monitoring/event/cmap'
20
21
  require 'mongo/monitoring/event/server_closed'
21
22
  require 'mongo/monitoring/event/server_description_changed'
22
23
  require 'mongo/monitoring/event/server_opening'