mongoid 7.3.4 → 7.3.5
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/mongoid/association/embedded/batchable.rb +20 -3
- data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
- data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- data/lib/mongoid/persistable/upsertable.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +7 -2
- data/spec/lite_spec_helper.rb +8 -1
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +21 -0
- data/spec/mongoid/association/embedded/embeds_many_models.rb +137 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +8 -0
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +24 -8
- data/spec/mongoid/criteria_spec.rb +32 -0
- data/spec/mongoid/query_cache_spec.rb +2 -2
- data/spec/mongoid/scopable_spec.rb +11 -0
- data/spec/shared/lib/mrss/cluster_config.rb +6 -1
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/share/Dockerfile.erb +3 -3
- data/spec/shared/shlib/server.sh +1 -1
- data/spec/support/models/audible_sound.rb +3 -0
- data.tar.gz.sig +0 -0
- metadata +581 -577
- metadata.gz.sig +2 -3
- data/spec/support/session_registry.rb +0 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efce0ba93d948e87b85aa1a6e1a0768ecb2bd17a052d5e34afb426c357391492
|
4
|
+
data.tar.gz: 39784e3b229e457971b79962c26e22f3f1e721c68d72268bdafafa821c245c80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f690e5ca59dfdf1e658ac922c5e8c0e0de1bef099f005205cab26b4e27922ce82b64dae38e803673b32e73f9327746562548c3f9667a4d3fd275483729e6ff3d
|
7
|
+
data.tar.gz: b87aef76b5145507b5e48f8516f4b27b99f401d7afb2fa56441d1d47540eac6f3f7bf198fadfd995e9fc08b0563727b6a5c4f7ce5014456e0dd4a6d345cdf3bb
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -82,7 +82,8 @@ module Mongoid
|
|
82
82
|
def batch_replace(docs)
|
83
83
|
if docs.blank?
|
84
84
|
if _assigning? && !empty?
|
85
|
-
_base.delayed_atomic_sets.
|
85
|
+
_base.delayed_atomic_sets.delete(path)
|
86
|
+
clear_atomic_path_cache
|
86
87
|
_base.add_atomic_unset(first)
|
87
88
|
target_duplicate = _target.dup
|
88
89
|
pre_process_batch_remove(target_duplicate, :delete)
|
@@ -94,7 +95,8 @@ module Mongoid
|
|
94
95
|
_base.delayed_atomic_sets.clear unless _assigning?
|
95
96
|
docs = normalize_docs(docs).compact
|
96
97
|
_target.clear and _unscoped.clear
|
97
|
-
_base.delayed_atomic_unsets.
|
98
|
+
_base.delayed_atomic_unsets.delete(path)
|
99
|
+
clear_atomic_path_cache
|
98
100
|
inserts = execute_batch_set(docs)
|
99
101
|
add_atomic_sets(inserts)
|
100
102
|
end
|
@@ -252,7 +254,22 @@ module Mongoid
|
|
252
254
|
#
|
253
255
|
# @since 3.0.0
|
254
256
|
def path
|
255
|
-
@path ||= _unscoped.
|
257
|
+
@path ||= if _unscoped.empty?
|
258
|
+
Mongoid::Atomic::Paths::Embedded::Many.position_without_document(_base, _association)
|
259
|
+
else
|
260
|
+
_unscoped.first.atomic_path
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
# Clear the cache for path and atomic_paths. This method is used when
|
265
|
+
# the path method is used, and the association has not been set on the
|
266
|
+
# document yet, which can cause path and atomic_paths to be calculated
|
267
|
+
# incorrectly later.
|
268
|
+
#
|
269
|
+
# @api private
|
270
|
+
def clear_atomic_path_cache
|
271
|
+
self.path = nil
|
272
|
+
_base.instance_variable_set("@atomic_paths", nil)
|
256
273
|
end
|
257
274
|
|
258
275
|
# Set the atomic path.
|
@@ -506,8 +506,8 @@ module Mongoid
|
|
506
506
|
selector = conditions || {}
|
507
507
|
removed = klass.send(method, selector.merge!(criteria.selector))
|
508
508
|
_target.delete_if do |doc|
|
509
|
-
|
510
|
-
unbind_one(doc)
|
509
|
+
doc._matches?(selector).tap do |b|
|
510
|
+
unbind_one(doc) if b
|
511
511
|
end
|
512
512
|
end
|
513
513
|
removed
|
@@ -39,6 +39,25 @@ module Mongoid
|
|
39
39
|
locator = document.new_record? ? "" : ".#{document._index}"
|
40
40
|
"#{pos}#{"." unless pos.blank?}#{document._association.store_as}#{locator}"
|
41
41
|
end
|
42
|
+
|
43
|
+
class << self
|
44
|
+
|
45
|
+
# Get the position of where the document would go for the given
|
46
|
+
# association. The use case for this function is when trying to
|
47
|
+
# persist an empty list for an embedded association. All of the
|
48
|
+
# existing functions for getting the position to store a document
|
49
|
+
# require passing in a document to store, which we don't have when
|
50
|
+
# trying to store the empty list.
|
51
|
+
#
|
52
|
+
# @param [ Document ] parent The parent document to store in.
|
53
|
+
# @param [ Association ] association The association.
|
54
|
+
#
|
55
|
+
# @return [ String ] The position string.
|
56
|
+
def position_without_document(parent, association)
|
57
|
+
pos = parent.atomic_position
|
58
|
+
"#{pos}#{"." unless pos.blank?}#{association.store_as}"
|
59
|
+
end
|
60
|
+
end
|
42
61
|
end
|
43
62
|
end
|
44
63
|
end
|
data/lib/mongoid/version.rb
CHANGED
@@ -80,8 +80,13 @@ development:
|
|
80
80
|
# (default: 10)
|
81
81
|
# connect_timeout: 10
|
82
82
|
|
83
|
-
#
|
84
|
-
#
|
83
|
+
# How long to wait for a response for each operation sent to the
|
84
|
+
# server. This timeout should be set to a value larger than the
|
85
|
+
# processing time for the longest operation that will be executed
|
86
|
+
# by the application. Note that this is a client-side timeout;
|
87
|
+
# the server may continue executing an operation after the client
|
88
|
+
# aborts it with the SocketTimeout exception.
|
89
|
+
# (default: nil, meaning no timeout)
|
85
90
|
# socket_timeout: 5
|
86
91
|
|
87
92
|
# The name of the replica set to connect to. Servers provided as seeds that do
|
data/spec/lite_spec_helper.rb
CHANGED
@@ -19,7 +19,14 @@ autoload :Timecop, 'timecop'
|
|
19
19
|
|
20
20
|
require 'support/spec_config'
|
21
21
|
require 'mrss/lite_constraints'
|
22
|
-
|
22
|
+
|
23
|
+
if Gem::Version.new(Mongo::VERSION) < Gem::Version.new('2.18.0.alpha')
|
24
|
+
require "mrss/session_registry_legacy"
|
25
|
+
else
|
26
|
+
require "mrss/session_registry"
|
27
|
+
end
|
28
|
+
|
29
|
+
Mrss.patch_mongo_for_session_registry
|
23
30
|
|
24
31
|
unless SpecConfig.instance.ci?
|
25
32
|
begin
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# encoding: utf-8
|
3
3
|
|
4
4
|
require "spec_helper"
|
5
|
+
require_relative '../embeds_many_models.rb'
|
5
6
|
|
6
7
|
describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
7
8
|
|
@@ -4400,4 +4401,24 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
|
4400
4401
|
end
|
4401
4402
|
end
|
4402
4403
|
end
|
4404
|
+
|
4405
|
+
context "when using assign_attributes with an already populated array" do
|
4406
|
+
let(:post) { EmmPost.create! }
|
4407
|
+
|
4408
|
+
before do
|
4409
|
+
post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'a'}],
|
4410
|
+
user_tags: [{id: BSON::ObjectId.new, title: 'b'}])
|
4411
|
+
post.save!
|
4412
|
+
post.reload
|
4413
|
+
post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'c'}],
|
4414
|
+
user_tags: [])
|
4415
|
+
post.save!
|
4416
|
+
post.reload
|
4417
|
+
end
|
4418
|
+
|
4419
|
+
it "has the correct embedded documents" do
|
4420
|
+
expect(post.company_tags.length).to eq(1)
|
4421
|
+
expect(post.company_tags.first.title).to eq("c")
|
4422
|
+
end
|
4423
|
+
end
|
4403
4424
|
end
|
@@ -52,3 +52,140 @@ class EmmProduct
|
|
52
52
|
|
53
53
|
field :name, type: String
|
54
54
|
end
|
55
|
+
|
56
|
+
class EmmInner
|
57
|
+
include Mongoid::Document
|
58
|
+
|
59
|
+
embeds_many :friends, :class_name => self.name, :cyclic => true
|
60
|
+
embedded_in :parent, :class_name => self.name, :cyclic => true
|
61
|
+
|
62
|
+
field :level, :type => Integer
|
63
|
+
end
|
64
|
+
|
65
|
+
class EmmOuter
|
66
|
+
include Mongoid::Document
|
67
|
+
embeds_many :inners, class_name: 'EmmInner'
|
68
|
+
|
69
|
+
field :level, :type => Integer
|
70
|
+
end
|
71
|
+
|
72
|
+
class EmmCustomerAddress
|
73
|
+
include Mongoid::Document
|
74
|
+
|
75
|
+
embedded_in :addressable, polymorphic: true, inverse_of: :work_address
|
76
|
+
end
|
77
|
+
|
78
|
+
class EmmFriend
|
79
|
+
include Mongoid::Document
|
80
|
+
|
81
|
+
embedded_in :befriendable, polymorphic: true
|
82
|
+
end
|
83
|
+
|
84
|
+
class EmmCustomer
|
85
|
+
include Mongoid::Document
|
86
|
+
|
87
|
+
embeds_one :home_address, class_name: 'EmmCustomerAddress', as: :addressable
|
88
|
+
embeds_one :work_address, class_name: 'EmmCustomerAddress', as: :addressable
|
89
|
+
|
90
|
+
embeds_many :close_friends, class_name: 'EmmFriend', as: :befriendable
|
91
|
+
embeds_many :acquaintances, class_name: 'EmmFriend', as: :befriendable
|
92
|
+
end
|
93
|
+
|
94
|
+
class EmmUser
|
95
|
+
include Mongoid::Document
|
96
|
+
include Mongoid::Timestamps
|
97
|
+
|
98
|
+
embeds_many :orders, class_name: 'EmmOrder'
|
99
|
+
end
|
100
|
+
|
101
|
+
class EmmOrder
|
102
|
+
include Mongoid::Document
|
103
|
+
|
104
|
+
field :amount, type: Integer
|
105
|
+
|
106
|
+
embedded_in :user, class_name: 'EmmUser'
|
107
|
+
end
|
108
|
+
|
109
|
+
module EmmSpec
|
110
|
+
# There is also a top-level Car class defined.
|
111
|
+
class Car
|
112
|
+
include Mongoid::Document
|
113
|
+
|
114
|
+
embeds_many :doors
|
115
|
+
end
|
116
|
+
|
117
|
+
class Door
|
118
|
+
include Mongoid::Document
|
119
|
+
|
120
|
+
embedded_in :car
|
121
|
+
end
|
122
|
+
|
123
|
+
class Tank
|
124
|
+
include Mongoid::Document
|
125
|
+
|
126
|
+
embeds_many :guns
|
127
|
+
embeds_many :emm_turrets
|
128
|
+
# This association references a model that is not in our module,
|
129
|
+
# and it does not define class_name hence Mongoid will not be able to
|
130
|
+
# figure out the inverse for this association.
|
131
|
+
embeds_many :emm_hatches
|
132
|
+
|
133
|
+
# class_name is intentionally unqualified, references a class in the
|
134
|
+
# same module. Rails permits class_name to be unqualified like this.
|
135
|
+
embeds_many :launchers, class_name: 'Launcher'
|
136
|
+
end
|
137
|
+
|
138
|
+
class Gun
|
139
|
+
include Mongoid::Document
|
140
|
+
|
141
|
+
embedded_in :tank
|
142
|
+
end
|
143
|
+
|
144
|
+
class Launcher
|
145
|
+
include Mongoid::Document
|
146
|
+
|
147
|
+
# class_name is intentionally unqualified.
|
148
|
+
embedded_in :tank, class_name: 'Tank'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# This is intentionally on top level.
|
153
|
+
class EmmTurret
|
154
|
+
include Mongoid::Document
|
155
|
+
|
156
|
+
embedded_in :tank, class_name: 'EmmSpec::Tank'
|
157
|
+
end
|
158
|
+
|
159
|
+
# This is intentionally on top level.
|
160
|
+
class EmmHatch
|
161
|
+
include Mongoid::Document
|
162
|
+
|
163
|
+
# No :class_name option on this association intentionally.
|
164
|
+
embedded_in :tank
|
165
|
+
end
|
166
|
+
|
167
|
+
class EmmPost
|
168
|
+
include Mongoid::Document
|
169
|
+
|
170
|
+
embeds_many :company_tags, class_name: "EmmCompanyTag"
|
171
|
+
embeds_many :user_tags, class_name: "EmmUserTag"
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
class EmmCompanyTag
|
176
|
+
include Mongoid::Document
|
177
|
+
|
178
|
+
field :title, type: String
|
179
|
+
|
180
|
+
embedded_in :post, class_name: "EmmPost"
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
class EmmUserTag
|
185
|
+
include Mongoid::Document
|
186
|
+
|
187
|
+
field :title, type: String
|
188
|
+
|
189
|
+
embedded_in :post, class_name: "EmmPost"
|
190
|
+
end
|
191
|
+
|
@@ -2395,6 +2395,10 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
2395
2395
|
it "removes the ids from the foreign key" do
|
2396
2396
|
expect(person.preference_ids).to eq([ preference_two.id ])
|
2397
2397
|
end
|
2398
|
+
|
2399
|
+
it "sets the association locally" do
|
2400
|
+
expect(person.preferences).to eq([preference_two])
|
2401
|
+
end
|
2398
2402
|
end
|
2399
2403
|
|
2400
2404
|
context "when conditions are not provided" do
|
@@ -2421,6 +2425,10 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
2421
2425
|
it "returns the number of documents deleted" do
|
2422
2426
|
expect(deleted).to eq(2)
|
2423
2427
|
end
|
2428
|
+
|
2429
|
+
it "sets the association locally" do
|
2430
|
+
expect(person.preferences).to eq([])
|
2431
|
+
end
|
2424
2432
|
end
|
2425
2433
|
end
|
2426
2434
|
end
|
@@ -2214,10 +2214,8 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2214
2214
|
Person.create(username: 'durran')
|
2215
2215
|
end
|
2216
2216
|
|
2217
|
-
|
2218
|
-
|
2219
|
-
person.posts.create(title: "Test")
|
2220
|
-
end
|
2217
|
+
let!(:post1) { person.posts.create!(title: "Testing") }
|
2218
|
+
let!(:post2) { person.posts.create!(title: "Test") }
|
2221
2219
|
|
2222
2220
|
it "removes the correct posts" do
|
2223
2221
|
person.posts.send(method, { title: "Testing" })
|
@@ -2233,6 +2231,11 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2233
2231
|
it "returns the number of documents deleted" do
|
2234
2232
|
expect(person.posts.send(method, { title: "Testing" })).to eq(1)
|
2235
2233
|
end
|
2234
|
+
|
2235
|
+
it "sets the association locally" do
|
2236
|
+
person.posts.send(method, { title: "Testing" })
|
2237
|
+
expect(person.posts).to eq([post2])
|
2238
|
+
end
|
2236
2239
|
end
|
2237
2240
|
|
2238
2241
|
context "when conditions are not provided" do
|
@@ -2259,6 +2262,11 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2259
2262
|
it "returns the number of documents deleted" do
|
2260
2263
|
expect(person.posts.send(method)).to eq(2)
|
2261
2264
|
end
|
2265
|
+
|
2266
|
+
it "sets the association locally" do
|
2267
|
+
person.posts.send(method)
|
2268
|
+
expect(person.posts).to eq([])
|
2269
|
+
end
|
2262
2270
|
end
|
2263
2271
|
end
|
2264
2272
|
|
@@ -2270,10 +2278,8 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2270
2278
|
Movie.create(title: "Bladerunner")
|
2271
2279
|
end
|
2272
2280
|
|
2273
|
-
|
2274
|
-
|
2275
|
-
movie.ratings.create(value: 2)
|
2276
|
-
end
|
2281
|
+
let!(:rating1) { movie.ratings.create!(value: 1) }
|
2282
|
+
let!(:rating2) { movie.ratings.create!(value: 2) }
|
2277
2283
|
|
2278
2284
|
it "removes the correct ratings" do
|
2279
2285
|
movie.ratings.send(method, { value: 1 })
|
@@ -2288,6 +2294,11 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2288
2294
|
it "returns the number of documents deleted" do
|
2289
2295
|
expect(movie.ratings.send(method, { value: 1 })).to eq(1)
|
2290
2296
|
end
|
2297
|
+
|
2298
|
+
it "sets the association locally" do
|
2299
|
+
movie.ratings.send(method, { value: 1 })
|
2300
|
+
expect(movie.ratings).to eq([rating2])
|
2301
|
+
end
|
2291
2302
|
end
|
2292
2303
|
|
2293
2304
|
context "when conditions are not provided" do
|
@@ -2314,6 +2325,11 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2314
2325
|
it "returns the number of documents deleted" do
|
2315
2326
|
expect(movie.ratings.send(method)).to eq(2)
|
2316
2327
|
end
|
2328
|
+
|
2329
|
+
it "sets the association locally" do
|
2330
|
+
movie.ratings.send(method)
|
2331
|
+
expect(movie.ratings).to eq([])
|
2332
|
+
end
|
2317
2333
|
end
|
2318
2334
|
end
|
2319
2335
|
end
|
@@ -3490,6 +3490,38 @@ describe Mongoid::Criteria do
|
|
3490
3490
|
'foo' => 1, '$and' => [{'foo' => 2}], 'bar' => 3)
|
3491
3491
|
end
|
3492
3492
|
end
|
3493
|
+
|
3494
|
+
context "when duplicating where conditions" do
|
3495
|
+
let(:criteria) { Sound.where(active: true).where(active: true) }
|
3496
|
+
|
3497
|
+
it 'does not duplicate criteria' do
|
3498
|
+
expect(criteria.selector).to eq('active' => true)
|
3499
|
+
end
|
3500
|
+
end
|
3501
|
+
|
3502
|
+
context "when duplicating where conditions with different values" do
|
3503
|
+
let(:criteria) { Sound.where(active: true).where(active: false).where(active: true).where(active: false) }
|
3504
|
+
|
3505
|
+
it 'does not duplicate criteria' do
|
3506
|
+
expect(criteria.selector).to eq(
|
3507
|
+
'active' => true, '$and' => [{'active' => false}])
|
3508
|
+
end
|
3509
|
+
end
|
3510
|
+
|
3511
|
+
# Used to test MONGOID-5251 where the find command was adding unnecessary
|
3512
|
+
# and clauses. Since the find command creates the criteria and executes it,
|
3513
|
+
# it is difficult to analyze the criteria used. For this reason, I have
|
3514
|
+
# extracted the crux of the issue, adding an _id to the the criteria twice,
|
3515
|
+
# and used that for the test case.
|
3516
|
+
context "when searching by _id twice" do
|
3517
|
+
let(:_id) { BSON::ObjectId.new }
|
3518
|
+
let(:criteria) { Band.where(_id: _id) }
|
3519
|
+
let(:dup_criteria) { criteria.where(_id: _id)}
|
3520
|
+
|
3521
|
+
it "does not duplicate the criteria" do
|
3522
|
+
expect(dup_criteria.selector).to eq({ "_id" => _id })
|
3523
|
+
end
|
3524
|
+
end
|
3493
3525
|
end
|
3494
3526
|
|
3495
3527
|
describe "#for_js" do
|
@@ -17,11 +17,11 @@ describe Mongoid::QueryCache do
|
|
17
17
|
# occur only within the scope of these tests.
|
18
18
|
#
|
19
19
|
# Other session leaks will be detected and addressed as part of RUBY-2391.
|
20
|
-
SessionRegistry.instance.clear_registry
|
20
|
+
Mrss::SessionRegistry.instance.clear_registry
|
21
21
|
end
|
22
22
|
|
23
23
|
after do
|
24
|
-
SessionRegistry.instance.verify_sessions_ended!
|
24
|
+
Mrss::SessionRegistry.instance.verify_sessions_ended!
|
25
25
|
end
|
26
26
|
|
27
27
|
let(:reset_legacy_qc_warning) do
|
@@ -111,6 +111,17 @@ describe Mongoid::Scopable do
|
|
111
111
|
expect(Band).to be_default_scoping
|
112
112
|
end
|
113
113
|
end
|
114
|
+
|
115
|
+
context "when parent class has default scope" do
|
116
|
+
|
117
|
+
let (:selector) do
|
118
|
+
AudibleSound.all.selector
|
119
|
+
end
|
120
|
+
|
121
|
+
it "the subclass doesn't duplicate the default scope in the selector" do
|
122
|
+
expect(selector).to eq({'active' => true})
|
123
|
+
end
|
124
|
+
end
|
114
125
|
end
|
115
126
|
|
116
127
|
describe ".default_scopable?" do
|
@@ -209,7 +209,12 @@ module Mrss
|
|
209
209
|
@server_version = build_info['version']
|
210
210
|
@enterprise = build_info['modules'] && build_info['modules'].include?('enterprise')
|
211
211
|
|
212
|
-
@server_parameters =
|
212
|
+
@server_parameters = begin
|
213
|
+
client.use(:admin).command(getParameter: '*').first
|
214
|
+
rescue => e
|
215
|
+
STDERR.puts("WARNING: Failed to obtain server parameters: #{e.class}: #{e.message}")
|
216
|
+
{}
|
217
|
+
end
|
213
218
|
|
214
219
|
if !sharded_ish? && short_server_version >= '3.4'
|
215
220
|
rv = @server_parameters['featureCompatibilityVersion']
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
module Mrss
|
7
|
+
|
8
|
+
def self.patch_mongo_for_session_registry
|
9
|
+
|
10
|
+
Mongo::Client.class_eval do
|
11
|
+
alias :get_session_without_tracking :get_session
|
12
|
+
|
13
|
+
def get_session(options = {})
|
14
|
+
get_session_without_tracking(options).tap do |session|
|
15
|
+
SessionRegistry.instance.register(session) if session&.materialized?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Mongo::Session.class_eval do
|
21
|
+
alias :end_session_without_tracking :end_session
|
22
|
+
|
23
|
+
def end_session
|
24
|
+
SessionRegistry.instance.unregister(self)
|
25
|
+
end_session_without_tracking
|
26
|
+
end
|
27
|
+
|
28
|
+
alias :materialize_if_needed_without_tracking :materialize_if_needed
|
29
|
+
|
30
|
+
def materialize_if_needed
|
31
|
+
materialize_if_needed_without_tracking.tap do
|
32
|
+
SessionRegistry.instance.register(self)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module Mrss
|
40
|
+
class SessionRegistry
|
41
|
+
include Singleton
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
@registry = {}
|
45
|
+
end
|
46
|
+
|
47
|
+
def register(session)
|
48
|
+
@registry[session.session_id] = session if session
|
49
|
+
end
|
50
|
+
|
51
|
+
def unregister(session)
|
52
|
+
return if session.ended? || !session.materialized?
|
53
|
+
@registry.delete(session.session_id)
|
54
|
+
end
|
55
|
+
|
56
|
+
def verify_sessions_ended!
|
57
|
+
@registry.delete_if { |_, session| session.ended? }
|
58
|
+
|
59
|
+
unless @registry.empty?
|
60
|
+
sessions = @registry.map { |_, session| session }
|
61
|
+
raise "Session registry contains live sessions: #{sessions.join(', ')}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def clear_registry
|
66
|
+
@registry = {}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
module Mrss
|
7
|
+
|
8
|
+
def self.patch_mongo_for_session_registry
|
9
|
+
|
10
|
+
Mongo::Client.class_eval do
|
11
|
+
alias :get_session_without_tracking :get_session
|
12
|
+
|
13
|
+
def get_session(options = {})
|
14
|
+
get_session_without_tracking(options).tap do |session|
|
15
|
+
SessionRegistry.instance.register(session)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Mongo::Session.class_eval do
|
21
|
+
alias :end_session_without_tracking :end_session
|
22
|
+
|
23
|
+
def end_session
|
24
|
+
SessionRegistry.instance.unregister(self)
|
25
|
+
end_session_without_tracking
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module Mrss
|
32
|
+
class SessionRegistry
|
33
|
+
include Singleton
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@registry = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
def register(session)
|
40
|
+
@registry[session.session_id] = session if session
|
41
|
+
end
|
42
|
+
|
43
|
+
def unregister(session)
|
44
|
+
@registry.delete(session.session_id) unless session.ended?
|
45
|
+
end
|
46
|
+
|
47
|
+
def verify_sessions_ended!
|
48
|
+
@registry.delete_if { |_, session| session.ended? }
|
49
|
+
|
50
|
+
unless @registry.empty?
|
51
|
+
sessions = @registry.map { |_, session| session }
|
52
|
+
raise "Session registry contains live sessions: #{sessions.join(', ')}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def clear_registry
|
57
|
+
@registry = {}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -233,13 +233,13 @@ CFG
|
|
233
233
|
# Current virtualenv fails with
|
234
234
|
# https://github.com/pypa/virtualenv/issues/1630
|
235
235
|
<% if distro =~ /ubuntu2004/ %>
|
236
|
-
RUN python3 -m pip install 'virtualenv<20' 'mtools-legacy[mlaunch]'
|
236
|
+
RUN python3 -m pip install 'virtualenv<20' 'mtools-legacy[mlaunch]==1.5.5'
|
237
237
|
<% else %>
|
238
|
-
RUN python2 -m pip install 'virtualenv<20' 'mtools-legacy[mlaunch]'
|
238
|
+
RUN python2 -m pip install 'virtualenv<20' 'mtools-legacy[mlaunch]==1.5.5'
|
239
239
|
<% end %>
|
240
240
|
|
241
241
|
RUN pip --version && \
|
242
|
-
pip install mtools-legacy[mlaunch]
|
242
|
+
pip install 'mtools-legacy[mlaunch]==1.5.5'
|
243
243
|
|
244
244
|
<% if @env.fetch('MONGODB_VERSION') >= '4.4' %>
|
245
245
|
# ubuntu1604 installs MarkupSafe 0.0.0 here instead of 2.0.0+
|
data/spec/shared/shlib/server.sh
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|