mongo 2.17.0 → 2.17.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7fed7eef29657f665e0b2cbecaab0e60626e76aad58087ff5fd8d051d237002
4
- data.tar.gz: 77e80dd97d3d60c6836b563233f23d1f505344905d87ff8afedbe31fa45b216a
3
+ metadata.gz: 1a38f748fe8350d12ecfd23a30e794b65addcfbf8f5303504f5f85999e2c2b0d
4
+ data.tar.gz: 876f431a9bfc558ecad0006a32b6ed90b6a94d05ac553a52fbc8b5d3b2b80a55
5
5
  SHA512:
6
- metadata.gz: 4a898c56e637b3c0597126cc207d9c70ae9f0b3533294fab7ba92f8882be72a5df44ead386e055433966b40ad7f34ef3d0a5a82ae1c9b3088d4fb2d428673ee8
7
- data.tar.gz: abec048d264aee514a33c660f0ac151f169f6b764d7e85c91f626a1ecb30e2b27c9ddcf3aa404c0f3e3cc27eb8f00dfe0e223a69096755556cb4942c5be9ce3f
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, server)
59
- @mutex.synchronize do
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
- server_address_str = nil
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
- server_address_str, specs =
132
- @to_kill.detect { |server_address_str, specs| specs.any? }
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.seed == server_address_str
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
- # so remove it here and hopefully it's handled elsewhere.
121
- # If not, RUBY-2706.
122
- command.delete(:read)
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
- Operation::MapReduce.new(map_reduce_spec(session))
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, server, session)
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, server)
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
@@ -20,5 +20,5 @@ module Mongo
20
20
  # The current version of the driver.
21
21
  #
22
22
  # @since 2.0.0
23
- VERSION = '2.17.0'.freeze
23
+ VERSION = '2.17.1'.freeze
24
24
  end
@@ -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, server)
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.seed ])
68
- expect(to_kill[address.seed]).to eq(Set.new([cursor_kill_spec_1]))
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, server)
76
- reaper.schedule_kill_cursor(cursor_kill_spec_2, server)
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.seed ])
81
- expect(to_kill[address.seed]).to contain_exactly(cursor_kill_spec_1, cursor_kill_spec_2)
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, server)
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.seed ])
92
- expect(to_kill[address.seed]).to contain_exactly(cursor_kill_spec_1, cursor_kill_spec_2)
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, server)
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(cursor.kill_spec,
193
- cursor.instance_variable_get(:@server))
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
@@ -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(cursor.kill_spec,
335
- cursor.instance_variable_get(:@server))
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
@@ -48,7 +48,7 @@ module Mongo
48
48
  attr_reader :tests
49
49
 
50
50
  def initialize(test_path)
51
- @spec = YAML.load(File.read(test_path))
51
+ @spec = ::Utils.load_spec_yaml_file(test_path)
52
52
  @description = File.basename(test_path)
53
53
  end
54
54
 
@@ -32,7 +32,7 @@ module Mongo
32
32
  #
33
33
  # @since 2.6.0
34
34
  def initialize(test_path)
35
- @spec = YAML.load(File.read(test_path))
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 = YAML.load(File.read(test_path))
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']))
@@ -204,7 +204,7 @@ module Mongo
204
204
  #
205
205
  # @since 2.1.0
206
206
  def initialize(test_path)
207
- @spec = YAML.load(File.read(test_path))
207
+ @spec = ::Utils.load_spec_yaml_file(test_path)
208
208
  @data = @spec['data']
209
209
  @tests = @spec['tests']
210
210
  end
@@ -100,7 +100,7 @@ module Mongo
100
100
  #
101
101
  # @since 2.0.0
102
102
  def initialize(test_path)
103
- @spec = YAML.load(File.read(test_path))
103
+ @spec = ::Utils.load_spec_yaml_file(test_path)
104
104
  @description = File.basename(test_path)
105
105
  end
106
106
 
@@ -12,9 +12,7 @@ module Mongo
12
12
  #
13
13
  # @since 2.0.0
14
14
  def initialize(test_path)
15
- contents = File.read(test_path)
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']
@@ -100,7 +100,7 @@ module Mongo
100
100
  #
101
101
  # @since 2.1.0
102
102
  def initialize(test_path)
103
- @spec = YAML.load(File.read(test_path))
103
+ @spec = ::Utils.load_spec_yaml_file(test_path)
104
104
  @description = File.basename(test_path)
105
105
  @data = @spec['data']
106
106
  end
@@ -13,7 +13,7 @@ module ReadWriteConcernDocument
13
13
  #
14
14
  # @since 2.0.0
15
15
  def initialize(test_path)
16
- @spec = YAML.load(File.read(test_path))
16
+ @spec = ::Utils.load_spec_yaml_file(test_path)
17
17
  @description = File.basename(test_path)
18
18
  end
19
19
 
data/spec/runners/sdam.rb CHANGED
@@ -77,7 +77,7 @@ module Mongo
77
77
  #
78
78
  # @since 2.0.0
79
79
  def initialize(test_path)
80
- @test = YAML.load(File.read(test_path))
80
+ @test = ::Utils.load_spec_yaml_file(test_path)
81
81
  @description = @test['description']
82
82
  @uri_string = @test['uri']
83
83
  @uri = URI.new(uri_string)
@@ -64,7 +64,7 @@ module Mongo
64
64
  #
65
65
  # @since 2.0.0
66
66
  def initialize(test_path)
67
- @test = YAML.load(File.read(test_path))
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 = YAML.load(File.read(test_path))
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
@@ -6,7 +6,7 @@ module Unified
6
6
  class TestGroup
7
7
  def initialize(path, **opts)
8
8
  if String === path
9
- data = YAML.load(File.read(path))
9
+ data = ::Utils.load_spec_yaml_file(path)
10
10
  else
11
11
  data = path
12
12
  end
@@ -15,7 +15,7 @@ describe 'DNS Seedlist Discovery' do
15
15
 
16
16
  SEED_LIST_DISCOVERY_TESTS.each do |test_path|
17
17
 
18
- spec = YAML.load(File.read(test_path))
18
+ spec = ::Utils.load_spec_yaml_file(test_path)
19
19
 
20
20
  test = Mongo::ConnectionString::Test.new(spec)
21
21
 
@@ -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
- R��NE��u3��o�|�M���:ٻ�5C��KI��9n��LF��k���xѻ���� �Jd�m�R̺vG�g�V�>��������3h�����1��S�`���d��AlA��E�K+{��UX��6\�tۚ˅L ]ʘ��%�&�6u�б��������L��V���rU��d��V]�$R��19�Y�7v��o��FI��m
2
- YkuШ���;��^���h�ǐ멾���n�=�/
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����坋��