mongo 2.24.0 → 2.24.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
- data/lib/mongo/bulk_write/result.rb +10 -2
- data/lib/mongo/bulk_write/result_combiner.rb +8 -1
- data/lib/mongo/config.rb +5 -0
- data/lib/mongo/error/bulk_write_error.rb +29 -1
- data/lib/mongo/error/invalid_server_preference.rb +3 -0
- data/lib/mongo/error/operation_failure.rb +40 -1
- data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +2 -0
- data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +3 -0
- data/lib/mongo/operation/result.rb +2 -1
- data/lib/mongo/operation/shared/executable.rb +1 -1
- data/lib/mongo/server/connection_pool.rb +55 -8
- data/lib/mongo/server/description/features.rb +1 -1
- data/lib/mongo/server/description.rb +23 -1
- data/lib/mongo/server_selector/base.rb +13 -0
- data/lib/mongo/server_selector/nearest.rb +3 -0
- data/lib/mongo/server_selector/primary.rb +3 -0
- data/lib/mongo/server_selector/primary_preferred.rb +3 -0
- data/lib/mongo/server_selector/secondary.rb +3 -0
- data/lib/mongo/server_selector/secondary_preferred.rb +3 -0
- data/lib/mongo/session.rb +34 -1
- data/lib/mongo/tracing/open_telemetry/command_tracer.rb +27 -0
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9359ddba0c1cd025a706f5970893bbdce249c2ab5fbe9d4ce3293a308bb11ade
|
|
4
|
+
data.tar.gz: f88046bc63c0a6b2d23017a3df2ba2cfe72bf6cd7d9565c985e64084bc41147d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1ea813993a5e069434299e68eacfb1c79bcbb0161728d703dd20e3047f2699a11640c94067e22c1089e34b56398afb959843eb3d914f110878056c646402c7e8
|
|
7
|
+
data.tar.gz: 837e4866998fc01f8523768fbee6f062a3d0564932f318c27d701e826ed123a4c329df0d74449455afa1146e2de42d7fe54941aaf25e9e9061fc83dd82d87d06
|
|
@@ -25,6 +25,10 @@ module Mongo
|
|
|
25
25
|
@acknowledged
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
# @return [ Array<String> ] Deduplicated list of "host:port" addresses of
|
|
29
|
+
# the servers that produced this bulk write's operations.
|
|
30
|
+
attr_reader :server_addresses
|
|
31
|
+
|
|
28
32
|
# Constant for number removed.
|
|
29
33
|
#
|
|
30
34
|
# @since 2.1.0
|
|
@@ -97,13 +101,17 @@ module Mongo
|
|
|
97
101
|
#
|
|
98
102
|
# @param [ BSON::Document, Hash ] results The results document.
|
|
99
103
|
# @param [ Boolean ] acknowledged Is the result acknowledged?
|
|
104
|
+
# @param [ Array<String> ] server_addresses Deduplicated "host:port"
|
|
105
|
+
# addresses of the servers that produced the underlying operation
|
|
106
|
+
# results.
|
|
100
107
|
#
|
|
101
108
|
# @since 2.1.0
|
|
102
109
|
#
|
|
103
110
|
# @api private
|
|
104
|
-
def initialize(results, acknowledged)
|
|
111
|
+
def initialize(results, acknowledged, server_addresses = [])
|
|
105
112
|
@results = results
|
|
106
113
|
@acknowledged = acknowledged
|
|
114
|
+
@server_addresses = Array(server_addresses).compact.uniq
|
|
107
115
|
end
|
|
108
116
|
|
|
109
117
|
# Returns the number of documents inserted.
|
|
@@ -189,7 +197,7 @@ module Mongo
|
|
|
189
197
|
#
|
|
190
198
|
# @since 2.1.0
|
|
191
199
|
def validate!
|
|
192
|
-
raise Error::BulkWriteError.new(@results) if @results['writeErrors'] || @results['writeConcernErrors']
|
|
200
|
+
raise Error::BulkWriteError.new(@results, server_addresses: @server_addresses) if @results['writeErrors'] || @results['writeConcernErrors']
|
|
193
201
|
|
|
194
202
|
self
|
|
195
203
|
end
|
|
@@ -28,6 +28,10 @@ module Mongo
|
|
|
28
28
|
# @return [ Hash ] results The results hash.
|
|
29
29
|
attr_reader :results
|
|
30
30
|
|
|
31
|
+
# @return [ Array<String> ] Deduplicated list of "host:port" addresses of
|
|
32
|
+
# the servers that produced the combined operation results.
|
|
33
|
+
attr_reader :server_addresses
|
|
34
|
+
|
|
31
35
|
# Create the new result combiner.
|
|
32
36
|
#
|
|
33
37
|
# @api private
|
|
@@ -39,6 +43,7 @@ module Mongo
|
|
|
39
43
|
def initialize
|
|
40
44
|
@results = {}
|
|
41
45
|
@count = 0
|
|
46
|
+
@server_addresses = []
|
|
42
47
|
end
|
|
43
48
|
|
|
44
49
|
# Adds a result to the overall results.
|
|
@@ -68,6 +73,8 @@ module Mongo
|
|
|
68
73
|
combine_errors!(result)
|
|
69
74
|
@count += count
|
|
70
75
|
@acknowledged = result.acknowledged?
|
|
76
|
+
seed = result.connection_description&.address&.seed
|
|
77
|
+
@server_addresses << seed if seed && !@server_addresses.include?(seed)
|
|
71
78
|
end
|
|
72
79
|
|
|
73
80
|
# Get the final result.
|
|
@@ -78,7 +85,7 @@ module Mongo
|
|
|
78
85
|
#
|
|
79
86
|
# @since 2.1.0
|
|
80
87
|
def result
|
|
81
|
-
BulkWrite::Result.new(results, @acknowledged).validate!
|
|
88
|
+
BulkWrite::Result.new(results, @acknowledged, @server_addresses).validate!
|
|
82
89
|
end
|
|
83
90
|
|
|
84
91
|
private
|
data/lib/mongo/config.rb
CHANGED
|
@@ -29,6 +29,11 @@ module Mongo
|
|
|
29
29
|
# decryption instead of BSON types.
|
|
30
30
|
option :csfle_convert_to_ruby_types, default: false
|
|
31
31
|
|
|
32
|
+
# When this flag is set to true, the (host:port) of the server that produced
|
|
33
|
+
# the error is appended to error messages for OperationFailure and
|
|
34
|
+
# BulkWriteError. See RUBY-3602.
|
|
35
|
+
option :include_server_address_in_errors, default: false
|
|
36
|
+
|
|
32
37
|
# Set the configuration options.
|
|
33
38
|
#
|
|
34
39
|
# @example Set the options.
|
|
@@ -34,6 +34,11 @@ module Mongo
|
|
|
34
34
|
# @return [ BSON::Document ] result The error result.
|
|
35
35
|
attr_reader :result
|
|
36
36
|
|
|
37
|
+
# @return [ Array<String> ] Deduplicated list of "host:port" addresses of
|
|
38
|
+
# the servers that produced this bulk write error. Empty when no
|
|
39
|
+
# addresses were supplied.
|
|
40
|
+
attr_reader :server_addresses
|
|
41
|
+
|
|
37
42
|
# Instantiate the new exception.
|
|
38
43
|
#
|
|
39
44
|
# @example Instantiate the exception.
|
|
@@ -41,10 +46,14 @@ module Mongo
|
|
|
41
46
|
#
|
|
42
47
|
# @param [ Hash ] result A processed response from the server
|
|
43
48
|
# reporting results of the operation.
|
|
49
|
+
# @param [ Array<String | Mongo::Address | Mongo::Server::Description> ]
|
|
50
|
+
# server_addresses Addresses of the servers that produced this error.
|
|
51
|
+
# Entries are normalized to "host:port" strings.
|
|
44
52
|
#
|
|
45
53
|
# @since 2.0.0
|
|
46
|
-
def initialize(result)
|
|
54
|
+
def initialize(result, server_addresses: nil)
|
|
47
55
|
@result = result
|
|
56
|
+
@server_addresses = normalize_server_addresses(server_addresses)
|
|
48
57
|
|
|
49
58
|
# Exception constructor behaves differently for a nil argument and
|
|
50
59
|
# for no argument. Avoid passing nil explicitly.
|
|
@@ -93,8 +102,27 @@ module Mongo
|
|
|
93
102
|
|
|
94
103
|
fragment = "Multiple errors: #{fragment}" if errors.length > 1
|
|
95
104
|
|
|
105
|
+
if Mongo.include_server_address_in_errors && @server_addresses.any?
|
|
106
|
+
fragment = "#{fragment} (on #{@server_addresses.join(', ')})"
|
|
107
|
+
end
|
|
108
|
+
|
|
96
109
|
fragment
|
|
97
110
|
end
|
|
111
|
+
|
|
112
|
+
def normalize_server_addresses(value)
|
|
113
|
+
return [] if value.nil?
|
|
114
|
+
|
|
115
|
+
Array(value).filter_map do |entry|
|
|
116
|
+
case entry
|
|
117
|
+
when String then entry
|
|
118
|
+
when Mongo::Address then entry.seed
|
|
119
|
+
when Mongo::Server::Description then entry.address&.seed
|
|
120
|
+
else
|
|
121
|
+
raise ArgumentError,
|
|
122
|
+
"server_addresses entries must be String, Mongo::Address, or Mongo::Server::Description; got #{entry.class}"
|
|
123
|
+
end
|
|
124
|
+
end.uniq
|
|
125
|
+
end
|
|
98
126
|
end
|
|
99
127
|
end
|
|
100
128
|
end
|
|
@@ -33,6 +33,9 @@ module Mongo
|
|
|
33
33
|
# Error message when hedge is specified for a read preference that does not support it.
|
|
34
34
|
#
|
|
35
35
|
# @api private
|
|
36
|
+
#
|
|
37
|
+
# @deprecated Hedged reads are deprecated in MongoDB Server 8.0 and will
|
|
38
|
+
# be removed in a future version.
|
|
36
39
|
NO_HEDGE_SUPPORT = 'The hedge option cannot be set for this read preference'
|
|
37
40
|
|
|
38
41
|
# Error message for when the max staleness is not at least twice the heartbeat frequency.
|
|
@@ -53,6 +53,10 @@ module Mongo
|
|
|
53
53
|
# @api experimental
|
|
54
54
|
attr_reader :server_message
|
|
55
55
|
|
|
56
|
+
# @return [ String | nil ] The address ("host:port") of the server
|
|
57
|
+
# that produced this error, if known.
|
|
58
|
+
attr_reader :server_address
|
|
59
|
+
|
|
56
60
|
# Error codes and code names that should result in a failing getMore
|
|
57
61
|
# command on a change stream NOT being resumed.
|
|
58
62
|
#
|
|
@@ -172,6 +176,8 @@ module Mongo
|
|
|
172
176
|
# error document.
|
|
173
177
|
# @option options [ String ] server_message The server-returned
|
|
174
178
|
# error message parsed from the response.
|
|
179
|
+
# @option options [ nil | String | Mongo::Address | Mongo::Server::Description ]
|
|
180
|
+
# :server_address The address of the server that produced the error.
|
|
175
181
|
# @option options [ Hash ] :write_concern_error_document The
|
|
176
182
|
# server-supplied write concern error document, if any.
|
|
177
183
|
# @option options [ Integer ] :write_concern_error_code Error code for
|
|
@@ -185,7 +191,8 @@ module Mongo
|
|
|
185
191
|
# @option options [ true | false ] :wtimeout Whether the error is a wtimeout.
|
|
186
192
|
def initialize(message = nil, result = nil, options = {})
|
|
187
193
|
@details = retrieve_details(options[:document])
|
|
188
|
-
|
|
194
|
+
@server_address = normalize_server_address(options[:server_address])
|
|
195
|
+
super(append_server_address(append_details(message, @details)))
|
|
189
196
|
|
|
190
197
|
@result = result
|
|
191
198
|
@code = options[:code]
|
|
@@ -241,6 +248,38 @@ module Mongo
|
|
|
241
248
|
|
|
242
249
|
message + " -- #{details.to_json}"
|
|
243
250
|
end
|
|
251
|
+
|
|
252
|
+
# Append the server address suffix to the message when the
|
|
253
|
+
# Mongo.include_server_address_in_errors flag is enabled and
|
|
254
|
+
# a server address is known.
|
|
255
|
+
#
|
|
256
|
+
# @return [ String | nil ] the message with the suffix appended,
|
|
257
|
+
# or the original message unchanged.
|
|
258
|
+
def append_server_address(message)
|
|
259
|
+
return message unless Mongo.include_server_address_in_errors
|
|
260
|
+
return message if @server_address.nil?
|
|
261
|
+
return "(on #{@server_address})" if message.nil? || message.empty?
|
|
262
|
+
|
|
263
|
+
"#{message} (on #{@server_address})"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Normalize a server_address option into a String "host:port" form.
|
|
267
|
+
#
|
|
268
|
+
# @param [ nil | String | Mongo::Address | Mongo::Server::Description ] value
|
|
269
|
+
#
|
|
270
|
+
# @return [ String | nil ] The normalized address, or nil.
|
|
271
|
+
def normalize_server_address(value)
|
|
272
|
+
case value
|
|
273
|
+
when nil then nil
|
|
274
|
+
when String then value
|
|
275
|
+
when Mongo::Address then value.seed
|
|
276
|
+
when Mongo::Server::Description
|
|
277
|
+
value.address.is_a?(Mongo::Address) ? value.address.seed : nil
|
|
278
|
+
else
|
|
279
|
+
raise ArgumentError,
|
|
280
|
+
"server_address must be nil, String, Mongo::Address, or Mongo::Server::Description; got #{value.class}"
|
|
281
|
+
end
|
|
282
|
+
end
|
|
244
283
|
end
|
|
245
284
|
|
|
246
285
|
# OperationFailure is the canonical implementor of the
|
|
@@ -23,6 +23,8 @@ module Mongo
|
|
|
23
23
|
private
|
|
24
24
|
|
|
25
25
|
def log_event(event)
|
|
26
|
+
return if event.previous_description == event.new_description
|
|
27
|
+
|
|
26
28
|
log_debug(
|
|
27
29
|
"Server description for #{event.address} changed from " +
|
|
28
30
|
"'#{event.previous_description.server_type}' to '#{event.new_description.server_type}'#{awaited_indicator(event)}."
|
|
@@ -24,6 +24,9 @@ module Mongo
|
|
|
24
24
|
|
|
25
25
|
def log_event(event)
|
|
26
26
|
if event.previous_topology.class == event.new_topology.class
|
|
27
|
+
return if event.previous_topology.server_descriptions ==
|
|
28
|
+
event.new_topology.server_descriptions
|
|
29
|
+
|
|
27
30
|
log_debug(
|
|
28
31
|
"There was a change in the members of the '#{event.new_topology.display_name}' " +
|
|
29
32
|
'topology.'
|
|
@@ -355,7 +355,8 @@ module Mongo
|
|
|
355
355
|
wtimeout: parser.wtimeout,
|
|
356
356
|
connection_description: connection_description,
|
|
357
357
|
document: parser.document,
|
|
358
|
-
server_message: parser.server_message
|
|
358
|
+
server_message: parser.server_message,
|
|
359
|
+
server_address: connection_description
|
|
359
360
|
)
|
|
360
361
|
end
|
|
361
362
|
|
|
@@ -141,6 +141,13 @@ module Mongo
|
|
|
141
141
|
@pending_connections = Set.new
|
|
142
142
|
@interrupt_connections = []
|
|
143
143
|
|
|
144
|
+
# RUBY-3364: count threads currently blocked on size_cv /
|
|
145
|
+
# max_connecting_cv. When non-zero, a newly-arriving thread must
|
|
146
|
+
# enter the wait queue even if the gate predicate is currently
|
|
147
|
+
# satisfied, to prevent barging past existing waiters.
|
|
148
|
+
@size_waiters = 0
|
|
149
|
+
@max_connecting_waiters = 0
|
|
150
|
+
|
|
144
151
|
# Mutex used for synchronizing access to @available_connections and
|
|
145
152
|
# @checked_out_connections. The pool object is thread-safe, thus
|
|
146
153
|
# all methods that retrieve or modify instance variables generally
|
|
@@ -1301,13 +1308,27 @@ module Mongo
|
|
|
1301
1308
|
connection = nil
|
|
1302
1309
|
|
|
1303
1310
|
@lock.synchronize do
|
|
1304
|
-
#
|
|
1305
|
-
#
|
|
1306
|
-
|
|
1311
|
+
# RUBY-3364: if any thread is already waiting for a size slot,
|
|
1312
|
+
# join the queue even when the gate predicate is currently
|
|
1313
|
+
# satisfied. Without this, re-entering threads (those that just
|
|
1314
|
+
# checked a connection back in) barge past existing waiters and
|
|
1315
|
+
# the 195 blocked threads in a 200:5 scenario never wake.
|
|
1316
|
+
# Skip the gate for unlimited pools (max_size == 0) where there
|
|
1317
|
+
# is no size constraint to wait on.
|
|
1318
|
+
must_wait = max_size != 0 && @size_waiters > 0
|
|
1319
|
+
until (max_size == 0 || unavailable_connections < max_size) && !must_wait
|
|
1307
1320
|
wait = deadline - Utils.monotonic_time
|
|
1308
1321
|
raise_check_out_timeout!(connection_global_id) if wait <= 0
|
|
1309
|
-
@
|
|
1322
|
+
@size_waiters += 1
|
|
1323
|
+
begin
|
|
1324
|
+
@size_cv.wait(wait)
|
|
1325
|
+
ensure
|
|
1326
|
+
@size_waiters -= 1
|
|
1327
|
+
end
|
|
1310
1328
|
raise_if_not_ready!
|
|
1329
|
+
# After one wait cycle we have served our "queue tax" and
|
|
1330
|
+
# compete for the slot on the next predicate check.
|
|
1331
|
+
must_wait = false
|
|
1311
1332
|
end
|
|
1312
1333
|
@connection_requests += 1
|
|
1313
1334
|
connection = wait_for_connection(connection_global_id, deadline)
|
|
@@ -1319,8 +1340,17 @@ module Mongo
|
|
|
1319
1340
|
@checked_out_connections << connection
|
|
1320
1341
|
@pending_connections.delete(connection) if @pending_connections.include?(connection)
|
|
1321
1342
|
@max_connecting_cv.signal
|
|
1322
|
-
#
|
|
1323
|
-
#
|
|
1343
|
+
# RUBY-3364: hand off the baton. A waiter that arrived during
|
|
1344
|
+
# our wake-up window (seeing our stale @size_waiters > 0) may be
|
|
1345
|
+
# parked on @size_cv with capacity already available. The
|
|
1346
|
+
# regular check-in path is the only other place that signals
|
|
1347
|
+
# @size_cv, so we wake the next waiter only when the predicate
|
|
1348
|
+
# is actually satisfied for them. Signaling unconditionally
|
|
1349
|
+
# would re-queue a waiter at the back of the FIFO and break
|
|
1350
|
+
# ordering.
|
|
1351
|
+
if @size_waiters > 0 && (max_size == 0 || unavailable_connections < max_size)
|
|
1352
|
+
@size_cv.signal
|
|
1353
|
+
end
|
|
1324
1354
|
end
|
|
1325
1355
|
|
|
1326
1356
|
connection
|
|
@@ -1342,9 +1372,12 @@ module Mongo
|
|
|
1342
1372
|
def wait_for_connection(connection_global_id, deadline)
|
|
1343
1373
|
connection = nil
|
|
1344
1374
|
while connection.nil?
|
|
1375
|
+
# RUBY-3364: as above, yield to any thread already queued for
|
|
1376
|
+
# a max_connecting slot before competing ourselves.
|
|
1377
|
+
must_wait = @max_connecting_waiters > 0
|
|
1345
1378
|
# The second gate to checking out a connection. Make sure 1) there
|
|
1346
1379
|
# exists an available connection and 2) we are under max_connecting.
|
|
1347
|
-
until @available_connections.any? || @pending_connections.length < @max_connecting
|
|
1380
|
+
until (@available_connections.any? || @pending_connections.length < @max_connecting) && !must_wait
|
|
1348
1381
|
wait = deadline - Utils.monotonic_time
|
|
1349
1382
|
if wait <= 0
|
|
1350
1383
|
# We are going to raise a timeout error, so the connection
|
|
@@ -1353,10 +1386,16 @@ module Mongo
|
|
|
1353
1386
|
decrement_connection_requests_and_signal
|
|
1354
1387
|
raise_check_out_timeout!(connection_global_id)
|
|
1355
1388
|
end
|
|
1356
|
-
@
|
|
1389
|
+
@max_connecting_waiters += 1
|
|
1390
|
+
begin
|
|
1391
|
+
@max_connecting_cv.wait(wait)
|
|
1392
|
+
ensure
|
|
1393
|
+
@max_connecting_waiters -= 1
|
|
1394
|
+
end
|
|
1357
1395
|
# We do not need to decrement the connection_requests counter
|
|
1358
1396
|
# or signal here because the pool is not ready yet.
|
|
1359
1397
|
raise_if_not_ready!
|
|
1398
|
+
must_wait = false
|
|
1360
1399
|
end
|
|
1361
1400
|
|
|
1362
1401
|
connection = get_connection(Process.pid, connection_global_id)
|
|
@@ -1370,6 +1409,14 @@ module Mongo
|
|
|
1370
1409
|
raise_check_out_timeout!(connection_global_id)
|
|
1371
1410
|
end
|
|
1372
1411
|
|
|
1412
|
+
# RUBY-3364: hand off the baton for max_connecting_cv. Signal
|
|
1413
|
+
# only if the gate predicate is satisfied for the next waiter, to
|
|
1414
|
+
# avoid re-queuing a waiter at the back of the FIFO.
|
|
1415
|
+
if @max_connecting_waiters > 0 &&
|
|
1416
|
+
(@available_connections.any? || @pending_connections.length < @max_connecting)
|
|
1417
|
+
@max_connecting_cv.signal
|
|
1418
|
+
end
|
|
1419
|
+
|
|
1373
1420
|
connection
|
|
1374
1421
|
end
|
|
1375
1422
|
|
|
@@ -61,7 +61,7 @@ module Mongo
|
|
|
61
61
|
# The wire protocol versions that this version of the driver supports.
|
|
62
62
|
#
|
|
63
63
|
# @since 2.0.0
|
|
64
|
-
DRIVER_WIRE_VERSIONS = 8..
|
|
64
|
+
DRIVER_WIRE_VERSIONS = 8..29
|
|
65
65
|
|
|
66
66
|
# The wire protocol versions that are deprecated in this version of the
|
|
67
67
|
# driver. Support for these versions will be removed in the future.
|
|
@@ -185,14 +185,35 @@ module Mongo
|
|
|
185
185
|
# @api private
|
|
186
186
|
CONNECTION_ID = 'connectionId'
|
|
187
187
|
|
|
188
|
+
# Constant for reading the modern primary flag from config.
|
|
189
|
+
#
|
|
190
|
+
# @api private
|
|
191
|
+
IS_WRITABLE_PRIMARY = 'isWritablePrimary'
|
|
192
|
+
|
|
193
|
+
# Constant for reading the helloOk capability flag from config.
|
|
194
|
+
#
|
|
195
|
+
# @api private
|
|
196
|
+
HELLO_OK = 'helloOk'
|
|
197
|
+
|
|
188
198
|
# Fields to exclude when comparing two descriptions.
|
|
189
199
|
#
|
|
200
|
+
# The PRIMARY (legacy `ismaster`), IS_WRITABLE_PRIMARY (modern `hello`),
|
|
201
|
+
# and HELLO_OK keys are excluded because the driver does a one-time
|
|
202
|
+
# legacy-`isMaster` to modern-`hello` protocol switch on the initial
|
|
203
|
+
# handshake (per the SDAM Server Monitoring spec). Two responses for the
|
|
204
|
+
# same logical role differ only in which of these keys is populated.
|
|
205
|
+
# The role itself is still differentiated by the SECONDARY flag and the
|
|
206
|
+
# remaining replica-set metadata.
|
|
207
|
+
#
|
|
190
208
|
# @since 2.0.6
|
|
191
209
|
EXCLUDE_FOR_COMPARISON = [ LOCAL_TIME,
|
|
192
210
|
LAST_WRITE,
|
|
193
211
|
OPERATION_TIME,
|
|
194
212
|
Operation::CLUSTER_TIME,
|
|
195
|
-
CONNECTION_ID,
|
|
213
|
+
CONNECTION_ID,
|
|
214
|
+
PRIMARY,
|
|
215
|
+
IS_WRITABLE_PRIMARY,
|
|
216
|
+
HELLO_OK, ].freeze
|
|
196
217
|
|
|
197
218
|
# Instantiate the new server description from the result of the hello
|
|
198
219
|
# command or fabricate a placeholder description for Unknown and
|
|
@@ -866,6 +887,7 @@ module Mongo
|
|
|
866
887
|
def ==(other)
|
|
867
888
|
return false if self.class != other.class
|
|
868
889
|
return false if unknown? || other.unknown?
|
|
890
|
+
return false if server_type != other.server_type
|
|
869
891
|
|
|
870
892
|
(config.keys + other.config.keys).uniq.all? do |k|
|
|
871
893
|
config[k] == other.config[k] || EXCLUDE_FOR_COMPARISON.include?(k)
|
|
@@ -37,6 +37,8 @@ module Mongo
|
|
|
37
37
|
# reads on the server. Hedged reads are not enabled by default. When
|
|
38
38
|
# specifying this option, it must be in the format: { enabled: true },
|
|
39
39
|
# where the value of the :enabled key is a boolean value.
|
|
40
|
+
# @deprecated Hedged reads are deprecated in MongoDB Server 8.0 and will
|
|
41
|
+
# be removed in a future version.
|
|
40
42
|
#
|
|
41
43
|
# @raise [ Error::InvalidServerPreference ] If tag sets are specified
|
|
42
44
|
# but not allowed.
|
|
@@ -51,6 +53,14 @@ module Mongo
|
|
|
51
53
|
@hedge = options[:hedge]
|
|
52
54
|
|
|
53
55
|
validate!
|
|
56
|
+
|
|
57
|
+
return if @hedge.nil?
|
|
58
|
+
|
|
59
|
+
Mongo::Deprecations.warn(
|
|
60
|
+
:hedge_read_preference,
|
|
61
|
+
'The hedge read preference option is deprecated. Hedged reads are ' \
|
|
62
|
+
'deprecated in MongoDB Server 8.0 and will be removed in a future version.'
|
|
63
|
+
)
|
|
54
64
|
end
|
|
55
65
|
|
|
56
66
|
# @return [ Hash ] options The options.
|
|
@@ -67,6 +77,9 @@ module Mongo
|
|
|
67
77
|
|
|
68
78
|
# @return [ Hash | nil ] hedge The document specifying whether to enable
|
|
69
79
|
# hedged reads.
|
|
80
|
+
#
|
|
81
|
+
# @deprecated Hedged reads are deprecated in MongoDB Server 8.0 and will
|
|
82
|
+
# be removed in a future version.
|
|
70
83
|
attr_reader :hedge
|
|
71
84
|
|
|
72
85
|
# Get the timeout for server selection.
|
|
@@ -59,6 +59,9 @@ module Mongo
|
|
|
59
59
|
# Whether the hedge option is allowed to be defined for this server preference.
|
|
60
60
|
#
|
|
61
61
|
# @return [ true ] true
|
|
62
|
+
#
|
|
63
|
+
# @deprecated Hedged reads are deprecated in MongoDB Server 8.0 and will
|
|
64
|
+
# be removed in a future version.
|
|
62
65
|
def hedge_allowed?
|
|
63
66
|
true
|
|
64
67
|
end
|
|
@@ -59,6 +59,9 @@ module Mongo
|
|
|
59
59
|
# Whether the hedge option is allowed to be defined for this server preference.
|
|
60
60
|
#
|
|
61
61
|
# @return [ false ] false
|
|
62
|
+
#
|
|
63
|
+
# @deprecated Hedged reads are deprecated in MongoDB Server 8.0 and will
|
|
64
|
+
# be removed in a future version.
|
|
62
65
|
def hedge_allowed?
|
|
63
66
|
false
|
|
64
67
|
end
|
|
@@ -59,6 +59,9 @@ module Mongo
|
|
|
59
59
|
# Whether the hedge option is allowed to be defined for this server preference.
|
|
60
60
|
#
|
|
61
61
|
# @return [ true ] true
|
|
62
|
+
#
|
|
63
|
+
# @deprecated Hedged reads are deprecated in MongoDB Server 8.0 and will
|
|
64
|
+
# be removed in a future version.
|
|
62
65
|
def hedge_allowed?
|
|
63
66
|
true
|
|
64
67
|
end
|
|
@@ -59,6 +59,9 @@ module Mongo
|
|
|
59
59
|
# Whether the hedge option is allowed to be defined for this server preference.
|
|
60
60
|
#
|
|
61
61
|
# @return [ true ] true
|
|
62
|
+
#
|
|
63
|
+
# @deprecated Hedged reads are deprecated in MongoDB Server 8.0 and will
|
|
64
|
+
# be removed in a future version.
|
|
62
65
|
def hedge_allowed?
|
|
63
66
|
true
|
|
64
67
|
end
|
|
@@ -59,6 +59,9 @@ module Mongo
|
|
|
59
59
|
# Whether the hedge option is allowed to be defined for this server preference.
|
|
60
60
|
#
|
|
61
61
|
# @return [ true ] true
|
|
62
|
+
#
|
|
63
|
+
# @deprecated Hedged reads are deprecated in MongoDB Server 8.0 and will
|
|
64
|
+
# be removed in a future version.
|
|
62
65
|
def hedge_allowed?
|
|
63
66
|
true
|
|
64
67
|
end
|
data/lib/mongo/session.rb
CHANGED
|
@@ -74,6 +74,8 @@ module Mongo
|
|
|
74
74
|
# and *:nearest*.
|
|
75
75
|
# @option options [ true | false ] :snapshot Set up the session for
|
|
76
76
|
# snapshot reads.
|
|
77
|
+
# @option options [ BSON::Timestamp ] :snapshot_time The desired snapshot
|
|
78
|
+
# time for snapshot reads. Only valid when :snapshot is true.
|
|
77
79
|
#
|
|
78
80
|
# @since 2.5.0
|
|
79
81
|
# @api private
|
|
@@ -82,6 +84,14 @@ module Mongo
|
|
|
82
84
|
raise ArgumentError, ':causal_consistency and :snapshot options cannot be both set on a session'
|
|
83
85
|
end
|
|
84
86
|
|
|
87
|
+
if options[:snapshot_time] && !options[:snapshot]
|
|
88
|
+
raise ArgumentError, ':snapshot_time can only be set when :snapshot is true'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
if options[:snapshot_time] && !options[:snapshot_time].is_a?(BSON::Timestamp)
|
|
92
|
+
raise ArgumentError, ':snapshot_time must be a BSON::Timestamp'
|
|
93
|
+
end
|
|
94
|
+
|
|
85
95
|
if options[:implicit]
|
|
86
96
|
unless server_session.nil?
|
|
87
97
|
raise ArgumentError, 'Implicit session cannot reference server session during construction'
|
|
@@ -104,6 +114,7 @@ module Mongo
|
|
|
104
114
|
@with_transaction_deadline = nil
|
|
105
115
|
@with_transaction_timeout_ms = nil
|
|
106
116
|
@inside_with_transaction = false
|
|
117
|
+
@snapshot_timestamp = options[:snapshot_time]
|
|
107
118
|
end
|
|
108
119
|
|
|
109
120
|
# @return [ Hash ] The options for this session.
|
|
@@ -936,6 +947,13 @@ module Mongo
|
|
|
936
947
|
#
|
|
937
948
|
# @api private
|
|
938
949
|
def unpin(connection = nil)
|
|
950
|
+
# Idempotent: if there is no pinned state to clear, do nothing. Nested
|
|
951
|
+
# unpin_maybe handlers (e.g. in BulkWrite#execute_operation wrapping an
|
|
952
|
+
# OpMsg execution that already calls unpin_maybe in its own do_execute)
|
|
953
|
+
# can call this method twice for the same error; checking the connection
|
|
954
|
+
# back into the pool a second time would raise from the pool.
|
|
955
|
+
return if @pinned_server.nil? && @pinned_connection.nil? && @pinned_connection_global_id.nil?
|
|
956
|
+
|
|
939
957
|
@pinned_server = nil
|
|
940
958
|
@pinned_connection_global_id = nil
|
|
941
959
|
conn = connection || @pinned_connection
|
|
@@ -1266,8 +1284,23 @@ module Mongo
|
|
|
1266
1284
|
@server_session.txn_num
|
|
1267
1285
|
end
|
|
1268
1286
|
|
|
1287
|
+
# @return [ BSON::Timestamp | nil ] The snapshot time for this session.
|
|
1288
|
+
# nil if the session is not a snapshot session, or if it is a snapshot
|
|
1289
|
+
# session for which no :snapshot_time option was provided and no read
|
|
1290
|
+
# has yet captured atClusterTime from the server.
|
|
1291
|
+
attr_reader :snapshot_timestamp
|
|
1292
|
+
|
|
1293
|
+
# Sets the snapshot time for the session. Once set, subsequent
|
|
1294
|
+
# assignments are ignored: snapshotTime is established at most once per
|
|
1295
|
+
# session, either from the :snapshot_time option at construction or from
|
|
1296
|
+
# the atClusterTime returned by the first find/aggregate/distinct
|
|
1297
|
+
# response. This keeps the property effectively read-only for callers,
|
|
1298
|
+
# per the snapshot-sessions spec rationale.
|
|
1299
|
+
#
|
|
1269
1300
|
# @api private
|
|
1270
|
-
|
|
1301
|
+
def snapshot_timestamp=(value)
|
|
1302
|
+
@snapshot_timestamp ||= value
|
|
1303
|
+
end
|
|
1271
1304
|
|
|
1272
1305
|
# @return [ Integer | nil ] The deadline for the current transaction, if any.
|
|
1273
1306
|
# @api private
|
|
@@ -21,6 +21,15 @@ module Mongo
|
|
|
21
21
|
#
|
|
22
22
|
# @api private
|
|
23
23
|
class CommandTracer
|
|
24
|
+
include Mongo::Monitoring::Event::Secure
|
|
25
|
+
|
|
26
|
+
# Commands for which a span MUST NOT be created. The OpenTelemetry spec
|
|
27
|
+
# requires drivers to skip command spans for sensitive commands listed in
|
|
28
|
+
# the Command Logging and Monitoring spec. We additionally skip hello /
|
|
29
|
+
# legacy hello in all forms — these are handshake/heartbeat traffic and
|
|
30
|
+
# would only add noise to traces.
|
|
31
|
+
HELLO_COMMANDS = %w[hello ismaster isMaster].freeze
|
|
32
|
+
|
|
24
33
|
# Initializes a new CommandTracer.
|
|
25
34
|
#
|
|
26
35
|
# @param otel_tracer [ OpenTelemetry::Trace::Tracer ] the OpenTelemetry tracer.
|
|
@@ -57,6 +66,8 @@ module Mongo
|
|
|
57
66
|
# @return [ Object ] the result of the command.
|
|
58
67
|
# rubocop:disable Lint/RescueException
|
|
59
68
|
def trace_command(message, _operation_context, connection)
|
|
69
|
+
return yield if skip_tracing?(message)
|
|
70
|
+
|
|
60
71
|
# Commands should always be nested under their operation span, not directly under
|
|
61
72
|
# the transaction span. Don't pass with_parent to use automatic parent resolution
|
|
62
73
|
# from the currently active span (the operation span).
|
|
@@ -76,6 +87,22 @@ module Mongo
|
|
|
76
87
|
|
|
77
88
|
private
|
|
78
89
|
|
|
90
|
+
# Determines whether the command must not be traced. Sensitive auth
|
|
91
|
+
# commands carry credentials in their payloads (SCRAM proofs, cleartext
|
|
92
|
+
# passwords, etc.) and the OpenTelemetry spec requires drivers to skip
|
|
93
|
+
# command spans for them. Hello / legacy hello are also skipped to keep
|
|
94
|
+
# handshake traffic out of traces.
|
|
95
|
+
#
|
|
96
|
+
# @param message [ Mongo::Protocol::Message ] the command message.
|
|
97
|
+
#
|
|
98
|
+
# @return [ Boolean ] true when no command span should be created.
|
|
99
|
+
def skip_tracing?(message)
|
|
100
|
+
name = command_name(message)
|
|
101
|
+
return true if HELLO_COMMANDS.include?(name)
|
|
102
|
+
|
|
103
|
+
sensitive?(command_name: name, document: message.documents.first)
|
|
104
|
+
end
|
|
105
|
+
|
|
79
106
|
# Creates a span for a command.
|
|
80
107
|
#
|
|
81
108
|
# @param message [ Mongo::Protocol::Message ] the command message.
|
data/lib/mongo/version.rb
CHANGED
data/lib/mongo.rb
CHANGED
|
@@ -101,6 +101,7 @@ module Mongo
|
|
|
101
101
|
delegate_option Config, :broken_view_options
|
|
102
102
|
delegate_option Config, :validate_update_replace
|
|
103
103
|
delegate_option Config, :csfle_convert_to_ruby_types
|
|
104
|
+
delegate_option Config, :include_server_address_in_errors
|
|
104
105
|
end
|
|
105
106
|
|
|
106
107
|
# Clears the driver's OCSP response cache.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mongo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.24.
|
|
4
|
+
version: 2.24.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- The MongoDB Ruby Team
|
|
@@ -559,7 +559,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
559
559
|
- !ruby/object:Gem::Version
|
|
560
560
|
version: '0'
|
|
561
561
|
requirements: []
|
|
562
|
-
rubygems_version: 4.0.
|
|
562
|
+
rubygems_version: 4.0.12
|
|
563
563
|
specification_version: 4
|
|
564
564
|
summary: Ruby driver for MongoDB
|
|
565
565
|
test_files: []
|