mongo 2.5.0 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|