Skip to content

Commit a6addbf

Browse files
committed
RUBY-3552 Deprecate support for server version 3.6
Adds a new Mongo::Deprecations module as well
1 parent 60c1e68 commit a6addbf

File tree

4 files changed

+126
-8
lines changed

4 files changed

+126
-8
lines changed

lib/mongo.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
require 'bson'
3636

37+
require 'mongo/deprecations'
3738
require 'mongo/id'
3839
require 'mongo/bson'
3940
require 'mongo/semaphore'

lib/mongo/deprecations.rb

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# frozen_string_literal: true
2+
3+
require 'mongo/loggable'
4+
5+
module Mongo
6+
# Used for reporting deprecated behavior in the driver. When it is possible
7+
# to detect that a deprecated feature is being used, a warning should be issued
8+
# through this module.
9+
#
10+
# The warning will be issued no more than once for that feature, regardless
11+
# of how many times Mongo::Deprecations.warn is called.
12+
#
13+
# @example Issue a deprecation warning.
14+
# Mongo::Deprecations.warn(:old_feature, "The old_feature is deprecated, use new_feature instead.")
15+
#
16+
# @api private
17+
module Deprecations
18+
extend self
19+
20+
include Mongo::Loggable
21+
22+
# Mutex for synchronizing access to warned features.
23+
# @api private
24+
MUTEX = Thread::Mutex.new
25+
26+
# Issue a warning about a deprecated feature. The warning is written to the
27+
# logger, and will not be written more than once per feature.
28+
def warn(feature, message)
29+
MUTEX.synchronize do
30+
return if _warned?(feature)
31+
32+
_warned!(feature)
33+
log_warn("[DEPRECATION:#{feature}] #{message}")
34+
end
35+
end
36+
37+
# Check if a warning for a given deprecated feature has already been issued.
38+
#
39+
# @param [ String | Symbol ] feature The deprecated feature.
40+
#
41+
# @return [ true | false ] If a warning has already been issued.
42+
def warned?(feature, prefix: false)
43+
MUTEX.synchronize { _warned?(feature, prefix: prefix) }
44+
end
45+
46+
# Mark that a warning for a given deprecated feature has been issued.
47+
#
48+
# @param [ String | Symbol ] feature The deprecated feature.
49+
def warned!(feature)
50+
MUTEX.synchronize { _warned!(feature) }
51+
end
52+
53+
# Clears all memory of previously warned features.
54+
def clear!
55+
MUTEX.synchronize { warned_features reset: true }
56+
true
57+
end
58+
59+
private
60+
61+
def warned_features(reset: false)
62+
@warned_features = nil if reset
63+
@warned_features ||= Set.new
64+
end
65+
66+
def _warned?(feature, prefix: false)
67+
if prefix
68+
warned_features.any? { |f| feature.to_s.start_with?(f) }
69+
else
70+
warned_features.include?(feature.to_s)
71+
end
72+
end
73+
74+
def _warned!(feature)
75+
warned_features.add(feature.to_s)
76+
end
77+
end
78+
end

lib/mongo/server/description/features.rb

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ class Features
7474
SERVER_TOO_OLD = "Server at (%s) reports wire version (%s), but this version of the Ruby driver " +
7575
"requires at least (%s)."
7676

77+
# Warning message if the server version is deprecated.
78+
SERVER_DEPRECATED = 'Server at (%s) reports wire version (%s), but support for that wire version ' \
79+
'is deprecated and will be removed in a future version of the Ruby driver. ' \
80+
'Please upgrade your MongoDB server to a newer version soon.'
81+
7782
# Error message if the driver is too old for the version of the server.
7883
#
7984
# @since 2.5.0
@@ -83,7 +88,20 @@ class Features
8388
# The wire protocol versions that this version of the driver supports.
8489
#
8590
# @since 2.0.0
86-
DRIVER_WIRE_VERSIONS = (6..25).freeze
91+
DRIVER_WIRE_VERSIONS = 6..25
92+
93+
# The wire protocol versions that are deprecated in this version of the
94+
# driver. Support for these versions will be removed in the future.
95+
#
96+
# If there are multiple currently-deprecated wire versions, this should
97+
# be set to a range of those versions.
98+
#
99+
# If there is only a single currently-deprecated wire version, this should
100+
# be set to a range where the min and max are the same value.
101+
#
102+
# If there are no currently-deprecated wire versions, this should be
103+
# set to an empty array.
104+
DEPRECATED_WIRE_VERSIONS = 6..6
87105

88106
# Create the methods for each mapping to tell if they are supported.
89107
#
@@ -131,20 +149,21 @@ def initialize(server_wire_versions, address = nil)
131149
end
132150

133151
# Check that there is an overlap between the driver supported wire
134-
# version range and the server wire version range.
135-
#
136-
# @example Verify the wire version overlap.
137-
# features.check_driver_support!
152+
# version range and the server wire version range. Also checks to see
153+
# if the server is using a deprecated wire version.
138154
#
139155
# @raise [ Error::UnsupportedFeatures ] If the wire version range is
140156
# not covered by the driver.
141-
#
142-
# @since 2.5.1
143157
def check_driver_support!
144-
if DRIVER_WIRE_VERSIONS.min > @server_wire_versions.max
158+
if DEPRECATED_WIRE_VERSIONS.include?(@server_wire_versions.max)
159+
feature = "wire_version:#{@address}"
160+
Mongo::Deprecations.warn(feature, SERVER_DEPRECATED % [@address, @server_wire_versions.max])
161+
162+
elsif DRIVER_WIRE_VERSIONS.min > @server_wire_versions.max
145163
raise Error::UnsupportedFeatures.new(SERVER_TOO_OLD % [@address,
146164
@server_wire_versions.max,
147165
DRIVER_WIRE_VERSIONS.min])
166+
148167
elsif DRIVER_WIRE_VERSIONS.max < @server_wire_versions.min
149168
raise Error::UnsupportedFeatures.new(DRIVER_TOO_OLD % [@address,
150169
@server_wire_versions.min,

spec/mongo/server/description/features_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,26 @@
3535
end
3636
end
3737

38+
if described_class::DEPRECATED_WIRE_VERSIONS.any?
39+
context 'when the max server wire version range is deprecated' do
40+
before do
41+
Mongo::Deprecations.clear!
42+
end
43+
44+
let(:wire_versions) do
45+
(described_class::DEPRECATED_WIRE_VERSIONS.min - 1)..described_class::DEPRECATED_WIRE_VERSIONS.max
46+
end
47+
48+
it 'issues a deprecation warning' do
49+
expect {
50+
features.check_driver_support!
51+
}.to change {
52+
Mongo::Deprecations.warned?("wire_version:#{default_address}")
53+
}.from(false).to(true)
54+
end
55+
end
56+
end
57+
3858
context 'when the server wire version range max is higher' do
3959

4060
let(:wire_versions) do

0 commit comments

Comments
 (0)