mongo 2.17.0 → 2.17.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/lib/mongo/cluster/reapers/cursor_reaper.rb +26 -14
- data/lib/mongo/collection/view/builder/map_reduce.rb +7 -4
- data/lib/mongo/collection/view/map_reduce.rb +14 -1
- data/lib/mongo/cursor/kill_spec.rb +19 -2
- data/lib/mongo/cursor.rb +5 -5
- data/lib/mongo/version.rb +1 -1
- data/spec/lite_spec_helper.rb +7 -0
- data/spec/mongo/cluster/cursor_reaper_spec.rb +22 -15
- data/spec/mongo/collection/view/map_reduce_spec.rb +16 -0
- data/spec/mongo/cursor_spec.rb +3 -2
- data/spec/runners/auth.rb +1 -1
- data/spec/runners/change_streams/spec.rb +1 -1
- data/spec/runners/cmap.rb +1 -1
- data/spec/runners/command_monitoring.rb +1 -1
- data/spec/runners/connection_string.rb +1 -1
- data/spec/runners/crud/spec.rb +1 -3
- data/spec/runners/gridfs.rb +1 -1
- data/spec/runners/read_write_concern_document.rb +1 -1
- data/spec/runners/sdam.rb +1 -1
- data/spec/runners/server_selection.rb +1 -1
- data/spec/runners/server_selection_rtt.rb +1 -1
- data/spec/runners/unified/test_group.rb +1 -1
- data/spec/spec_tests/seed_list_discovery_spec.rb +1 -1
- data/spec/support/utils.rb +31 -0
- data.tar.gz.sig +4 -2
- metadata +1056 -1055
- metadata.gz.sig +1 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a38f748fe8350d12ecfd23a30e794b65addcfbf8f5303504f5f85999e2c2b0d
|
4
|
+
data.tar.gz: 876f431a9bfc558ecad0006a32b6ed90b6a94d05ac553a52fbc8b5d3b2b80a55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 256181a9c42fee1b029c899ab56a1a1f5b5283d4071913fc5777ad185f5349a00dc1fa36ac60b9b203a15f1d0857511c551f417f78864a04899e973e8da14b96
|
7
|
+
data.tar.gz: 1272cc35779781fe390276007c831e653b64087e1f34b0459e12d8dfea7099dd39be4e06cef347e36fa7222064ba2f267a5be4a48120d6017f4424876123195b
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -44,6 +44,7 @@ module Mongo
|
|
44
44
|
@to_kill = {}
|
45
45
|
@active_cursor_ids = Set.new
|
46
46
|
@mutex = Mutex.new
|
47
|
+
@kill_spec_queue = Queue.new
|
47
48
|
end
|
48
49
|
|
49
50
|
attr_reader :cluster
|
@@ -51,17 +52,10 @@ module Mongo
|
|
51
52
|
# Schedule a kill cursors operation to be eventually executed.
|
52
53
|
#
|
53
54
|
# @param [ Cursor::KillSpec ] kill_spec The kill specification.
|
54
|
-
# @param [ Mongo::Server ] server The server to send the kill cursors
|
55
|
-
# operation to.
|
56
55
|
#
|
57
56
|
# @api private
|
58
|
-
def schedule_kill_cursor(kill_spec
|
59
|
-
@
|
60
|
-
if @active_cursor_ids.include?(kill_spec.cursor_id)
|
61
|
-
@to_kill[server.address.seed] ||= Set.new
|
62
|
-
@to_kill[server.address.seed] << kill_spec
|
63
|
-
end
|
64
|
-
end
|
57
|
+
def schedule_kill_cursor(kill_spec)
|
58
|
+
@kill_spec_queue << kill_spec
|
65
59
|
end
|
66
60
|
|
67
61
|
# Register a cursor id as active.
|
@@ -110,6 +104,24 @@ module Mongo
|
|
110
104
|
end
|
111
105
|
end
|
112
106
|
|
107
|
+
# Read and decode scheduled kill cursors operations.
|
108
|
+
#
|
109
|
+
# This method mutates instance variables without locking, so is is not
|
110
|
+
# thread safe. Generally, it should not be called itself, this is a helper
|
111
|
+
# for `kill_cursor` method.
|
112
|
+
#
|
113
|
+
# @api private
|
114
|
+
def read_scheduled_kill_specs
|
115
|
+
while kill_spec = @kill_spec_queue.pop(true)
|
116
|
+
if @active_cursor_ids.include?(kill_spec.cursor_id)
|
117
|
+
@to_kill[kill_spec.server_address] ||= Set.new
|
118
|
+
@to_kill[kill_spec.server_address] << kill_spec
|
119
|
+
end
|
120
|
+
end
|
121
|
+
rescue ThreadError
|
122
|
+
# Empty queue, nothing to do.
|
123
|
+
end
|
124
|
+
|
113
125
|
# Execute all pending kill cursors operations.
|
114
126
|
#
|
115
127
|
# @example Execute pending kill cursors operations.
|
@@ -122,14 +134,14 @@ module Mongo
|
|
122
134
|
# TODO optimize this to batch kill cursor operations for the same
|
123
135
|
# server/database/collection instead of killing each cursor
|
124
136
|
# individually.
|
125
|
-
|
126
137
|
loop do
|
127
|
-
|
138
|
+
server_address = nil
|
128
139
|
|
129
140
|
kill_spec = @mutex.synchronize do
|
141
|
+
read_scheduled_kill_specs
|
130
142
|
# Find a server that has any cursors scheduled for destruction.
|
131
|
-
|
132
|
-
@to_kill.detect { |
|
143
|
+
server_address, specs =
|
144
|
+
@to_kill.detect { |_, specs| specs.any? }
|
133
145
|
|
134
146
|
if specs.nil?
|
135
147
|
# All servers have empty specs, nothing to do.
|
@@ -168,7 +180,7 @@ module Mongo
|
|
168
180
|
op = Operation::KillCursors.new(spec)
|
169
181
|
|
170
182
|
server = cluster.servers.detect do |server|
|
171
|
-
server.address
|
183
|
+
server.address == server_address
|
172
184
|
end
|
173
185
|
|
174
186
|
unless server
|
@@ -115,11 +115,14 @@ module Mongo
|
|
115
115
|
end
|
116
116
|
command.update(view_options)
|
117
117
|
command.update(options.slice(:collation))
|
118
|
+
|
118
119
|
# Read preference isn't simply passed in the command payload
|
119
|
-
# (it may need to be converted to wire protocol flags)
|
120
|
-
#
|
121
|
-
#
|
122
|
-
|
120
|
+
# (it may need to be converted to wire protocol flags).
|
121
|
+
# Ideally it should be removed here, however due to Mongoid 7
|
122
|
+
# using this method and requiring :read to be returned from it,
|
123
|
+
# we cannot do this just yet - see RUBY-2932.
|
124
|
+
#command.delete(:read)
|
125
|
+
|
123
126
|
command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
|
124
127
|
command
|
125
128
|
end
|
@@ -250,7 +250,20 @@ module Mongo
|
|
250
250
|
end
|
251
251
|
|
252
252
|
def initial_query_op(session)
|
253
|
-
|
253
|
+
spec = map_reduce_spec(session)
|
254
|
+
# Read preference isn't simply passed in the command payload
|
255
|
+
# (it may need to be converted to wire protocol flags).
|
256
|
+
# Passing it in command payload produces errors on at least
|
257
|
+
# 5.0 mongoses.
|
258
|
+
# In the future map_reduce_command should remove :read
|
259
|
+
# from its return value, however we cannot do this right now
|
260
|
+
# due to Mongoid 7 relying on :read being returned as part of
|
261
|
+
# the command - see RUBY-2932.
|
262
|
+
# Delete :read here for now because it cannot be sent to mongos this way.
|
263
|
+
spec = spec.dup
|
264
|
+
spec[:selector] = spec[:selector].dup
|
265
|
+
spec[:selector].delete(:read)
|
266
|
+
Operation::MapReduce.new(spec)
|
254
267
|
end
|
255
268
|
|
256
269
|
def valid_server?(server)
|
@@ -25,14 +25,31 @@ module Mongo
|
|
25
25
|
# @api private
|
26
26
|
class KillSpec
|
27
27
|
|
28
|
-
def initialize(cursor_id:, coll_name:, db_name:, service_id:)
|
28
|
+
def initialize(cursor_id:, coll_name:, db_name:, service_id:, server_address:)
|
29
29
|
@cursor_id = cursor_id
|
30
30
|
@coll_name = coll_name
|
31
31
|
@db_name = db_name
|
32
32
|
@service_id = service_id
|
33
|
+
@server_address = server_address
|
33
34
|
end
|
34
35
|
|
35
|
-
attr_reader :cursor_id, :coll_name, :db_name, :service_id
|
36
|
+
attr_reader :cursor_id, :coll_name, :db_name, :service_id, :server_address
|
37
|
+
|
38
|
+
def ==(other)
|
39
|
+
cursor_id == other.cursor_id &&
|
40
|
+
coll_name == other.coll_name &&
|
41
|
+
db_name == other.db_name &&
|
42
|
+
service_id == other.service_id &&
|
43
|
+
server_address == other.server_address
|
44
|
+
end
|
45
|
+
|
46
|
+
def eql?(other)
|
47
|
+
self.==(other)
|
48
|
+
end
|
49
|
+
|
50
|
+
def hash
|
51
|
+
[cursor_id, coll_name, db_name, service_id, server_address].compact.hash
|
52
|
+
end
|
36
53
|
end
|
37
54
|
end
|
38
55
|
end
|
data/lib/mongo/cursor.rb
CHANGED
@@ -84,9 +84,8 @@ module Mongo
|
|
84
84
|
@session = @options[:session]
|
85
85
|
unless closed?
|
86
86
|
register
|
87
|
-
ObjectSpace.define_finalizer(self, self.class.finalize(kill_spec,
|
87
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(kill_spec(server),
|
88
88
|
cluster,
|
89
|
-
server,
|
90
89
|
@session))
|
91
90
|
end
|
92
91
|
end
|
@@ -107,12 +106,12 @@ module Mongo
|
|
107
106
|
# @return [ Proc ] The Finalizer.
|
108
107
|
#
|
109
108
|
# @api private
|
110
|
-
def self.finalize(kill_spec, cluster,
|
109
|
+
def self.finalize(kill_spec, cluster, session)
|
111
110
|
unless KillSpec === kill_spec
|
112
111
|
raise ArgumentError, "First argument must be a KillSpec: #{kill_spec.inspect}"
|
113
112
|
end
|
114
113
|
proc do
|
115
|
-
cluster.schedule_kill_cursor(kill_spec
|
114
|
+
cluster.schedule_kill_cursor(kill_spec)
|
116
115
|
session.end_session if session && session.implicit?
|
117
116
|
end
|
118
117
|
end
|
@@ -367,12 +366,13 @@ module Mongo
|
|
367
366
|
end
|
368
367
|
|
369
368
|
# @api private
|
370
|
-
def kill_spec
|
369
|
+
def kill_spec(server)
|
371
370
|
KillSpec.new(
|
372
371
|
cursor_id: id,
|
373
372
|
coll_name: collection_name,
|
374
373
|
db_name: database.name,
|
375
374
|
service_id: initial_result.connection_description.service_id,
|
375
|
+
server_address: server.address,
|
376
376
|
)
|
377
377
|
end
|
378
378
|
|
data/lib/mongo/version.rb
CHANGED
data/spec/lite_spec_helper.rb
CHANGED
@@ -157,6 +157,13 @@ RSpec.configure do |config|
|
|
157
157
|
end
|
158
158
|
|
159
159
|
if SpecConfig.instance.active_support?
|
160
|
+
require "active_support/version"
|
161
|
+
if ActiveSupport.version >= Gem::Version.new(7)
|
162
|
+
# ActiveSupport wants us to require ALL of it all of the time.
|
163
|
+
# See: https://github.com/rails/rails/issues/43851,
|
164
|
+
# https://github.com/rails/rails/issues/43889, etc.
|
165
|
+
require 'active_support'
|
166
|
+
end
|
160
167
|
require "active_support/time"
|
161
168
|
require 'mongo/active_support'
|
162
169
|
end
|
@@ -41,12 +41,12 @@ describe Mongo::Cluster::CursorReaper do
|
|
41
41
|
let(:cursor_id) { 1 }
|
42
42
|
let(:cursor_kill_spec_1) do
|
43
43
|
Mongo::Cursor::KillSpec.new(
|
44
|
-
cursor_id: cursor_id, coll_name: 'c', db_name: 'd', service_id: nil,
|
44
|
+
cursor_id: cursor_id, coll_name: 'c', db_name: 'd', service_id: nil, server_address: address
|
45
45
|
)
|
46
46
|
end
|
47
47
|
let(:cursor_kill_spec_2) do
|
48
48
|
Mongo::Cursor::KillSpec.new(
|
49
|
-
cursor_id: cursor_id, coll_name: 'c', db_name: 'q', service_id: nil,
|
49
|
+
cursor_id: cursor_id, coll_name: 'c', db_name: 'q', service_id: nil, server_address: address
|
50
50
|
)
|
51
51
|
end
|
52
52
|
let(:to_kill) { reaper.instance_variable_get(:@to_kill)}
|
@@ -60,36 +60,40 @@ describe Mongo::Cluster::CursorReaper do
|
|
60
60
|
context 'when there is not a list already for the server' do
|
61
61
|
|
62
62
|
before do
|
63
|
-
reaper.schedule_kill_cursor(cursor_kill_spec_1
|
63
|
+
reaper.schedule_kill_cursor(cursor_kill_spec_1)
|
64
|
+
reaper.read_scheduled_kill_specs
|
64
65
|
end
|
65
66
|
|
66
67
|
it 'initializes the list of op specs to a set' do
|
67
|
-
expect(to_kill.keys).to eq([ address
|
68
|
-
expect(to_kill[address
|
68
|
+
expect(to_kill.keys).to eq([ address ])
|
69
|
+
expect(to_kill[address]).to contain_exactly(cursor_kill_spec_1)
|
69
70
|
end
|
70
71
|
end
|
71
72
|
|
72
73
|
context 'when there is a list of ops already for the server' do
|
73
74
|
|
74
75
|
before do
|
75
|
-
reaper.schedule_kill_cursor(cursor_kill_spec_1
|
76
|
-
reaper.
|
76
|
+
reaper.schedule_kill_cursor(cursor_kill_spec_1)
|
77
|
+
reaper.read_scheduled_kill_specs
|
78
|
+
reaper.schedule_kill_cursor(cursor_kill_spec_2)
|
79
|
+
reaper.read_scheduled_kill_specs
|
77
80
|
end
|
78
81
|
|
79
82
|
it 'adds the op to the server list' do
|
80
|
-
expect(to_kill.keys).to eq([ address
|
81
|
-
expect(to_kill[address
|
83
|
+
expect(to_kill.keys).to eq([ address ])
|
84
|
+
expect(to_kill[address]).to contain_exactly(cursor_kill_spec_1, cursor_kill_spec_2)
|
82
85
|
end
|
83
86
|
|
84
87
|
context 'when the same op is added more than once' do
|
85
88
|
|
86
89
|
before do
|
87
|
-
reaper.schedule_kill_cursor(cursor_kill_spec_2
|
90
|
+
reaper.schedule_kill_cursor(cursor_kill_spec_2)
|
91
|
+
reaper.read_scheduled_kill_specs
|
88
92
|
end
|
89
93
|
|
90
94
|
it 'does not allow duplicates ops for a server' do
|
91
|
-
expect(to_kill.keys).to eq([ address
|
92
|
-
expect(to_kill[address
|
95
|
+
expect(to_kill.keys).to eq([ address ])
|
96
|
+
expect(to_kill[address]).to contain_exactly(cursor_kill_spec_1, cursor_kill_spec_2)
|
93
97
|
end
|
94
98
|
end
|
95
99
|
end
|
@@ -98,7 +102,7 @@ describe Mongo::Cluster::CursorReaper do
|
|
98
102
|
context 'when the cursor is not on the list of active cursors' do
|
99
103
|
|
100
104
|
before do
|
101
|
-
reaper.schedule_kill_cursor(cursor_kill_spec_1
|
105
|
+
reaper.schedule_kill_cursor(cursor_kill_spec_1)
|
102
106
|
end
|
103
107
|
|
104
108
|
it 'does not add the kill cursors op spec to the list' do
|
@@ -189,8 +193,11 @@ describe Mongo::Cluster::CursorReaper do
|
|
189
193
|
around do |example|
|
190
194
|
authorized_collection.insert_many(docs)
|
191
195
|
periodic_executor.stop!
|
192
|
-
cluster.schedule_kill_cursor(
|
193
|
-
|
196
|
+
cluster.schedule_kill_cursor(
|
197
|
+
cursor.kill_spec(
|
198
|
+
cursor.instance_variable_get(:@server)
|
199
|
+
)
|
200
|
+
)
|
194
201
|
periodic_executor.flush
|
195
202
|
example.run
|
196
203
|
periodic_executor.run!
|
@@ -878,4 +878,20 @@ describe Mongo::Collection::View::MapReduce do
|
|
878
878
|
end
|
879
879
|
end
|
880
880
|
end
|
881
|
+
|
882
|
+
describe '#map_reduce_spec' do
|
883
|
+
context 'when read preference is given' do
|
884
|
+
let(:view_options) do
|
885
|
+
{ read: {mode: :secondary} }
|
886
|
+
end
|
887
|
+
|
888
|
+
context 'selector' do
|
889
|
+
# For compatibility with released versions of Mongoid, this method
|
890
|
+
# must return read preference under the :read key.
|
891
|
+
it 'contains read preference' do
|
892
|
+
map_reduce_spec[:selector][:read].should == {'mode' => :secondary}
|
893
|
+
end
|
894
|
+
end
|
895
|
+
end
|
896
|
+
end
|
881
897
|
end
|
data/spec/mongo/cursor_spec.rb
CHANGED
@@ -331,8 +331,9 @@ describe Mongo::Cursor do
|
|
331
331
|
|
332
332
|
before do
|
333
333
|
authorized_collection.insert_many(documents)
|
334
|
-
cluster.schedule_kill_cursor(
|
335
|
-
|
334
|
+
cluster.schedule_kill_cursor(
|
335
|
+
cursor.kill_spec(cursor.instance_variable_get(:@server))
|
336
|
+
)
|
336
337
|
end
|
337
338
|
|
338
339
|
let(:view) do
|
data/spec/runners/auth.rb
CHANGED
@@ -32,7 +32,7 @@ module Mongo
|
|
32
32
|
#
|
33
33
|
# @since 2.6.0
|
34
34
|
def initialize(test_path)
|
35
|
-
@spec =
|
35
|
+
@spec = ::Utils.load_spec_yaml_file(test_path)
|
36
36
|
@description = File.basename(test_path)
|
37
37
|
@spec_tests = @spec['tests']
|
38
38
|
@collection_name = @spec['collection_name']
|
data/spec/runners/cmap.rb
CHANGED
@@ -40,7 +40,7 @@ module Mongo
|
|
40
40
|
#
|
41
41
|
# @param [ String ] test_path The path to the file.
|
42
42
|
def initialize(test_path)
|
43
|
-
@test =
|
43
|
+
@test = ::Utils.load_spec_yaml_file(test_path)
|
44
44
|
|
45
45
|
@description = @test['description']
|
46
46
|
@pool_options = ::Utils.snakeize_hash(process_options(@test['poolOptions']))
|
data/spec/runners/crud/spec.rb
CHANGED
@@ -12,9 +12,7 @@ module Mongo
|
|
12
12
|
#
|
13
13
|
# @since 2.0.0
|
14
14
|
def initialize(test_path)
|
15
|
-
|
16
|
-
|
17
|
-
@spec = YAML.load(contents)
|
15
|
+
@spec = ::Utils.load_spec_yaml_file(test_path)
|
18
16
|
@description = File.basename(test_path)
|
19
17
|
@data = BSON::ExtJSON.parse_obj(@spec['data'])
|
20
18
|
@tests = @spec['tests']
|
data/spec/runners/gridfs.rb
CHANGED
data/spec/runners/sdam.rb
CHANGED
@@ -64,7 +64,7 @@ module Mongo
|
|
64
64
|
#
|
65
65
|
# @since 2.0.0
|
66
66
|
def initialize(test_path)
|
67
|
-
@test =
|
67
|
+
@test = ::Utils.load_spec_yaml_file(test_path)
|
68
68
|
@description = "#{@test['topology_description']['type']}: #{File.basename(test_path)}"
|
69
69
|
@heartbeat_frequency = @test['heartbeatFrequencyMS'] / 1000 if @test['heartbeatFrequencyMS']
|
70
70
|
@read_preference = @test['read_preference']
|
@@ -28,7 +28,7 @@ module Mongo
|
|
28
28
|
#
|
29
29
|
# @since 2.0.0
|
30
30
|
def initialize(test_path)
|
31
|
-
@test =
|
31
|
+
@test = ::Utils.load_spec_yaml_file(test_path)
|
32
32
|
@description = "#{File.basename(test_path)}: avg_rtt_ms: #{@test['avg_rtt_ms']}, new_rtt_ms: #{@test['new_rtt_ms']}," +
|
33
33
|
" new_avg_rtt: #{@test['new_avg_rtt']}"
|
34
34
|
@average_rtt = @test['avg_rtt_ms'] == 'NULL' ? nil : @test['avg_rtt_ms'].to_f / 1000
|
data/spec/support/utils.rb
CHANGED
@@ -595,4 +595,35 @@ module Utils
|
|
595
595
|
end
|
596
596
|
end
|
597
597
|
end
|
598
|
+
|
599
|
+
module_function def load_spec_yaml_file(path)
|
600
|
+
permitted_classes = [
|
601
|
+
BigDecimal,
|
602
|
+
Date,
|
603
|
+
Time,
|
604
|
+
Range,
|
605
|
+
Regexp,
|
606
|
+
Symbol,
|
607
|
+
BSON::Binary,
|
608
|
+
BSON::Code,
|
609
|
+
BSON::CodeWithScope,
|
610
|
+
BSON::DbPointer,
|
611
|
+
BSON::Decimal128,
|
612
|
+
BSON::Int32,
|
613
|
+
BSON::Int64,
|
614
|
+
BSON::MaxKey,
|
615
|
+
BSON::MinKey,
|
616
|
+
BSON::ObjectId,
|
617
|
+
BSON::Regexp::Raw,
|
618
|
+
BSON::Symbol::Raw,
|
619
|
+
BSON::Timestamp,
|
620
|
+
BSON::Undefined,
|
621
|
+
]
|
622
|
+
if RUBY_VERSION.start_with?("2.5")
|
623
|
+
YAML.safe_load(File.read(path), permitted_classes, [], true)
|
624
|
+
else
|
625
|
+
# Here we have Ruby 2.6+ that supports the new syntax of `safe_load``.
|
626
|
+
YAML.safe_load(File.read(path), permitted_classes: permitted_classes, aliases: true)
|
627
|
+
end
|
628
|
+
end
|
598
629
|
end
|
data.tar.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
�1�o5
|
2
|
+
q��7�������t��A!m�Ks�w�_��2�/���@C���T��E�rX6��*b�J���9�� �ʲRQʨ:�D_�6��'fz�6����ް
|
3
|
+
��jN:ɳ9Ͽ@��H4ga@�=�|��"� �W|�h��BH�\
|
4
|
+
���W���,jsgb ���c�HnT.�2 ]�f��T�`�"��I�&�@�^���9���1<5������|N�f����坋��
|