activesupport 8.0.3 → 8.0.4

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: b2cdf9736ba5b94841913f95e5e83f01cc82becad9006ed2d75e18f1cc117c43
4
- data.tar.gz: 7f8f545780e7ecfece1bdd6af006e504d91e89ad019a1020cd43014a296e7def
3
+ metadata.gz: 32beba8624850f5da4cad945a95adadbf26c3469dc4da4f231412b37b6fbc070
4
+ data.tar.gz: 66eec5b8c43f67d79449762999acce95b9c73a93800197bdaca5f22033876819
5
5
  SHA512:
6
- metadata.gz: b23ff4bae6aae8f2e154b478c8f36825d0179152a0591591c240ea2b8d6104dcad0b70598a9b42888ab41448a06bc6b69c4ca537c1e5edb386fa81408f25acde
7
- data.tar.gz: 84fa236c5c86feff0ae2283888ca7266c5f5d9090474b099c2b9142c082e107062bea571d8197f0138a022d7db7fe08e02f3544ade6cd611de68c35b26b90e75
6
+ metadata.gz: 1eb3ea47ffa973a4c8378e804c7bf69e03013d39b30f73e5a80285672fa8aa1d109385ea3b9dff14f438d38e39ee47e6333567a385cd3bf0a64371b7e546757b
7
+ data.tar.gz: f204a3f69b69120cd00b904589a0d6bdfbf0f9655c2f6fd20070af01799b1851dead84e44c9c3ef3af1f70e56cc4323de07dad8dc14128624aba904f48c9dd83
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## Rails 8.0.4 (October 28, 2025) ##
2
+
3
+ * Fix `Enumerable#sole` to return the full tuple instead of just the first element of the tuple.
4
+
5
+ *Olivier Bellone*
6
+
7
+ * Fix parallel tests hanging when worker processes die abruptly.
8
+
9
+ Previously, if a worker process was killed (e.g., OOM killed, `kill -9`) during parallel
10
+ test execution, the test suite would hang forever waiting for the dead worker.
11
+
12
+ *Joshua Young*
13
+
14
+ * Fix `NameError` when `class_attribute` is defined on instance singleton classes.
15
+
16
+ Previously, calling `class_attribute` on an instance's singleton class would raise
17
+ a `NameError` when accessing the attribute through the instance.
18
+
19
+ ```ruby
20
+ object = MyClass.new
21
+ object.singleton_class.class_attribute :foo, default: "bar"
22
+ object.foo # previously raised NameError, now returns "bar"
23
+ ```
24
+
25
+ *Joshua Young*
26
+
27
+
1
28
  ## Rails 8.0.3 (September 22, 2025) ##
2
29
 
3
30
  * `ActiveSupport::FileUpdateChecker` does not depend on `Time.now` to prevent unnecessary reloads with time travel test helpers
@@ -32,7 +59,7 @@
32
59
 
33
60
  ```ruby
34
61
  >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
35
- => {"c" => 1, "d" => 2}
62
+ => {"b" => 1, "c" => 2}
36
63
  ```
37
64
 
38
65
  *Jason T Johnson*, *Jean Boussier*
@@ -96,14 +96,16 @@ class Class
96
96
  namespaced_name = :"__class_attr_#{name}"
97
97
  ::ActiveSupport::ClassAttribute.redefine(self, name, namespaced_name, default)
98
98
 
99
- delegators = [
100
- "def #{name}; #{namespaced_name}; end",
101
- "def #{name}=(value); self.#{namespaced_name} = value; end",
102
- ]
99
+ class_methods << "def #{name}; #{namespaced_name}; end"
100
+ class_methods << "def #{name}=(value); self.#{namespaced_name} = value; end"
103
101
 
104
- class_methods.concat(delegators)
105
102
  if singleton_class?
106
- methods.concat(delegators)
103
+ methods << <<~RUBY if instance_reader
104
+ silence_redefinition_of_method(:#{name})
105
+ def #{name}
106
+ self.singleton_class.#{name}
107
+ end
108
+ RUBY
107
109
  else
108
110
  methods << <<~RUBY if instance_reader
109
111
  silence_redefinition_of_method def #{name}
@@ -212,12 +212,12 @@ module Enumerable
212
212
  result = nil
213
213
  found = false
214
214
 
215
- each do |element|
215
+ each do |*element|
216
216
  if found
217
217
  raise SoleItemExpectedError, "multiple items found"
218
218
  end
219
219
 
220
- result = element
220
+ result = element.size == 1 ? element[0] : element
221
221
  found = true
222
222
  end
223
223
 
@@ -9,7 +9,7 @@ module ActiveSupport
9
9
  module VERSION
10
10
  MAJOR = 8
11
11
  MINOR = 0
12
- TINY = 3
12
+ TINY = 4
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -164,7 +164,7 @@ module ActiveSupport
164
164
  @cpu_time_finish - @cpu_time_start
165
165
  end
166
166
 
167
- # Returns the idle time time (in milliseconds) passed between the call to
167
+ # Returns the idle time (in milliseconds) passed between the call to
168
168
  # #start! and the call to #finish!.
169
169
  def idle_time
170
170
  diff = duration - cpu_time
@@ -14,6 +14,7 @@ module ActiveSupport
14
14
  def initialize
15
15
  @queue = Queue.new
16
16
  @active_workers = Concurrent::Map.new
17
+ @worker_pids = Concurrent::Map.new
17
18
  @in_flight = Concurrent::Map.new
18
19
  end
19
20
 
@@ -40,12 +41,24 @@ module ActiveSupport
40
41
  end
41
42
  end
42
43
 
43
- def start_worker(worker_id)
44
+ def start_worker(worker_id, worker_pid)
44
45
  @active_workers[worker_id] = true
46
+ @worker_pids[worker_id] = worker_pid
45
47
  end
46
48
 
47
- def stop_worker(worker_id)
49
+ def stop_worker(worker_id, worker_pid)
48
50
  @active_workers.delete(worker_id)
51
+ @worker_pids.delete(worker_id)
52
+ end
53
+
54
+ def remove_dead_workers(dead_pids)
55
+ dead_pids.each do |dead_pid|
56
+ worker_id = @worker_pids.key(dead_pid)
57
+ if worker_id
58
+ @active_workers.delete(worker_id)
59
+ @worker_pids.delete(worker_id)
60
+ end
61
+ end
49
62
  end
50
63
 
51
64
  def active_workers?
@@ -18,7 +18,7 @@ module ActiveSupport
18
18
  DRb.stop_service
19
19
 
20
20
  @queue = DRbObject.new_with_uri(@url)
21
- @queue.start_worker(@id)
21
+ @queue.start_worker(@id, Process.pid)
22
22
 
23
23
  begin
24
24
  after_fork
@@ -29,7 +29,7 @@ module ActiveSupport
29
29
  set_process_title("(stopping)")
30
30
 
31
31
  run_cleanup
32
- @queue.stop_worker(@id)
32
+ @queue.stop_worker(@id, Process.pid)
33
33
  end
34
34
  end
35
35
 
@@ -47,8 +47,19 @@ module ActiveSupport
47
47
  end
48
48
 
49
49
  def shutdown
50
+ dead_worker_pids = @worker_pool.filter_map do |pid|
51
+ Process.waitpid(pid, Process::WNOHANG)
52
+ rescue Errno::ECHILD
53
+ pid
54
+ end
55
+ @queue_server.remove_dead_workers(dead_worker_pids)
56
+
50
57
  @queue_server.shutdown
51
- @worker_pool.each { |pid| Process.waitpid pid }
58
+ @worker_pool.each do |pid|
59
+ Process.waitpid(pid)
60
+ rescue Errno::ECHILD
61
+ nil
62
+ end
52
63
  end
53
64
  end
54
65
  end
@@ -74,6 +74,8 @@ module ActiveSupport
74
74
  "decimal" => Proc.new do |number|
75
75
  if String === number
76
76
  number.to_d
77
+ elsif Float === number
78
+ BigDecimal(number, 0)
77
79
  else
78
80
  BigDecimal(number)
79
81
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activesupport
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.3
4
+ version: 8.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -494,10 +494,10 @@ licenses:
494
494
  - MIT
495
495
  metadata:
496
496
  bug_tracker_uri: https://github.com/rails/rails/issues
497
- changelog_uri: https://github.com/rails/rails/blob/v8.0.3/activesupport/CHANGELOG.md
498
- documentation_uri: https://api.rubyonrails.org/v8.0.3/
497
+ changelog_uri: https://github.com/rails/rails/blob/v8.0.4/activesupport/CHANGELOG.md
498
+ documentation_uri: https://api.rubyonrails.org/v8.0.4/
499
499
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
500
- source_code_uri: https://github.com/rails/rails/tree/v8.0.3/activesupport
500
+ source_code_uri: https://github.com/rails/rails/tree/v8.0.4/activesupport
501
501
  rubygems_mfa_required: 'true'
502
502
  rdoc_options:
503
503
  - "--encoding"