mongo 2.5.0 → 2.5.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +2 -0
- data/Rakefile +4 -1
- data/lib/mongo/address.rb +2 -1
- data/lib/mongo/client.rb +6 -51
- data/lib/mongo/cluster.rb +34 -4
- data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -1
- data/lib/mongo/cluster/topology/replica_set.rb +3 -1
- data/lib/mongo/collection.rb +6 -6
- data/lib/mongo/collection/view.rb +2 -4
- data/lib/mongo/cursor.rb +9 -4
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/operation/uses_command_op_msg.rb +1 -1
- data/lib/mongo/server.rb +3 -0
- data/lib/mongo/server/description.rb +1 -1
- data/lib/mongo/server/description/features.rb +18 -12
- data/lib/mongo/server_selector/selectable.rb +5 -1
- data/lib/mongo/session.rb +38 -43
- data/lib/mongo/session/session_pool.rb +12 -30
- data/lib/mongo/socket.rb +24 -0
- data/lib/mongo/socket/tcp.rb +0 -1
- data/lib/mongo/uri.rb +26 -5
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/address_spec.rb +37 -2
- data/spec/mongo/bulk_write_spec.rb +4 -10
- data/spec/mongo/change_stream_examples_spec.rb +40 -0
- data/spec/mongo/client_spec.rb +47 -12
- data/spec/mongo/cluster/topology/replica_set_spec.rb +2 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +2 -8
- data/spec/mongo/collection/view/change_stream_spec.rb +1 -5
- data/spec/mongo/collection/view/map_reduce_spec.rb +2 -8
- data/spec/mongo/collection/view/readable_spec.rb +1 -1
- data/spec/mongo/collection_spec.rb +11 -29
- data/spec/mongo/crud_spec.rb +6 -2
- data/spec/mongo/cursor_spec.rb +84 -1
- data/spec/mongo/database_spec.rb +2 -8
- data/spec/mongo/dns_seedlist_discovery_spec.rb +67 -63
- data/spec/mongo/max_staleness_spec.rb +1 -0
- data/spec/mongo/retryable_writes_spec.rb +7 -9
- data/spec/mongo/sdam_spec.rb +42 -24
- data/spec/mongo/server/description/features_spec.rb +3 -3
- data/spec/mongo/server_selection_spec.rb +2 -0
- data/spec/mongo/server_selector_spec.rb +2 -0
- data/spec/mongo/session/session_pool_spec.rb +16 -22
- data/spec/mongo/session_spec.rb +13 -8
- data/spec/mongo/uri/srv_protocol_spec.rb +481 -478
- data/spec/mongo/uri_spec.rb +1 -1
- data/spec/spec_helper.rb +11 -63
- data/spec/support/authorization.rb +35 -1
- data/spec/support/connection_string_tests/invalid-uris.yml +27 -11
- data/spec/support/event_subscriber.rb +66 -0
- data/spec/support/sdam/rs/compatible.yml +41 -0
- data/spec/support/sdam/rs/discover_arbiters.yml +3 -1
- data/spec/support/sdam/rs/discover_passives.yml +6 -2
- data/spec/support/sdam/rs/discover_primary.yml +3 -1
- data/spec/support/sdam/rs/discover_secondary.yml +3 -1
- data/spec/support/sdam/rs/discovery.yml +12 -4
- data/spec/support/sdam/rs/equal_electionids.yml +6 -2
- data/spec/support/sdam/rs/ghost_discovered.yml +3 -1
- data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +3 -1
- data/spec/support/sdam/rs/ls_timeout.yml +169 -14
- data/spec/support/sdam/rs/member_reconfig.yml +6 -2
- data/spec/support/sdam/rs/member_standalone.yml +6 -2
- data/spec/support/sdam/rs/new_primary.yml +6 -2
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +9 -3
- data/spec/support/sdam/rs/new_primary_new_setversion.yml +9 -3
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +6 -2
- data/spec/support/sdam/rs/non_rs_member.yml +3 -2
- data/spec/support/sdam/rs/normalize_case.yml +3 -1
- data/spec/support/sdam/rs/null_election_id.yml +12 -4
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +6 -4
- data/spec/support/sdam/rs/primary_changes_set_name.yml +6 -2
- data/spec/support/sdam/rs/primary_disconnect.yml +3 -1
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +15 -5
- data/spec/support/sdam/rs/primary_disconnect_setversion.yml +15 -5
- data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +6 -2
- data/spec/support/sdam/rs/primary_mismatched_me.yml +26 -37
- data/spec/support/sdam/rs/primary_reports_new_member.yml +12 -4
- data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +6 -2
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +3 -1
- data/spec/support/sdam/rs/response_from_removed.yml +6 -2
- data/spec/support/sdam/rs/rsother_discovered.yml +6 -2
- data/spec/support/sdam/rs/sec_not_auth.yml +6 -2
- data/spec/support/sdam/rs/secondary_mismatched_me.yml +26 -37
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +3 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +6 -2
- data/spec/support/sdam/rs/setversion_without_electionid.yml +6 -2
- data/spec/support/sdam/rs/stepdown_change_set_name.yml +6 -2
- data/spec/support/sdam/rs/too_new.yml +41 -0
- data/spec/support/sdam/rs/too_old.yml +39 -0
- data/spec/support/sdam/rs/unexpected_mongos.yml +3 -1
- data/spec/support/sdam/rs/use_setversion_without_electionid.yml +9 -3
- data/spec/support/sdam/rs/wrong_set_name.yml +3 -1
- data/spec/support/server_discovery_and_monitoring.rb +13 -0
- data/spec/support/shared/session.rb +10 -30
- metadata +10 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22155206427257fef9e634311719afb58b03f76c
|
4
|
+
data.tar.gz: c156ef4a3569277ad0c398455d7983c3e2475051
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4252e5a66f31ee3ba496bd573b37ee08f0dd513b3d1e1b154da01c7d34dc19714fc929de7454cc4ea0415fbb44312a8b1c29cf06c1cfb20adee72e97cd917443
|
7
|
+
data.tar.gz: efb7c93290353223cfc910a383b0a0edd9f2d0cc3b6405389256f48fe1dd1ed3647449db8d07663300303ba07a25a038f46d4c2ee5b1bdc0e804890e73b698b6
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -45,6 +45,8 @@ Running Tests
|
|
45
45
|
|
46
46
|
The driver uses RSpec as it's primary testing tool. To run all tests simple run `rspec`.
|
47
47
|
|
48
|
+
If you need to run the tests without making any external connections, set the ENV variable EXTERNAL_DISABLED to 'true'.
|
49
|
+
|
48
50
|
To run a test at a specific location (where `42` is the line number), use:
|
49
51
|
|
50
52
|
rspec path/to/spec.rb:42
|
data/Rakefile
CHANGED
@@ -15,7 +15,10 @@ Bundler.require(*default_groups)
|
|
15
15
|
|
16
16
|
require 'rspec/core/rake_task'
|
17
17
|
|
18
|
-
RSpec::Core::RakeTask.new(:spec)
|
18
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
19
|
+
t.rspec_opts = "--profile 5" if ENV['CI']
|
20
|
+
end
|
21
|
+
|
19
22
|
task :default => :spec
|
20
23
|
|
21
24
|
namespace :spec do
|
data/lib/mongo/address.rb
CHANGED
@@ -185,7 +185,8 @@ module Mongo
|
|
185
185
|
error = nil
|
186
186
|
::Socket.getaddrinfo(host, nil, family, ::Socket::SOCK_STREAM).each do |info|
|
187
187
|
begin
|
188
|
-
|
188
|
+
_host = (host == LOCALHOST) ? info[3] : host
|
189
|
+
res = FAMILY_MAP[info[4]].new(_host, port, host)
|
189
190
|
res.socket(connect_timeout, ssl_options).connect!(connect_timeout).close
|
190
191
|
return res
|
191
192
|
rescue IOError, SystemCallError, Error::SocketTimeoutError, Error::SocketError => e
|
data/lib/mongo/client.rb
CHANGED
@@ -96,8 +96,6 @@ module Mongo
|
|
96
96
|
# Delegate subscription to monitoring.
|
97
97
|
def_delegators :@monitoring, :subscribe, :unsubscribe
|
98
98
|
|
99
|
-
def_delegators :@cluster, :logical_session_timeout
|
100
|
-
|
101
99
|
# Determine if this client is equivalent to another object.
|
102
100
|
#
|
103
101
|
# @example Check client equality.
|
@@ -249,32 +247,14 @@ module Mongo
|
|
249
247
|
# @since 2.0.0
|
250
248
|
def initialize(addresses_or_uri, options = Options::Redacted.new)
|
251
249
|
@monitoring = Monitoring.new(options)
|
252
|
-
Session::SessionPool.create(self)
|
253
250
|
if addresses_or_uri.is_a?(::String)
|
254
251
|
create_from_uri(addresses_or_uri, validate_options!(options))
|
255
252
|
else
|
256
253
|
create_from_addresses(addresses_or_uri, validate_options!(options))
|
257
254
|
end
|
258
|
-
ObjectSpace.define_finalizer(self, self.class.finalize(@session_pool))
|
259
255
|
yield(self) if block_given?
|
260
256
|
end
|
261
257
|
|
262
|
-
# Finalize the client for garbage collection. Ends all sessions in the session pool.
|
263
|
-
#
|
264
|
-
# @example Finalize the client.
|
265
|
-
# Client.finalize(session_pool)
|
266
|
-
#
|
267
|
-
# @param [ Session::SessionPool ] session_pool The session pool.
|
268
|
-
#
|
269
|
-
# @return [ Proc ] The Finalizer.
|
270
|
-
#
|
271
|
-
# @since 2.5.0
|
272
|
-
def self.finalize(session_pool)
|
273
|
-
proc do
|
274
|
-
begin; session_pool.end_sessions; rescue; end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
258
|
# Get an inspection of the client as a string.
|
279
259
|
#
|
280
260
|
# @example Inspect the client.
|
@@ -345,7 +325,6 @@ module Mongo
|
|
345
325
|
opts = validate_options!(new_options)
|
346
326
|
client.options.update(opts)
|
347
327
|
Database.create(client)
|
348
|
-
Session::SessionPool.create(client)
|
349
328
|
# We can't use the same cluster if some options that would affect it
|
350
329
|
# have changed.
|
351
330
|
if cluster_modifying?(opts)
|
@@ -445,7 +424,7 @@ module Mongo
|
|
445
424
|
# Start a session.
|
446
425
|
#
|
447
426
|
# @example Start a session.
|
448
|
-
# client.start_session
|
427
|
+
# client.start_session(causal_consistency: true)
|
449
428
|
#
|
450
429
|
# @param [ Hash ] options The session options.
|
451
430
|
#
|
@@ -456,42 +435,18 @@ module Mongo
|
|
456
435
|
#
|
457
436
|
# @since 2.5.0
|
458
437
|
def start_session(options = {})
|
459
|
-
|
460
|
-
raise Error::InvalidSession.new(Session::SESSIONS_NOT_SUPPORTED)
|
461
|
-
end
|
462
|
-
Session.new(@session_pool.checkout, self, options)
|
438
|
+
cluster.send(:get_session, options.merge(implicit: false)) ||
|
439
|
+
(raise Error::InvalidSession.new(Session::SESSIONS_NOT_SUPPORTED))
|
463
440
|
end
|
464
441
|
|
465
442
|
private
|
466
443
|
|
467
444
|
def get_session(options = {})
|
468
|
-
|
469
|
-
options[:session].validate!(self)
|
470
|
-
options[:session]
|
471
|
-
elsif sessions_supported?
|
472
|
-
Session.new(@session_pool.checkout, self, options.merge(implicit: true))
|
473
|
-
end
|
474
|
-
end
|
475
|
-
|
476
|
-
def with_session(options = {})
|
477
|
-
if options[:session]
|
478
|
-
options[:session].validate!(self)
|
479
|
-
yield(options[:session])
|
480
|
-
elsif sessions_supported?
|
481
|
-
@session_pool.with_session do |server_session|
|
482
|
-
yield(Session.new(server_session, self, options))
|
483
|
-
end
|
484
|
-
else
|
485
|
-
yield
|
486
|
-
end
|
445
|
+
cluster.send(:get_session, options)
|
487
446
|
end
|
488
447
|
|
489
|
-
def
|
490
|
-
|
491
|
-
ServerSelector.get(mode: :primary_preferred).select_server(cluster)
|
492
|
-
end
|
493
|
-
!!logical_session_timeout
|
494
|
-
rescue Error::NoServerAvailable
|
448
|
+
def with_session(options = {}, &block)
|
449
|
+
cluster.send(:with_session, options, &block)
|
495
450
|
end
|
496
451
|
|
497
452
|
def create_from_addresses(addresses, opts = Options::Redacted.new)
|
data/lib/mongo/cluster.rb
CHANGED
@@ -75,6 +75,11 @@ module Mongo
|
|
75
75
|
# @since 2.5.0
|
76
76
|
attr_reader :cluster_time
|
77
77
|
|
78
|
+
# @private
|
79
|
+
#
|
80
|
+
# @since 2.5.1
|
81
|
+
attr_reader :session_pool
|
82
|
+
|
78
83
|
def_delegators :topology, :replica_set?, :replica_set_name, :sharded?,
|
79
84
|
:single?, :unknown?, :member_discovered
|
80
85
|
def_delegators :@cursor_reaper, :register_cursor, :schedule_kill_cursor, :unregister_cursor
|
@@ -173,6 +178,7 @@ module Mongo
|
|
173
178
|
@cluster_time = nil
|
174
179
|
@cluster_time_lock = Mutex.new
|
175
180
|
@topology = Topology.initial(seeds, monitoring, options)
|
181
|
+
Session::SessionPool.create(self)
|
176
182
|
|
177
183
|
publish_sdam_event(
|
178
184
|
Monitoring::TOPOLOGY_OPENING,
|
@@ -195,7 +201,7 @@ module Mongo
|
|
195
201
|
@periodic_executor = PeriodicExecutor.new(@cursor_reaper, @socket_reaper)
|
196
202
|
@periodic_executor.run!
|
197
203
|
|
198
|
-
ObjectSpace.define_finalizer(self, self.class.finalize(pools, @periodic_executor))
|
204
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(pools, @periodic_executor, @session_pool))
|
199
205
|
end
|
200
206
|
|
201
207
|
# Finalize the cluster for garbage collection. Disconnects all the scoped
|
@@ -204,14 +210,16 @@ module Mongo
|
|
204
210
|
# @example Finalize the cluster.
|
205
211
|
# Cluster.finalize(pools)
|
206
212
|
#
|
207
|
-
# @param [ Hash<Address, Server::ConnectionPool> ] pools The connection
|
208
|
-
#
|
213
|
+
# @param [ Hash<Address, Server::ConnectionPool> ] pools The connection pools.
|
214
|
+
# @param [ PeriodicExecutor ] periodic_executor The periodic executor.
|
215
|
+
# @param [ SessionPool ] session_pool The session pool.
|
209
216
|
#
|
210
217
|
# @return [ Proc ] The Finalizer.
|
211
218
|
#
|
212
219
|
# @since 2.2.0
|
213
|
-
def self.finalize(pools, periodic_executor)
|
220
|
+
def self.finalize(pools, periodic_executor, session_pool)
|
214
221
|
proc do
|
222
|
+
session_pool.end_sessions
|
215
223
|
periodic_executor.stop!
|
216
224
|
pools.values.each do |pool|
|
217
225
|
pool.disconnect!
|
@@ -495,6 +503,28 @@ module Mongo
|
|
495
503
|
|
496
504
|
private
|
497
505
|
|
506
|
+
def get_session(options = {})
|
507
|
+
return options[:session].validate!(self) if options[:session]
|
508
|
+
if sessions_supported?
|
509
|
+
Session.new(@session_pool.checkout, self, { implicit: true }.merge(options))
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
def with_session(options = {})
|
514
|
+
session = get_session(options)
|
515
|
+
yield(session)
|
516
|
+
ensure
|
517
|
+
session.end_session if (session && session.implicit?)
|
518
|
+
end
|
519
|
+
|
520
|
+
def sessions_supported?
|
521
|
+
if servers.empty? && !topology.single?
|
522
|
+
ServerSelector.get(mode: :primary_preferred).select_server(self)
|
523
|
+
end
|
524
|
+
!!logical_session_timeout
|
525
|
+
rescue Error::NoServerAvailable
|
526
|
+
end
|
527
|
+
|
498
528
|
def direct_connection?(address)
|
499
529
|
address.seed == @topology.seed
|
500
530
|
end
|
@@ -29,7 +29,7 @@ module Mongo
|
|
29
29
|
# @example Initialize the socket reaper.
|
30
30
|
# SocketReaper.new(cluster)
|
31
31
|
#
|
32
|
-
# @
|
32
|
+
# @param [ Mongo::Cluster ] cluster The cluster whose pools' stale sockets
|
33
33
|
# need to be reaped at regular intervals.
|
34
34
|
#
|
35
35
|
# @since 2.5.0
|
@@ -217,7 +217,9 @@ module Mongo
|
|
217
217
|
# @since 2.0.6
|
218
218
|
def remove_server?(description, server)
|
219
219
|
remove_self?(description, server) ||
|
220
|
-
(member_of_this_set?(description) &&
|
220
|
+
(member_of_this_set?(description) &&
|
221
|
+
!description.servers.empty? &&
|
222
|
+
!description.lists_server?(server))
|
221
223
|
end
|
222
224
|
|
223
225
|
# A replica set topology is not sharded.
|
data/lib/mongo/collection.rb
CHANGED
@@ -410,23 +410,23 @@ module Mongo
|
|
410
410
|
# collection.insert_one({ name: 'test' })
|
411
411
|
#
|
412
412
|
# @param [ Hash ] document The document to insert.
|
413
|
-
# @param [ Hash ]
|
413
|
+
# @param [ Hash ] opts The insert options.
|
414
414
|
#
|
415
|
-
# @option
|
415
|
+
# @option opts [ Session ] :session The session to use for the operation.
|
416
416
|
#
|
417
417
|
# @return [ Result ] The database response wrapper.
|
418
418
|
#
|
419
419
|
# @since 2.0.0
|
420
|
-
def insert_one(document,
|
421
|
-
client.send(:with_session,
|
420
|
+
def insert_one(document, opts = {})
|
421
|
+
client.send(:with_session, opts) do |session|
|
422
422
|
write_with_retry(session, write_concern) do |server, txn_num|
|
423
423
|
Operation::Write::Insert.new(
|
424
424
|
:documents => [ document ],
|
425
425
|
:db_name => database.name,
|
426
426
|
:coll_name => name,
|
427
427
|
:write_concern => write_concern,
|
428
|
-
:bypass_document_validation => !!
|
429
|
-
:options =>
|
428
|
+
:bypass_document_validation => !!opts[:bypass_document_validation],
|
429
|
+
:options => opts,
|
430
430
|
:id_generator => client.options[:id_generator],
|
431
431
|
:session => session,
|
432
432
|
:txn_num => txn_num
|
@@ -199,10 +199,8 @@ module Mongo
|
|
199
199
|
|
200
200
|
def view; self; end
|
201
201
|
|
202
|
-
def with_session(opts = {})
|
203
|
-
client.send(:with_session, @options.merge(opts))
|
204
|
-
yield(session)
|
205
|
-
end
|
202
|
+
def with_session(opts = {}, &block)
|
203
|
+
client.send(:with_session, @options.merge(opts), &block)
|
206
204
|
end
|
207
205
|
end
|
208
206
|
end
|
data/lib/mongo/cursor.rb
CHANGED
@@ -69,7 +69,8 @@ module Mongo
|
|
69
69
|
ObjectSpace.define_finalizer(self, self.class.finalize(result.cursor_id,
|
70
70
|
cluster,
|
71
71
|
kill_cursors_op_spec,
|
72
|
-
server
|
72
|
+
server,
|
73
|
+
@session))
|
73
74
|
end
|
74
75
|
|
75
76
|
|
@@ -87,8 +88,11 @@ module Mongo
|
|
87
88
|
# @return [ Proc ] The Finalizer.
|
88
89
|
#
|
89
90
|
# @since 2.3.0
|
90
|
-
def self.finalize(cursor_id, cluster, op_spec, server)
|
91
|
-
proc
|
91
|
+
def self.finalize(cursor_id, cluster, op_spec, server, session)
|
92
|
+
proc do
|
93
|
+
cluster.schedule_kill_cursor(cursor_id, op_spec, server)
|
94
|
+
session.end_session if session && session.implicit?
|
95
|
+
end
|
92
96
|
end
|
93
97
|
|
94
98
|
# Get a human-readable string representation of +Cursor+.
|
@@ -219,7 +223,7 @@ module Mongo
|
|
219
223
|
end
|
220
224
|
|
221
225
|
def end_session
|
222
|
-
@session.
|
226
|
+
@session.end_session if @session && @session.implicit?
|
223
227
|
end
|
224
228
|
|
225
229
|
def kill_cursors_operation
|
@@ -251,6 +255,7 @@ module Mongo
|
|
251
255
|
@coll_name ||= result.namespace.sub("#{database.name}.", '') if result.namespace
|
252
256
|
unregister if result.cursor_id == 0
|
253
257
|
@cursor_id = result.cursor_id
|
258
|
+
end_session if !more?
|
254
259
|
result.documents
|
255
260
|
end
|
256
261
|
|
data/lib/mongo/error.rb
CHANGED
@@ -58,7 +58,7 @@ module Mongo
|
|
58
58
|
apply_session_id!(selector)
|
59
59
|
apply_causal_consistency!(selector, server)
|
60
60
|
end
|
61
|
-
elsif session && !session.
|
61
|
+
elsif session && !session.implicit?
|
62
62
|
apply_cluster_time!(selector, server)
|
63
63
|
apply_session_id!(selector)
|
64
64
|
apply_causal_consistency!(selector, server)
|
data/lib/mongo/server.rb
CHANGED
@@ -264,7 +264,7 @@ module Mongo
|
|
264
264
|
def initialize(address, config = {}, average_round_trip_time = 0)
|
265
265
|
@address = address
|
266
266
|
@config = config
|
267
|
-
@features = Features.new(wire_versions, me)
|
267
|
+
@features = Features.new(wire_versions, me || @address.to_s)
|
268
268
|
@average_round_trip_time = average_round_trip_time
|
269
269
|
end
|
270
270
|
|
@@ -88,21 +88,27 @@ module Mongo
|
|
88
88
|
# @since 2.0.0
|
89
89
|
def initialize(server_wire_versions, address = nil)
|
90
90
|
@server_wire_versions = server_wire_versions
|
91
|
-
|
91
|
+
@address = address
|
92
92
|
end
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
94
|
+
# Check that there is an overlap between the driver supported wire version range
|
95
|
+
# and the server wire version range.
|
96
|
+
#
|
97
|
+
# @example Verify the wire version overlap.
|
98
|
+
# features.check_driver_support!
|
99
|
+
#
|
100
|
+
# @raise [ Error::UnsupportedFeatures ] If the wire version range is not covered
|
101
|
+
# by the driver.
|
102
|
+
#
|
103
|
+
# @since 2.5.1
|
104
|
+
def check_driver_support!
|
105
|
+
if DRIVER_WIRE_VERSIONS.min > @server_wire_versions.max
|
106
|
+
raise Error::UnsupportedFeatures.new(SERVER_TOO_OLD % [@address,
|
107
|
+
@server_wire_versions.max,
|
102
108
|
DRIVER_WIRE_VERSIONS.min])
|
103
|
-
elsif DRIVER_WIRE_VERSIONS.max < server_wire_versions.min
|
104
|
-
raise Error::UnsupportedFeatures.new(DRIVER_TOO_OLD % [address,
|
105
|
-
server_wire_versions.min,
|
109
|
+
elsif DRIVER_WIRE_VERSIONS.max < @server_wire_versions.min
|
110
|
+
raise Error::UnsupportedFeatures.new(DRIVER_TOO_OLD % [@address,
|
111
|
+
@server_wire_versions.min,
|
106
112
|
DRIVER_WIRE_VERSIONS.max])
|
107
113
|
end
|
108
114
|
end
|
@@ -105,8 +105,12 @@ module Mongo
|
|
105
105
|
# There is no point pinging a standalone as the subsequent scan is
|
106
106
|
# not going to change anything about the cluster.
|
107
107
|
if ping && !cluster.single?
|
108
|
-
|
108
|
+
if server.connectable?
|
109
|
+
server.check_driver_support!
|
110
|
+
return server
|
111
|
+
end
|
109
112
|
else
|
113
|
+
server.check_driver_support!
|
110
114
|
return server
|
111
115
|
end
|
112
116
|
end
|
data/lib/mongo/session.rb
CHANGED
@@ -17,7 +17,7 @@ require 'mongo/session/server_session'
|
|
17
17
|
|
18
18
|
module Mongo
|
19
19
|
|
20
|
-
# A logical
|
20
|
+
# A logical session representing a set of sequential operations executed
|
21
21
|
# by an application that are related in some way.
|
22
22
|
#
|
23
23
|
# @since 2.5.0
|
@@ -29,10 +29,10 @@ module Mongo
|
|
29
29
|
# @since 2.5.0
|
30
30
|
attr_reader :options
|
31
31
|
|
32
|
-
# Get the
|
32
|
+
# Get the cluster through which this session was created.
|
33
33
|
#
|
34
|
-
# @since 2.5.
|
35
|
-
attr_reader :
|
34
|
+
# @since 2.5.1
|
35
|
+
attr_reader :cluster
|
36
36
|
|
37
37
|
# The cluster time for this session.
|
38
38
|
#
|
@@ -44,14 +44,13 @@ module Mongo
|
|
44
44
|
# @since 2.5.0
|
45
45
|
attr_reader :operation_time
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
# Error message describing that the session was attempted to be used by a client different from the
|
50
|
-
# one it was originally associated with.
|
47
|
+
# Error message indicating that the session was retrieved from a client with a different cluster than that of the
|
48
|
+
# client through which it is currently being used.
|
51
49
|
#
|
52
50
|
# @since 2.5.0
|
53
|
-
MISMATCHED_CLUSTER_ERROR_MSG = 'The client used to create this session does not match that
|
54
|
-
'
|
51
|
+
MISMATCHED_CLUSTER_ERROR_MSG = 'The configuration of the client used to create this session does not match that ' +
|
52
|
+
'of the client owning this operation. Please only use this session for operations through its parent ' +
|
53
|
+
'client.'.freeze
|
55
54
|
|
56
55
|
# Error message describing that the session cannot be used because it has already been ended.
|
57
56
|
#
|
@@ -66,16 +65,16 @@ module Mongo
|
|
66
65
|
# Initialize a Session.
|
67
66
|
#
|
68
67
|
# @example
|
69
|
-
# Session.new(server_session,
|
68
|
+
# Session.new(server_session, cluster, options)
|
70
69
|
#
|
71
|
-
# @param [ ServerSession ] server_session The server session this
|
72
|
-
# @param [
|
70
|
+
# @param [ ServerSession ] server_session The server session this session is associated with.
|
71
|
+
# @param [ Cluster ] cluster The cluster through which this session is created.
|
73
72
|
# @param [ Hash ] options The options for this session.
|
74
73
|
#
|
75
74
|
# @since 2.5.0
|
76
|
-
def initialize(server_session,
|
75
|
+
def initialize(server_session, cluster, options = {})
|
77
76
|
@server_session = server_session
|
78
|
-
@
|
77
|
+
@cluster = cluster
|
79
78
|
@options = options.dup.freeze
|
80
79
|
@cluster_time = nil
|
81
80
|
end
|
@@ -101,26 +100,13 @@ module Mongo
|
|
101
100
|
#
|
102
101
|
# @since 2.5.0
|
103
102
|
def end_session
|
104
|
-
if !ended? && @
|
105
|
-
@
|
106
|
-
nil
|
103
|
+
if !ended? && @cluster
|
104
|
+
@cluster.session_pool.checkin(@server_session)
|
107
105
|
end
|
108
106
|
ensure
|
109
107
|
@server_session = nil
|
110
108
|
end
|
111
109
|
|
112
|
-
# End this session if it's an implicit session.
|
113
|
-
#
|
114
|
-
# @example
|
115
|
-
# session.end_implicit_session
|
116
|
-
#
|
117
|
-
# @return [ nil ] Always nil.
|
118
|
-
#
|
119
|
-
# @since 2.5.0
|
120
|
-
def end_implicit_session
|
121
|
-
end_session if implicit_session?
|
122
|
-
end
|
123
|
-
|
124
110
|
# Whether this session has ended.
|
125
111
|
#
|
126
112
|
# @example
|
@@ -148,18 +134,19 @@ module Mongo
|
|
148
134
|
# Validate the session.
|
149
135
|
#
|
150
136
|
# @example
|
151
|
-
# session.validate!(
|
137
|
+
# session.validate!(cluster)
|
152
138
|
#
|
153
|
-
# @param [
|
139
|
+
# @param [ Cluster ] cluster The cluster the session is attempted to be used with.
|
154
140
|
#
|
155
141
|
# @return [ nil ] nil if the session is valid.
|
156
142
|
#
|
157
143
|
# @raise [ Mongo::Error::InvalidSession ] Raise error if the session is not valid.
|
158
144
|
#
|
159
145
|
# @since 2.5.0
|
160
|
-
def validate!(
|
161
|
-
|
146
|
+
def validate!(cluster)
|
147
|
+
check_matching_cluster!(cluster)
|
162
148
|
check_if_ended!
|
149
|
+
self
|
163
150
|
end
|
164
151
|
|
165
152
|
# Process a response from the server that used this session.
|
@@ -173,7 +160,7 @@ module Mongo
|
|
173
160
|
#
|
174
161
|
# @since 2.5.0
|
175
162
|
def process(result)
|
176
|
-
unless
|
163
|
+
unless implicit?
|
177
164
|
set_operation_time(result)
|
178
165
|
set_cluster_time(result)
|
179
166
|
end
|
@@ -229,7 +216,7 @@ module Mongo
|
|
229
216
|
#
|
230
217
|
# @since 2.5.0
|
231
218
|
def retry_writes?
|
232
|
-
!!
|
219
|
+
!!cluster.options[:retry_writes] && (cluster.replica_set? || cluster.sharded?)
|
233
220
|
end
|
234
221
|
|
235
222
|
# Get the session id.
|
@@ -247,7 +234,7 @@ module Mongo
|
|
247
234
|
# Increment and return the next transaction number.
|
248
235
|
#
|
249
236
|
# @example Get the next transaction number.
|
250
|
-
#
|
237
|
+
# session.next_txn_num
|
251
238
|
#
|
252
239
|
# @return [ Integer ] The next transaction number.
|
253
240
|
#
|
@@ -256,6 +243,18 @@ module Mongo
|
|
256
243
|
@server_session.next_txn_num if @server_session
|
257
244
|
end
|
258
245
|
|
246
|
+
# Is this session an implicit one (not user-created).
|
247
|
+
#
|
248
|
+
# @example Is the session implicit?
|
249
|
+
# session.implicit?
|
250
|
+
#
|
251
|
+
# @return [ true, false ] Whether this session is implicit.
|
252
|
+
#
|
253
|
+
# @since 2.5.1
|
254
|
+
def implicit?
|
255
|
+
@implicit_session ||= !!(@options.key?(:implicit) && @options[:implicit] == true)
|
256
|
+
end
|
257
|
+
|
259
258
|
private
|
260
259
|
|
261
260
|
def causal_consistency_doc(read_concern)
|
@@ -274,10 +273,6 @@ module Mongo
|
|
274
273
|
end)
|
275
274
|
end
|
276
275
|
|
277
|
-
def implicit_session?
|
278
|
-
@implicit_session ||= !!(@options.key?(:implicit) && @options[:implicit] == true)
|
279
|
-
end
|
280
|
-
|
281
276
|
def set_operation_time(result)
|
282
277
|
if result && result.operation_time
|
283
278
|
@operation_time = result.operation_time
|
@@ -298,8 +293,8 @@ module Mongo
|
|
298
293
|
raise Mongo::Error::InvalidSession.new(SESSION_ENDED_ERROR_MSG) if ended?
|
299
294
|
end
|
300
295
|
|
301
|
-
def
|
302
|
-
if @
|
296
|
+
def check_matching_cluster!(cluster)
|
297
|
+
if @cluster != cluster
|
303
298
|
raise Mongo::Error::InvalidSession.new(MISMATCHED_CLUSTER_ERROR_MSG)
|
304
299
|
end
|
305
300
|
end
|