activesupport 7.1.0 → 7.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82365193f8aa8e04a486a7ed6f82adeb64093abd70569d67c7756b065f754b82
4
- data.tar.gz: ececf5de5e7b69fe11b7edc1007e7b850c2463005ffba7f2763b85636e192d98
3
+ metadata.gz: ecb3bcd9549f6429e9a7b2e3e54bd529a71608135834c95ecad50ed60dd8935a
4
+ data.tar.gz: 23c6ef54d1fbef9a19494322bae6ed4f4719d1a9f0b60e3f507dc1ccd4cf9adf
5
5
  SHA512:
6
- metadata.gz: e6daffabed388ec6412bff231a3d2478f430625d266078fe186c92594353b87026dc22a492e689ea7a716a570eb75a9eb53582a45b33627a06444be1b560da7e
7
- data.tar.gz: 33dc1b13f205838ad773fc7c4bfda5bb6bec704cbdb7ffdaedfe938a91088c2dd98d1ade38514689dbb66d2f5f45e3871973b8981c21cd6deabec0cff41349da
6
+ metadata.gz: abdba26b48e19b8f107f9110e2934f315f8f4fcf87340309f4786faf0998903a21e791d362e106550439088016039c692e00c90b380b5b7602b497244ea30419
7
+ data.tar.gz: 8f256ca213eea9aed13061094dca338c5886ba2bd3454036cd39649938399cc41ec74ff09ec28beabc21b9a57713c98e60125b13306e63a56aa908ad269b2316
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## Rails 7.1.1 (October 11, 2023) ##
2
+
3
+ * Add support for keyword arguments when delegating calls to custom loggers from `ActiveSupport::BroadcastLogger`.
4
+
5
+ *Edouard Chin*
6
+
7
+ * `NumberHelper`: handle objects responding `to_d`.
8
+
9
+ *fatkodima*
10
+
11
+ * Fix RedisCacheStore to properly set the TTL when incrementing or decrementing.
12
+
13
+ This bug was only impacting Redis server older than 7.0.
14
+
15
+ *Thomas Countz*
16
+
17
+ * Fix MemoryStore to prevent race conditions when incrementing or decrementing.
18
+
19
+ *Pierre Jambet*
20
+
21
+
1
22
  ## Rails 7.1.0 (October 05, 2023) ##
2
23
 
3
24
  * No changes.
@@ -868,7 +889,7 @@
868
889
 
869
890
  *Trevor Turk*
870
891
 
871
- * `ActiveSupport::Cache:Store#fetch` now passes an options accessor to the block.
892
+ * `ActiveSupport::Cache::Store#fetch` now passes an options accessor to the block.
872
893
 
873
894
  It makes possible to override cache options:
874
895
 
@@ -51,6 +51,26 @@ module ActiveSupport
51
51
  #
52
52
  # broadcast = BroadcastLogger.new
53
53
  # broadcast.info("Hello world") # The log message will appear nowhere.
54
+ #
55
+ # If you are adding a custom logger with custom methods to the broadcast,
56
+ # the `BroadcastLogger` will proxy them and return the raw value, or an array
57
+ # of raw values, depending on how many loggers in the broadcasts responded to
58
+ # the method:
59
+ #
60
+ # class MyLogger < ::Logger
61
+ # def loggable?
62
+ # true
63
+ # end
64
+ # end
65
+ #
66
+ # logger = BroadcastLogger.new
67
+ # logger.loggable? # => A NoMethodError exception is raised because no loggers in the broadcasts could respond.
68
+ #
69
+ # logger.broadcast_to(MyLogger.new(STDOUT))
70
+ # logger.loggable? # => true
71
+ # logger.broadcast_to(MyLogger.new(STDOUT))
72
+ # puts logger.broadcasts # => [MyLogger, MyLogger]
73
+ # logger.loggable? # [true, true]
54
74
  class BroadcastLogger
55
75
  include ActiveSupport::LoggerSilence
56
76
 
@@ -203,15 +223,15 @@ module ActiveSupport
203
223
  @broadcasts.each { |logger| block.call(logger) }
204
224
  end
205
225
 
206
- def method_missing(name, *args, &block)
226
+ def method_missing(name, *args, **kwargs, &block)
207
227
  loggers = @broadcasts.select { |logger| logger.respond_to?(name) }
208
228
 
209
229
  if loggers.none?
210
- super(name, *args, &block)
230
+ super(name, *args, **kwargs, &block)
211
231
  elsif loggers.one?
212
- loggers.first.send(name, *args, &block)
232
+ loggers.first.send(name, *args, **kwargs, &block)
213
233
  else
214
- loggers.map { |logger| logger.send(name, *args, &block) }
234
+ loggers.map { |logger| logger.send(name, *args, **kwargs, &block) }
215
235
  end
216
236
  end
217
237
 
@@ -238,16 +238,18 @@ module ActiveSupport
238
238
  key = normalize_key(name, options)
239
239
  version = normalize_version(name, options)
240
240
 
241
- entry = read_entry(key, **options)
241
+ synchronize do
242
+ entry = read_entry(key, **options)
242
243
 
243
- if !entry || entry.expired? || entry.mismatched?(version)
244
- write(name, Integer(amount), options)
245
- amount
246
- else
247
- num = entry.value.to_i + amount
248
- entry = Entry.new(num, expires_at: entry.expires_at, version: entry.version)
249
- write_entry(key, entry)
250
- num
244
+ if !entry || entry.expired? || entry.mismatched?(version)
245
+ write(name, Integer(amount), options)
246
+ amount
247
+ else
248
+ num = entry.value.to_i + amount
249
+ entry = Entry.new(num, expires_at: entry.expires_at, version: entry.version)
250
+ write_entry(key, entry)
251
+ num
252
+ end
251
253
  end
252
254
  end
253
255
  end
@@ -438,18 +438,26 @@ module ActiveSupport
438
438
  redis.then do |c|
439
439
  c = c.node_for(key) if c.is_a?(Redis::Distributed)
440
440
 
441
- if options[:expires_in] && supports_expire_nx?
442
- c.pipelined do |pipeline|
443
- pipeline.incrby(key, amount)
444
- pipeline.call(:expire, key, options[:expires_in].to_i, "NX")
445
- end.first
441
+ expires_in = options[:expires_in]
442
+
443
+ if expires_in
444
+ if supports_expire_nx?
445
+ count, _ = c.pipelined do |pipeline|
446
+ pipeline.incrby(key, amount)
447
+ pipeline.call(:expire, key, expires_in.to_i, "NX")
448
+ end
449
+ else
450
+ count, ttl = c.pipelined do |pipeline|
451
+ pipeline.incrby(key, amount)
452
+ pipeline.ttl(key)
453
+ end
454
+ c.expire(key, expires_in.to_i) if ttl < 0
455
+ end
446
456
  else
447
457
  count = c.incrby(key, amount)
448
- if count != amount && options[:expires_in] && c.ttl(key) < 0
449
- c.expire(key, options[:expires_in].to_i)
450
- end
451
- count
452
458
  end
459
+
460
+ count
453
461
  end
454
462
  end
455
463
 
@@ -439,9 +439,9 @@ module ActiveSupport
439
439
  #
440
440
  # ==== Dynamic Options
441
441
  #
442
- # In some cases it may be necessary to to dynamically compute options based
443
- # on the cached value. For this purpose, a ActiveSupport::Cache::WriteOptions
444
- # instance is passed as a second argument to the block
442
+ # In some cases it may be necessary to dynamically compute options based
443
+ # on the cached value. To support this, an ActiveSupport::Cache::WriteOptions
444
+ # instance is passed as the second argument to the block. For example:
445
445
  #
446
446
  # cache.fetch("authentication-token:#{user.id}") do |key, options|
447
447
  # token = authenticate_to_service
@@ -449,12 +449,6 @@ module ActiveSupport
449
449
  # token
450
450
  # end
451
451
  #
452
- # Only some options can be set dynamically:
453
- #
454
- # - +:expires_in+
455
- # - +:expires_at+
456
- # - +:version+
457
- #
458
452
  def fetch(name, options = nil, &block)
459
453
  if block_given?
460
454
  options = merged_options(options)
@@ -29,7 +29,7 @@ require "active_support/core_ext/date/conversions"
29
29
  # It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
30
30
  # bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
31
31
  # ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
32
- # should give exactly the same results with or without active support.
32
+ # should give exactly the same results with or without Active Support.
33
33
 
34
34
  module ActiveSupport
35
35
  module ToJsonWithActiveSupportEncoder # :nodoc:
@@ -60,8 +60,8 @@ module ActiveSupport
60
60
  # [+raise+] Raise ActiveSupport::DeprecationException.
61
61
  # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
62
62
  # [+log+] Log all deprecation warnings to +Rails.logger+.
63
- # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
64
- # [+report+] Use +ActiveSupport::ErrorReporter+ to report deprecations.
63
+ # [+notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
64
+ # [+report+] Use ActiveSupport::ErrorReporter to report deprecations.
65
65
  # [+silence+] Do nothing. On \Rails, set <tt>config.active_support.report_deprecations = false</tt> to disable all behaviors.
66
66
  #
67
67
  # Setting behaviors only affects deprecations that happen after boot time.
@@ -88,8 +88,8 @@ module ActiveSupport
88
88
  # [+raise+] Raise ActiveSupport::DeprecationException.
89
89
  # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
90
90
  # [+log+] Log all deprecation warnings to +Rails.logger+.
91
- # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
92
- # [+report+] Use +ActiveSupport::ErrorReporter+ to report deprecations.
91
+ # [+notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
92
+ # [+report+] Use ActiveSupport::ErrorReporter to report deprecations.
93
93
  # [+silence+] Do nothing.
94
94
  #
95
95
  # Setting behaviors only affects deprecations that happen after boot time.
@@ -9,7 +9,7 @@ module ActiveSupport
9
9
  module VERSION
10
10
  MAJOR = 7
11
11
  MINOR = 1
12
- TINY = 0
12
+ TINY = 1
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -130,6 +130,7 @@ module ActiveSupport
130
130
  # indicate whether old option sets are still in use or can be removed from
131
131
  # rotation.
132
132
 
133
+ ##
133
134
  private
134
135
  def build(salt, secret_generator:, secret_generator_options:, **options)
135
136
  secret_length = MessageEncryptor.key_len(*options[:cipher])
@@ -126,6 +126,7 @@ module ActiveSupport
126
126
  # indicate whether old option sets are still in use or can be removed from
127
127
  # rotation.
128
128
 
129
+ ##
129
130
  private
130
131
  def build(salt, secret_generator:, secret_generator_options:, **options)
131
132
  MessageVerifier.new(secret_generator.call(salt, **secret_generator_options), **options)
@@ -65,16 +65,16 @@ module ActiveSupport
65
65
  end
66
66
  end
67
67
 
68
- # Returns a "handle" for an event with the given +name+ and +payload+
68
+ # Returns a "handle" for an event with the given +name+ and +payload+.
69
69
  #
70
- # +#start+ and +#finish+ must each be called exactly once on the returned object.
70
+ # #start and #finish must each be called exactly once on the returned object.
71
71
  #
72
- # Where possible, it's best to use +#instrument+, which will record the
72
+ # Where possible, it's best to use #instrument, which will record the
73
73
  # start and finish of the event and correctly handle any exceptions.
74
74
  # +build_handle+ is a low-level API intended for cases where using
75
- # +#instrument+ isn't possible.
75
+ # +instrument+ isn't possible.
76
76
  #
77
- # See ActiveSupport::Notifications::Fanout::Handle
77
+ # See ActiveSupport::Notifications::Fanout::Handle.
78
78
  def build_handle(name, payload)
79
79
  @notifier.build_handle(name, @id, payload)
80
80
  end
@@ -146,21 +146,21 @@ module ActiveSupport
146
146
  @allocation_count_finish = now_allocations
147
147
  end
148
148
 
149
- # Returns the CPU time (in milliseconds) passed since the call to
150
- # +start!+ and the call to +finish!+
149
+ # Returns the CPU time (in milliseconds) passed between the call to
150
+ # #start! and the call to #finish!.
151
151
  def cpu_time
152
152
  @cpu_time_finish - @cpu_time_start
153
153
  end
154
154
 
155
- # Returns the idle time time (in milliseconds) passed since the call to
156
- # +start!+ and the call to +finish!+
155
+ # Returns the idle time time (in milliseconds) passed between the call to
156
+ # #start! and the call to #finish!.
157
157
  def idle_time
158
158
  diff = duration - cpu_time
159
159
  diff > 0.0 ? diff : 0.0
160
160
  end
161
161
 
162
- # Returns the number of allocations made since the call to +start!+ and
163
- # the call to +finish!+
162
+ # Returns the number of allocations made between the call to #start! and
163
+ # the call to #finish!.
164
164
  def allocations
165
165
  @allocation_count_finish - @allocation_count_start
166
166
  end
@@ -179,8 +179,10 @@ module ActiveSupport
179
179
  case number
180
180
  when Float, Rational
181
181
  number.to_d(0)
182
- else
182
+ when String
183
183
  BigDecimal(number, exception: false)
184
+ else
185
+ number.to_d rescue nil
184
186
  end
185
187
  end
186
188
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activesupport
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.0
4
+ version: 7.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-05 00:00:00.000000000 Z
11
+ date: 2023-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -446,10 +446,10 @@ licenses:
446
446
  - MIT
447
447
  metadata:
448
448
  bug_tracker_uri: https://github.com/rails/rails/issues
449
- changelog_uri: https://github.com/rails/rails/blob/v7.1.0/activesupport/CHANGELOG.md
450
- documentation_uri: https://api.rubyonrails.org/v7.1.0/
449
+ changelog_uri: https://github.com/rails/rails/blob/v7.1.1/activesupport/CHANGELOG.md
450
+ documentation_uri: https://api.rubyonrails.org/v7.1.1/
451
451
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
452
- source_code_uri: https://github.com/rails/rails/tree/v7.1.0/activesupport
452
+ source_code_uri: https://github.com/rails/rails/tree/v7.1.1/activesupport
453
453
  rubygems_mfa_required: 'true'
454
454
  post_install_message:
455
455
  rdoc_options: