mongo 2.4.3 → 2.5.0.beta

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 (235) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +3 -2
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo.rb +3 -2
  5. data/lib/mongo/auth/cr.rb +6 -4
  6. data/lib/mongo/auth/cr/conversation.rb +33 -17
  7. data/lib/mongo/auth/ldap.rb +4 -2
  8. data/lib/mongo/auth/ldap/conversation.rb +19 -9
  9. data/lib/mongo/auth/scram.rb +7 -4
  10. data/lib/mongo/auth/scram/conversation.rb +62 -24
  11. data/lib/mongo/auth/user.rb +10 -0
  12. data/lib/mongo/auth/user/view.rb +44 -22
  13. data/lib/mongo/auth/x509.rb +4 -2
  14. data/lib/mongo/auth/x509/conversation.rb +19 -9
  15. data/lib/mongo/bulk_write.rb +33 -27
  16. data/lib/mongo/bulk_write/combineable.rb +5 -0
  17. data/lib/mongo/bulk_write/transformable.rb +2 -0
  18. data/lib/mongo/bulk_write/validatable.rb +4 -0
  19. data/lib/mongo/client.rb +123 -12
  20. data/lib/mongo/cluster.rb +52 -11
  21. data/lib/mongo/cluster/app_metadata.rb +8 -2
  22. data/lib/mongo/cluster/cursor_reaper.rb +0 -1
  23. data/lib/mongo/cluster/topology.rb +1 -1
  24. data/lib/mongo/collection.rb +114 -27
  25. data/lib/mongo/collection/view.rb +8 -2
  26. data/lib/mongo/collection/view/aggregation.rb +11 -7
  27. data/lib/mongo/collection/view/builder/aggregation.rb +5 -1
  28. data/lib/mongo/collection/view/builder/find_command.rb +5 -3
  29. data/lib/mongo/collection/view/builder/map_reduce.rb +11 -3
  30. data/lib/mongo/collection/view/builder/op_query.rb +1 -1
  31. data/lib/mongo/collection/view/change_stream.rb +160 -0
  32. data/lib/mongo/collection/view/change_stream/retryable.rb +57 -0
  33. data/lib/mongo/collection/view/iterable.rb +11 -10
  34. data/lib/mongo/collection/view/map_reduce.rb +22 -18
  35. data/lib/mongo/collection/view/readable.rb +51 -37
  36. data/lib/mongo/collection/view/writable.rb +72 -40
  37. data/lib/mongo/cursor.rb +25 -4
  38. data/lib/mongo/cursor/builder/get_more_command.rb +4 -2
  39. data/lib/mongo/database.rb +22 -11
  40. data/lib/mongo/database/view.rb +16 -12
  41. data/lib/mongo/error.rb +5 -0
  42. data/lib/mongo/error/invalid_session.rb +36 -0
  43. data/lib/mongo/error/missing_resume_token.rb +39 -0
  44. data/lib/mongo/error/operation_failure.rb +17 -0
  45. data/lib/mongo/error/parser.rb +3 -2
  46. data/lib/mongo/error/unknown_payload_type.rb +41 -0
  47. data/lib/mongo/error/unsupported_array_filters.rb +51 -0
  48. data/lib/mongo/error/unsupported_message_type.rb +23 -0
  49. data/lib/mongo/grid/fs_bucket.rb +5 -4
  50. data/lib/mongo/grid/stream/read.rb +3 -2
  51. data/lib/mongo/grid/stream/write.rb +2 -2
  52. data/lib/mongo/index/view.rb +35 -25
  53. data/lib/mongo/monitoring/event/secure.rb +14 -0
  54. data/lib/mongo/operation.rb +16 -0
  55. data/lib/mongo/operation/commands.rb +1 -0
  56. data/lib/mongo/operation/commands/aggregate.rb +9 -5
  57. data/lib/mongo/operation/commands/aggregate/result.rb +1 -1
  58. data/lib/mongo/operation/commands/collections_info.rb +6 -6
  59. data/lib/mongo/operation/commands/command.rb +2 -1
  60. data/lib/mongo/operation/commands/create.rb +6 -2
  61. data/lib/mongo/operation/commands/drop.rb +6 -2
  62. data/lib/mongo/operation/commands/drop_database.rb +6 -2
  63. data/lib/mongo/operation/commands/explain.rb +27 -0
  64. data/lib/mongo/operation/commands/explain/result.rb +52 -0
  65. data/lib/mongo/operation/commands/indexes.rb +1 -1
  66. data/lib/mongo/operation/commands/list_collections.rb +1 -1
  67. data/lib/mongo/operation/commands/list_collections/result.rb +1 -1
  68. data/lib/mongo/operation/commands/list_indexes.rb +1 -1
  69. data/lib/mongo/operation/commands/list_indexes/result.rb +1 -1
  70. data/lib/mongo/operation/commands/map_reduce.rb +8 -4
  71. data/lib/mongo/operation/commands/map_reduce/result.rb +13 -1
  72. data/lib/mongo/operation/commands/user_query.rb +1 -1
  73. data/lib/mongo/operation/commands/users_info.rb +6 -2
  74. data/lib/mongo/operation/executable.rb +4 -1
  75. data/lib/mongo/operation/read_preference.rb +10 -5
  76. data/lib/mongo/operation/result.rb +26 -2
  77. data/lib/mongo/operation/specifiable.rb +13 -1
  78. data/lib/mongo/operation/uses_command_op_msg.rb +47 -0
  79. data/lib/mongo/operation/write/bulk/bulkable.rb +4 -1
  80. data/lib/mongo/operation/write/bulk/insert/result.rb +4 -4
  81. data/lib/mongo/operation/write/command/create_index.rb +6 -1
  82. data/lib/mongo/operation/write/command/delete.rb +28 -4
  83. data/lib/mongo/operation/write/command/drop_index.rb +6 -1
  84. data/lib/mongo/operation/write/command/insert.rb +22 -18
  85. data/lib/mongo/operation/write/command/update.rb +24 -9
  86. data/lib/mongo/operation/write/command/writable.rb +14 -1
  87. data/lib/mongo/operation/write/insert.rb +4 -1
  88. data/lib/mongo/operation/write/insert/result.rb +2 -2
  89. data/lib/mongo/operation/write/update.rb +7 -1
  90. data/lib/mongo/operation/write/write_command_enabled.rb +20 -3
  91. data/lib/mongo/protocol.rb +3 -0
  92. data/lib/mongo/protocol/bit_vector.rb +2 -2
  93. data/lib/mongo/protocol/compressed.rb +135 -0
  94. data/lib/mongo/protocol/delete.rb +8 -6
  95. data/lib/mongo/protocol/get_more.rb +8 -6
  96. data/lib/mongo/protocol/insert.rb +8 -6
  97. data/lib/mongo/protocol/kill_cursors.rb +8 -6
  98. data/lib/mongo/protocol/message.rb +31 -3
  99. data/lib/mongo/protocol/msg.rb +172 -0
  100. data/lib/mongo/protocol/query.rb +26 -6
  101. data/lib/mongo/protocol/registry.rb +76 -0
  102. data/lib/mongo/protocol/reply.rb +10 -5
  103. data/lib/mongo/protocol/serializers.rb +224 -0
  104. data/lib/mongo/protocol/update.rb +8 -6
  105. data/lib/mongo/retryable.rb +4 -2
  106. data/lib/mongo/server.rb +6 -3
  107. data/lib/mongo/server/connectable.rb +1 -1
  108. data/lib/mongo/server/connection.rb +30 -8
  109. data/lib/mongo/server/description.rb +25 -1
  110. data/lib/mongo/server/description/features.rb +4 -1
  111. data/lib/mongo/server/monitor.rb +5 -0
  112. data/lib/mongo/server/monitor/connection.rb +50 -2
  113. data/lib/mongo/server_selector/nearest.rb +10 -4
  114. data/lib/mongo/server_selector/primary.rb +20 -0
  115. data/lib/mongo/server_selector/primary_preferred.rb +10 -4
  116. data/lib/mongo/server_selector/secondary.rb +10 -4
  117. data/lib/mongo/server_selector/secondary_preferred.rb +24 -4
  118. data/lib/mongo/session.rb +180 -0
  119. data/lib/mongo/session/server_session.rb +73 -0
  120. data/lib/mongo/session/session_pool.rb +161 -0
  121. data/lib/mongo/uri.rb +11 -0
  122. data/lib/mongo/version.rb +1 -1
  123. data/mongo.gemspec +2 -1
  124. data/spec/mongo/auth/cr_spec.rb +12 -0
  125. data/spec/mongo/auth/ldap_spec.rb +2 -0
  126. data/spec/mongo/auth/scram/conversation_spec.rb +6 -6
  127. data/spec/mongo/auth/scram_spec.rb +25 -1
  128. data/spec/mongo/auth/user/view_spec.rb +268 -76
  129. data/spec/mongo/auth/x509_spec.rb +2 -0
  130. data/spec/mongo/bulk_write_spec.rb +435 -5
  131. data/spec/mongo/client_spec.rb +356 -39
  132. data/spec/mongo/cluster/app_metadata_spec.rb +2 -2
  133. data/spec/mongo/cluster_spec.rb +176 -0
  134. data/spec/mongo/collection/view/aggregation_spec.rb +33 -12
  135. data/spec/mongo/collection/view/builder/find_command_spec.rb +46 -6
  136. data/spec/mongo/collection/view/change_stream_spec.rb +814 -0
  137. data/spec/mongo/collection/view/map_reduce_spec.rb +94 -17
  138. data/spec/mongo/collection/view/readable_spec.rb +3 -12
  139. data/spec/mongo/collection_spec.rb +1048 -42
  140. data/spec/mongo/cursor/builder/get_more_command_spec.rb +19 -0
  141. data/spec/mongo/cursor_spec.rb +2 -2
  142. data/spec/mongo/database_spec.rb +50 -1
  143. data/spec/mongo/grid/fs_bucket_spec.rb +225 -137
  144. data/spec/mongo/grid/stream/read_spec.rb +2 -2
  145. data/spec/mongo/index/view_spec.rb +146 -8
  146. data/spec/mongo/monitoring/event/secure_spec.rb +42 -0
  147. data/spec/mongo/operation/read/query_spec.rb +2 -1
  148. data/spec/mongo/operation/specifiable_spec.rb +2 -2
  149. data/spec/mongo/operation/write/command/delete_spec.rb +96 -13
  150. data/spec/mongo/operation/write/command/insert_spec.rb +111 -12
  151. data/spec/mongo/operation/write/command/update_spec.rb +93 -10
  152. data/spec/mongo/operation/write/delete_spec.rb +1 -1
  153. data/spec/mongo/operation/write/insert_spec.rb +1 -1
  154. data/spec/mongo/operation/write/update_spec.rb +1 -1
  155. data/spec/mongo/protocol/compressed_spec.rb +66 -0
  156. data/spec/mongo/protocol/delete_spec.rb +14 -0
  157. data/spec/mongo/protocol/get_more_spec.rb +14 -0
  158. data/spec/mongo/protocol/insert_spec.rb +14 -0
  159. data/spec/mongo/protocol/kill_cursors_spec.rb +14 -0
  160. data/spec/mongo/protocol/msg_spec.rb +499 -0
  161. data/spec/mongo/protocol/query_spec.rb +45 -0
  162. data/spec/mongo/protocol/registry_spec.rb +31 -0
  163. data/spec/mongo/protocol/reply_spec.rb +14 -0
  164. data/spec/mongo/protocol/update_spec.rb +14 -0
  165. data/spec/mongo/retryable_spec.rb +6 -2
  166. data/spec/mongo/sdam_spec.rb +4 -0
  167. data/spec/mongo/server/connection_spec.rb +4 -2
  168. data/spec/mongo/server/description_spec.rb +28 -1
  169. data/spec/mongo/session/server_session_spec.rb +16 -0
  170. data/spec/mongo/session/session_pool_spec.rb +194 -0
  171. data/spec/mongo/uri_spec.rb +31 -2
  172. data/spec/spec_helper.rb +104 -0
  173. data/spec/support/authorization.rb +6 -1
  174. data/spec/support/crud.rb +3 -1
  175. data/spec/support/crud/write.rb +6 -1
  176. data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +69 -0
  177. data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +63 -0
  178. data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +109 -0
  179. data/spec/support/sdam/rs/discover_arbiters.yml +1 -1
  180. data/spec/support/sdam/rs/discover_passives.yml +2 -2
  181. data/spec/support/sdam/rs/discover_primary.yml +1 -1
  182. data/spec/support/sdam/rs/discover_secondary.yml +1 -1
  183. data/spec/support/sdam/rs/discovery.yml +4 -4
  184. data/spec/support/sdam/rs/equal_electionids.yml +1 -0
  185. data/spec/support/sdam/rs/ghost_discovered.yml +1 -1
  186. data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +1 -1
  187. data/spec/support/sdam/rs/ls_timeout.yml +88 -0
  188. data/spec/support/sdam/rs/member_reconfig.yml +2 -2
  189. data/spec/support/sdam/rs/member_standalone.yml +2 -2
  190. data/spec/support/sdam/rs/new_primary.yml +2 -2
  191. data/spec/support/sdam/rs/new_primary_new_electionid.yml +3 -0
  192. data/spec/support/sdam/rs/new_primary_new_setversion.yml +3 -0
  193. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
  194. data/spec/support/sdam/rs/non_rs_member.yml +1 -1
  195. data/spec/support/sdam/rs/normalize_case.yml +1 -1
  196. data/spec/support/sdam/rs/null_election_id.yml +4 -0
  197. data/spec/support/sdam/rs/primary_becomes_standalone.yml +2 -2
  198. data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
  199. data/spec/support/sdam/rs/primary_disconnect.yml +2 -2
  200. data/spec/support/sdam/rs/primary_disconnect_electionid.yml +5 -0
  201. data/spec/support/sdam/rs/primary_disconnect_setversion.yml +5 -0
  202. data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +58 -0
  203. data/spec/support/sdam/rs/primary_reports_new_member.yml +4 -4
  204. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +2 -2
  205. data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
  206. data/spec/support/sdam/rs/response_from_removed.yml +2 -2
  207. data/spec/support/sdam/rs/rsother_discovered.yml +1 -1
  208. data/spec/support/sdam/rs/sec_not_auth.yml +1 -1
  209. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
  210. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
  211. data/spec/support/sdam/rs/setversion_without_electionid.yml +2 -0
  212. data/spec/support/sdam/rs/stepdown_change_set_name.yml +2 -2
  213. data/spec/support/sdam/rs/unexpected_mongos.yml +1 -1
  214. data/spec/support/sdam/rs/use_setversion_without_electionid.yml +3 -0
  215. data/spec/support/sdam/rs/wrong_set_name.yml +1 -1
  216. data/spec/support/sdam/sharded/ls_timeout_mongos.yml +97 -0
  217. data/spec/support/sdam/sharded/mongos_disconnect.yml +3 -3
  218. data/spec/support/sdam/sharded/multiple_mongoses.yml +1 -1
  219. data/spec/support/sdam/sharded/non_mongos_removed.yml +1 -1
  220. data/spec/support/sdam/sharded/normalize_uri_case.yml +1 -1
  221. data/spec/support/sdam/single/direct_connection_external_ip.yml +1 -1
  222. data/spec/support/sdam/single/direct_connection_mongos.yml +1 -1
  223. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
  224. data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
  225. data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
  226. data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
  227. data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
  228. data/spec/support/sdam/single/ls_timeout_standalone.yml +35 -0
  229. data/spec/support/sdam/single/not_ok_response.yml +1 -1
  230. data/spec/support/sdam/single/standalone_removed.yml +1 -1
  231. data/spec/support/sdam/single/unavailable_seed.yml +1 -1
  232. data/spec/support/server_discovery_and_monitoring.rb +4 -0
  233. data/spec/support/shared/session.rb +236 -0
  234. metadata +53 -15
  235. metadata.gz.sig +0 -0
@@ -154,10 +154,22 @@ module Mongo
154
154
  # @since 2.1.0
155
155
  LOCAL_TIME = 'localTime'.freeze
156
156
 
157
+ # Constant for reading operationTime info from config.
158
+ #
159
+ # @since 2.5.0
160
+ OPERATION_TIME = 'operationTime'.freeze
161
+
162
+ # Constant for reading logicalSessionTimeoutMinutes info from config.
163
+ #
164
+ # @since 2.5.0
165
+ LOGICAL_SESSION_TIMEOUT_MINUTES = 'logicalSessionTimeoutMinutes'.freeze
166
+
157
167
  # Fields to exclude when comparing two descriptions.
158
168
  #
159
169
  # @since 2.0.6
160
- EXCLUDE_FOR_COMPARISON = [ LOCAL_TIME, LAST_WRITE ].freeze
170
+ EXCLUDE_FOR_COMPARISON = [ LOCAL_TIME,
171
+ LAST_WRITE,
172
+ OPERATION_TIME ].freeze
161
173
 
162
174
  # @return [ Address ] address The server's address.
163
175
  attr_reader :address
@@ -382,6 +394,18 @@ module Mongo
382
394
  config[LAST_WRITE][LAST_WRITE_DATE] if config[LAST_WRITE]
383
395
  end
384
396
 
397
+ # Get the logicalSessionTimeoutMinutes from the config.
398
+ #
399
+ # @example Get the logicalSessionTimeoutMinutes value in minutes.
400
+ # description.logical_session_timeout
401
+ #
402
+ # @return [ Integer, nil ] The logical session timeout in minutes.
403
+ #
404
+ # @since 2.5.0
405
+ def logical_session_timeout
406
+ config[LOGICAL_SESSION_TIMEOUT_MINUTES] if config[LOGICAL_SESSION_TIMEOUT_MINUTES]
407
+ end
408
+
385
409
  # Is the server a mongos?
386
410
  #
387
411
  # @example Is the server a mongos?
@@ -25,6 +25,9 @@ module Mongo
25
25
  #
26
26
  # @since 2.0.0
27
27
  MAPPINGS = {
28
+ :array_filters => 6,
29
+ :op_msg => 6,
30
+ :sessions => 6,
28
31
  :collation => 5,
29
32
  :max_staleness => 5,
30
33
  :find_command => 4,
@@ -38,7 +41,7 @@ module Mongo
38
41
  # The wire protocol versions that this version of the driver supports.
39
42
  #
40
43
  # @since 2.0.0
41
- DRIVER_WIRE_VERSIONS = (0..5).freeze
44
+ DRIVER_WIRE_VERSIONS = (0..6).freeze
42
45
 
43
46
  # Create the methods for each mapping to tell if they are supported.
44
47
  #
@@ -23,6 +23,7 @@ module Mongo
23
23
  # @since 2.0.0
24
24
  class Monitor
25
25
  include Loggable
26
+ extend Forwardable
26
27
 
27
28
  # The default time for a server to refresh its status is 10 seconds.
28
29
  #
@@ -58,6 +59,10 @@ module Mongo
58
59
  # @since 2.4.0
59
60
  attr_reader :last_scan
60
61
 
62
+ # The compressor is determined during the handshake, so it must be an attribute
63
+ # of the connection.
64
+ def_delegators :connection, :compressor
65
+
61
66
  # Force the monitor to immediately do a check of its server.
62
67
  #
63
68
  # @example Force a scan.
@@ -22,22 +22,38 @@ module Mongo
22
22
  class Connection
23
23
  include Retryable
24
24
  include Connectable
25
+ include Loggable
25
26
 
26
27
  # The command used for determining server status.
27
28
  #
28
29
  # @since 2.2.0
29
30
  ISMASTER = { :ismaster => 1 }.freeze
30
31
 
32
+ # The command used for determining server status formatted for an OP_MSG (server versions >= 3.6).
33
+ #
34
+ # @since 2.5.0
35
+ ISMASTER_OP_MSG = { :ismaster => 1, '$db' => Database::ADMIN }.freeze
36
+
31
37
  # The constant for the ismaster command.
32
38
  #
33
39
  # @since 2.2.0
34
40
  ISMASTER_MESSAGE = Protocol::Query.new(Database::ADMIN, Database::COMMAND, ISMASTER, :limit => -1)
35
41
 
42
+ # The constant for the ismaster command as an OP_MSG (server versions >= 3.6).
43
+ #
44
+ # @since 2.5.0
45
+ ISMASTER_OP_MSG_MESSAGE = Protocol::Msg.new([:none], {}, ISMASTER_OP_MSG)
46
+
36
47
  # The raw bytes for the ismaster message.
37
48
  #
38
49
  # @since 2.2.0
39
50
  ISMASTER_BYTES = ISMASTER_MESSAGE.serialize.to_s.freeze
40
51
 
52
+ # The raw bytes for the ismaster OP_MSG message (server versions >= 3.6).
53
+ #
54
+ # @since 2.5.0
55
+ ISMASTER_OP_MSG_BYTES = ISMASTER_OP_MSG_MESSAGE.serialize.to_s.freeze
56
+
41
57
  # The default time in seconds to timeout a connection attempt.
42
58
  #
43
59
  # @since 2.1.2
@@ -45,6 +61,23 @@ module Mongo
45
61
  # @deprecated Please use Server::CONNECT_TIMEOUT instead. Will be removed in 3.0.0
46
62
  CONNECT_TIMEOUT = 10.freeze
47
63
 
64
+ # Key for compression algorithms in the response from the server during handshake.
65
+ #
66
+ # @since 2.5.0
67
+ COMPRESSION = 'compression'.freeze
68
+
69
+ # Warning message that the server has no compression algorithms in common with those requested
70
+ # by the client.
71
+ #
72
+ # @since 2.5.0
73
+ COMPRESSION_WARNING = 'The server has no compression algorithms in common with those requested. ' +
74
+ 'Compression will not be used.'.freeze
75
+
76
+ # The compressor, which is determined during the handshake.
77
+ #
78
+ # @since 2.5.0
79
+ attr_reader :compressor
80
+
48
81
  # Send the preserialized ismaster call.
49
82
  #
50
83
  # @example Send a preserialized ismaster message.
@@ -57,7 +90,7 @@ module Mongo
57
90
  ensure_connected do |socket|
58
91
  read_with_one_retry do
59
92
  socket.write(ISMASTER_BYTES)
60
- Protocol::Reply.deserialize(socket).documents[0]
93
+ Protocol::Message.deserialize(socket).documents[0]
61
94
  end
62
95
  end
63
96
  end
@@ -122,6 +155,7 @@ module Mongo
122
155
  @ssl_options = options.reject { |k, v| !k.to_s.start_with?(SSL) }
123
156
  @socket = nil
124
157
  @pid = Process.pid
158
+ @compressor = nil
125
159
  end
126
160
 
127
161
  # Get the socket timeout.
@@ -142,10 +176,24 @@ module Mongo
142
176
 
143
177
  private
144
178
 
179
+ def set_compressor!(reply)
180
+ server_compressors = reply[COMPRESSION]
181
+
182
+ if options[:compressors]
183
+ if intersection = (server_compressors & options[:compressors])
184
+ @compressor = intersection[0]
185
+ else
186
+ log_warn(COMPRESSION_WARNING)
187
+ end
188
+ end
189
+ end
190
+
145
191
  def handshake!
146
192
  if @app_metadata
147
193
  socket.write(@app_metadata.ismaster_bytes)
148
- Protocol::Reply.deserialize(socket, Mongo::Protocol::Message::MAX_MESSAGE_SIZE).documents[0]
194
+ reply = Protocol::Message.deserialize(socket, Mongo::Protocol::Message::MAX_MESSAGE_SIZE).documents[0]
195
+ set_compressor!(reply)
196
+ reply
149
197
  end
150
198
  end
151
199
  end
@@ -22,6 +22,11 @@ module Mongo
22
22
  class Nearest
23
23
  include Selectable
24
24
 
25
+ # Name of the this read preference in the server's format.
26
+ #
27
+ # @since 2.5.0
28
+ SERVER_FORMATTED_NAME = 'nearest'.freeze
29
+
25
30
  # Get the name of the server mode type.
26
31
  #
27
32
  # @example Get the name of the server mode for this preference.
@@ -65,11 +70,12 @@ module Mongo
65
70
  #
66
71
  # @since 2.0.0
67
72
  def to_mongos
68
- preference = { :mode => 'nearest' }
69
- preference.merge!({ :tags => tag_sets }) unless tag_sets.empty?
70
- preference.merge!({ maxStalenessSeconds: max_staleness }) if max_staleness
71
- preference
73
+ @doc ||= (preference = { :mode => SERVER_FORMATTED_NAME }
74
+ preference.merge!({ :tags => tag_sets }) unless tag_sets.empty?
75
+ preference.merge!({ maxStalenessSeconds: max_staleness }) if max_staleness
76
+ preference)
72
77
  end
78
+ alias :to_doc :to_mongos
73
79
 
74
80
  private
75
81
 
@@ -23,6 +23,11 @@ module Mongo
23
23
  class Primary
24
24
  include Selectable
25
25
 
26
+ # Name of the this read preference in the server's format.
27
+ #
28
+ # @since 2.5.0
29
+ SERVER_FORMATTED_NAME = 'primary'.freeze
30
+
26
31
  # Get the name of the server mode type.
27
32
  #
28
33
  # @example Get the name of the server mode for this preference.
@@ -69,6 +74,21 @@ module Mongo
69
74
  nil
70
75
  end
71
76
 
77
+ # Convert this server preference definition into a format appropriate
78
+ # for a mongodb server.
79
+ #
80
+ # @example Convert this server preference definition into a format
81
+ # for a server.
82
+ # preference = Mongo::ServerSelector::Primary.new
83
+ # preference.to_doc
84
+ #
85
+ # @return [ Hash ] The server preference formatted for a mongodb server.
86
+ #
87
+ # @since 2.5.0
88
+ def to_doc
89
+ @doc ||= { mode: SERVER_FORMATTED_NAME }
90
+ end
91
+
72
92
  private
73
93
 
74
94
  # Select the primary server from a list of candidates.
@@ -23,6 +23,11 @@ module Mongo
23
23
  class PrimaryPreferred
24
24
  include Selectable
25
25
 
26
+ # Name of the this read preference in the server's format.
27
+ #
28
+ # @since 2.5.0
29
+ SERVER_FORMATTED_NAME = 'primaryPreferred'.freeze
30
+
26
31
  # Get the name of the server mode type.
27
32
  #
28
33
  # @example Get the name of the server mode for this preference.
@@ -66,11 +71,12 @@ module Mongo
66
71
  #
67
72
  # @since 2.0.0
68
73
  def to_mongos
69
- preference = { :mode => 'primaryPreferred' }
70
- preference.merge!({ :tags => tag_sets }) unless tag_sets.empty?
71
- preference.merge!({ maxStalenessSeconds: max_staleness }) if max_staleness
72
- preference
74
+ @doc ||= (preference = { :mode => SERVER_FORMATTED_NAME }
75
+ preference.merge!({ :tags => tag_sets }) unless tag_sets.empty?
76
+ preference.merge!({ maxStalenessSeconds: max_staleness }) if max_staleness
77
+ preference)
73
78
  end
79
+ alias :to_doc :to_mongos
74
80
 
75
81
  private
76
82
 
@@ -23,6 +23,11 @@ module Mongo
23
23
  class Secondary
24
24
  include Selectable
25
25
 
26
+ # Name of the this read preference in the server's format.
27
+ #
28
+ # @since 2.5.0
29
+ SERVER_FORMATTED_NAME = 'secondary'.freeze
30
+
26
31
  # Get the name of the server mode type.
27
32
  #
28
33
  # @example Get the name of the server mode for this preference.
@@ -66,11 +71,12 @@ module Mongo
66
71
  #
67
72
  # @since 2.0.0
68
73
  def to_mongos
69
- preference = { :mode => 'secondary' }
70
- preference.merge!({ :tags => tag_sets }) unless tag_sets.empty?
71
- preference.merge!({ maxStalenessSeconds: max_staleness }) if max_staleness
72
- preference
74
+ @doc ||= (preference = { :mode => SERVER_FORMATTED_NAME }
75
+ preference.merge!({ :tags => tag_sets }) unless tag_sets.empty?
76
+ preference.merge!({ maxStalenessSeconds: max_staleness }) if max_staleness
77
+ preference)
73
78
  end
79
+ alias :to_doc :to_mongos
74
80
 
75
81
  private
76
82
 
@@ -23,6 +23,11 @@ module Mongo
23
23
  class SecondaryPreferred
24
24
  include Selectable
25
25
 
26
+ # Name of the this read preference in the server's format.
27
+ #
28
+ # @since 2.5.0
29
+ SERVER_FORMATTED_NAME = 'secondaryPreferred'.freeze
30
+
26
31
  # Get the name of the server mode type.
27
32
  #
28
33
  # @example Get the name of the server mode for this preference.
@@ -69,10 +74,25 @@ module Mongo
69
74
  # @since 2.0.0
70
75
  def to_mongos
71
76
  return nil if tag_sets.empty? && max_staleness.nil?
72
- preference = { mode: 'secondaryPreferred' }
73
- preference.merge!({ tags: tag_sets }) unless tag_sets.empty?
74
- preference.merge!({ maxStalenessSeconds: max_staleness }) if max_staleness
75
- preference
77
+ to_doc
78
+ end
79
+
80
+ # Convert this server preference definition into a format appropriate
81
+ # for a server.
82
+ #
83
+ # @example Convert this server preference definition into a format
84
+ # for a server.
85
+ # preference = Mongo::ServerSelector::SecondaryPreferred.new
86
+ # preference.to_doc
87
+ #
88
+ # @return [ Hash ] The server preference formatted for a server.
89
+ #
90
+ # @since 2.5.0
91
+ def to_doc
92
+ @doc ||= (preference = { mode: SERVER_FORMATTED_NAME }
93
+ preference.merge!({ tags: tag_sets }) unless tag_sets.empty?
94
+ preference.merge!({ maxStalenessSeconds: max_staleness }) if max_staleness
95
+ preference)
76
96
  end
77
97
 
78
98
  private
@@ -0,0 +1,180 @@
1
+ # Copyright (C) 2017 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
+ require 'mongo/session/session_pool'
16
+ require 'mongo/session/server_session'
17
+
18
+ module Mongo
19
+
20
+ # A logical client session representing a set of sequential operations executed
21
+ # by an application that are related in some way.
22
+ #
23
+ # @since 2.5.0
24
+ class Session
25
+ extend Forwardable
26
+
27
+ # Get the options for this session.
28
+ #
29
+ # @since 2.5.0
30
+ attr_reader :options
31
+
32
+ # Get the client through which this session was created.
33
+ #
34
+ # @since 2.5.0
35
+ attr_reader :client
36
+
37
+ def_delegators :@server_session, :session_id
38
+
39
+ # Error message describing that the session was attempted to be used by a client different from the
40
+ # one it was originally associated with.
41
+ #
42
+ # @since 2.5.0
43
+ MISTMATCHED_CLUSTER_ERROR_MSG = 'The client used to create this session does not match that of client ' +
44
+ 'initiating this operation. Please only use this session for operations through its parent client.'.freeze
45
+
46
+ # Error message describing that the session cannot be used because it has already been ended.
47
+ #
48
+ # @since 2.5.0
49
+ SESSION_ENDED_ERROR_MSG = 'This session has ended and cannot be used. Please create a new one.'.freeze
50
+
51
+ # Error message describing that sessions are not supported by the server version.
52
+ #
53
+ # @since 2.5.0
54
+ SESSIONS_NOT_SUPPORTED = 'Sessions are not supported by the connected servers.'.freeze
55
+
56
+ # Initialize a Session.
57
+ #
58
+ # @example
59
+ # Session.new(server_session, client, options)
60
+ #
61
+ # @param [ ServerSession ] server_session The server session this client session is associated with.
62
+ # @param [ Client ] client The client through which this session is created.
63
+ # @param [ Hash ] options The options for this session.
64
+ #
65
+ # @since 2.5.0
66
+ def initialize(server_session, client, options = {})
67
+ @server_session = server_session
68
+ @client = client
69
+ @options = options
70
+ end
71
+
72
+ # End this session.
73
+ #
74
+ # @example
75
+ # session.end_session
76
+ #
77
+ # @return [ nil ] Always nil.
78
+ #
79
+ # @since 2.5.0
80
+ def end_session
81
+ if !ended? && @client
82
+ @client.instance_variable_get(:@session_pool).checkin(@server_session)
83
+ nil
84
+ end
85
+ ensure
86
+ @server_session = nil
87
+ end
88
+
89
+ # End this session if it's an implicit session.
90
+ #
91
+ # @example
92
+ # session.end_implicit_session
93
+ #
94
+ # @return [ nil ] Always nil.
95
+ #
96
+ # @since 2.5.0
97
+ def end_implicit_session
98
+ end_session if implicit_session?
99
+ end
100
+
101
+ # Whether this session has ended.
102
+ #
103
+ # @example
104
+ # session.ended?
105
+ #
106
+ # @return [ true, false ] Whether the session has ended.
107
+ #
108
+ # @since 2.5.0
109
+ def ended?
110
+ @server_session.nil?
111
+ end
112
+
113
+ # Add this session's id to a command document.
114
+ #
115
+ # @example
116
+ # session.add_id!(cmd)
117
+ #
118
+ # @return [ Hash, BSON::Document ] The command document.
119
+ #
120
+ # @since 2.5.0
121
+ def add_id!(command)
122
+ command.merge!(lsid: session_id)
123
+ end
124
+
125
+ # Validate the session.
126
+ #
127
+ # @example
128
+ # session.validate!(client)
129
+ #
130
+ # @param [ Client ] client The client the session is attempted to be used with.
131
+ #
132
+ # @return [ nil ] nil if the session is valid.
133
+ #
134
+ # @raise [ Mongo::Error::InvalidSession ] Raise error if the session is not valid.
135
+ #
136
+ # @since 2.5.0
137
+ def validate!(client)
138
+ check_matching_client!(client)
139
+ check_if_ended!
140
+ end
141
+
142
+ # Process a response from the server that used this session.
143
+ #
144
+ # @example Process a response from the server.
145
+ # session.process(result)
146
+ #
147
+ # @param [ Operation::Result ] The result from the operation.
148
+ #
149
+ # @return [ Operation::Result ] The result.
150
+ #
151
+ # @since 2.5.0
152
+ def process(result)
153
+ set_operation_time(result)
154
+ @server_session.set_last_use!
155
+ result
156
+ end
157
+
158
+ private
159
+
160
+ def implicit_session?
161
+ @implicit_session ||= !!(@options.key?(:implicit) && @options[:implicit] == true)
162
+ end
163
+
164
+ def set_operation_time(result)
165
+ if result && result.operation_time
166
+ @operation_time = result.operation_time
167
+ end
168
+ end
169
+
170
+ def check_if_ended!
171
+ raise Mongo::Error::InvalidSession.new(SESSION_ENDED_ERROR_MSG) if ended?
172
+ end
173
+
174
+ def check_matching_client!(client)
175
+ if @client != client
176
+ raise Mongo::Error::InvalidSession.new(MISTMATCHED_CLUSTER_ERROR_MSG)
177
+ end
178
+ end
179
+ end
180
+ end