Commit Graph

8884 Commits

Author SHA1 Message Date
Xavier Noria fc9a179033 Depends on Zeitwerk 2.5.0.beta2 2021-08-21 01:23:21 +02:00
Xavier Noria 38e82daee8 Delete AS::Dependencies.safe_constantize 2021-08-20 17:51:05 +02:00
Xavier Noria 3e3504bdaa Delete AS::Dependencies.constantize 2021-08-20 09:47:22 +02:00
Xavier Noria d4ab55e901 Delete orphan requires in AS::Dependencies 2021-08-19 00:14:06 +02:00
Xavier Noria c640deef99 Delete AS::Dependencies.explicitly_unloadable_constants 2021-08-18 23:26:29 +02:00
Xavier Noria fb9a33d602 Delete AS::Dependencies.mechanism 2021-08-18 23:26:25 +02:00
Xavier Noria 0f2d2ba87d Delete AS::Dependencies.load? 2021-08-18 23:26:20 +02:00
Xavier Noria ed1571ddc0 Delete AS::Dependencies.autoloadable_module? 2021-08-18 23:26:16 +02:00
Xavier Noria c1a89b57df Delete AS::Dependencies.load_once_path? 2021-08-18 23:26:12 +02:00
Xavier Noria bde4b04323 Delete AS::Dependencies.uninitialized_constant 2021-08-18 23:26:07 +02:00
Xavier Noria bc2cd69c22 Delete AS::Dependencies::WatchStack 2021-08-18 23:26:03 +02:00
Xavier Noria dd5d632a6b Delete AS::Dependencies.constant_watch_stack 2021-08-18 23:25:59 +02:00
Xavier Noria e5cdd54525 Delete AS::Dependencies.will_autoload? 2021-08-18 23:25:54 +02:00
Xavier Noria 2105d1ed3e Delete AS::Dependencies.mark_for_unload 2021-08-18 23:25:49 +02:00
Xavier Noria 7788697797 Delete AS::Dependencies.loading 2021-08-18 23:25:49 +02:00
Xavier Noria 4ba449aafb Delete AS::Dependencies.loaded 2021-08-18 23:25:49 +02:00
Xavier Noria 46576a4555 Delete AS::Dependencies.history 2021-08-18 23:25:49 +02:00
Xavier Noria 5102fdeacf Delete AS::Dependencies.remove_constant 2021-08-18 23:25:49 +02:00
Xavier Noria 2b31655493 Delete AS::Dependencies.new_constants_in 2021-08-18 23:25:49 +02:00
Xavier Noria e24ae73021 Delete AS::Dependencies.qualified_name_for 2021-08-18 23:25:49 +02:00
Xavier Noria 1b92154ff4 Delete AS::Dependencies.autoload_module! 2021-08-18 23:25:49 +02:00
Xavier Noria 7b2223be8b Delete AS::Dependencies.remove_unloadable_constants! 2021-08-18 23:25:49 +02:00
Xavier Noria d3ffcafb14 Delete AS::Dependencies.load_file 2021-08-18 23:25:44 +02:00
Xavier Noria 805067e6d2 Delete AS::Dependencies.loadable_constants_for_path 2021-08-18 23:25:35 +02:00
Xavier Noria 98381b7ba2 Delete AS::Dependencies.require_or_load 2021-08-18 22:44:59 +02:00
Xavier Noria 1343a3a67d Delete AS::Dependencies.load_missing_constant 2021-08-18 22:43:52 +02:00
Xavier Noria 27262897c7 Delete AS::Dependencies::Loadable 2021-08-18 22:31:07 +02:00
Xavier Noria a7a217212b Delete AS::Dependencies::ModuleConstMissing 2021-08-18 22:27:55 +02:00
Xavier Noria 627037fa8b Delete AS::Dependencies.depend_on 2021-08-18 22:24:08 +02:00
Xavier Noria 2306a8e645 Setup the once autoloader on bootstrap 2021-08-17 05:23:51 +02:00
Xavier Noria bbe74a8c97 Delete AS::Dependencies.unhook! 2021-08-17 05:18:22 +02:00
Xavier Noria 2a22b4c53b Delete AS::Dependencies.hook! 2021-08-17 05:18:22 +02:00
Kasper Timm Hansen 0965b67bf7
Merge pull request #42967 from p8/main
Clean up missing dots in changelogs
2021-08-13 02:24:40 +02:00
Ryuta Kamizono ee98178ea5 Fix rubocop offences
https://github.com/rails/rails/runs/3294975031
2021-08-11 13:53:39 +09:00
Xavier Noria 3401139842 Move require_dependencies suite to the one for dependencies
require_dependency has now one single definition, and its implementation
does not depend on Zeitwerk or even applications. It only depends on
having some autoload paths in place.

We can test that in the AS test suite.
2021-08-11 00:12:53 +02:00
Xavier Noria 6983a89c72 Deletes the classic implementation of require_dependency 2021-08-09 17:26:51 +02:00
Xavier Noria 36e716cdc1 Implement support for before_remove_const in zeitwek mode
This needs Zeitwerk 2.5 for the on_unload hook.
2021-08-09 13:15:10 +02:00
Petrik de Heus 6828334555
Add missing dots to changelogs 2021-08-07 18:53:10 +02:00
Ryuta Kamizono 685caef33b Fix "warning: instance variable @parallelized not initialized" 2021-08-07 13:04:31 +09:00
Ryuta Kamizono e0ce6bbd6a Fix kwargs delegation in `PerThreadRegistry#method_missing`
Without this fix, the delegation will raise the ArgumentError:

```
% bin/test -w test/per_thread_registry_test.rb
Running 1 tests in a single process (parallelization threshold is 50)
Run options: --seed 23992

# Running:

E

Error:
PerThreadRegistryTest#test_method_missing_with_kwargs:
ArgumentError: wrong number of arguments (given 1, expected 0; required keyword: x)
    /Users/kamipo/src/github.com/rails/rails/activesupport/test/per_thread_registry_test.rb:9:in `foo'
    /Users/kamipo/src/github.com/rails/rails/activesupport/lib/active_support/per_thread_registry.rb:55:in `foo'
    /Users/kamipo/src/github.com/rails/rails/activesupport/lib/active_support/per_thread_registry.rb:57:in `method_missing'
    /Users/kamipo/src/github.com/rails/rails/activesupport/test/per_thread_registry_test.rb:13:in `test_method_missing_with_kwargs'
```
2021-08-06 18:24:02 +09:00
Ryuta Kamizono 6e7e8128d2 Fix markup in RDoc [ci skip] 2021-08-06 16:24:03 +09:00
Rafael França 207da352dd
Merge pull request #42913 from ghiculescu/deprecation-opt-out
Allow entirely opting out of deprecation warnings
2021-08-05 23:52:41 -04:00
Xavier Noria 6068639775 Upgrades Zeitwerk to 2.5.0.beta 2021-08-04 09:43:06 +02:00
Rafael Mendonça França 18707ab17f
Standardize nodoc comments 2021-07-29 21:18:07 +00:00
Alex Ghiculescu ea3185ebdd Allow entirely opting out of deprecation warnings
Previously if you did `app.config.active_support.deprecation = :silence`, some work would still be done on each call to `ActiveSupport::Deprecation.warn`. Specifically [checking the backtrace](12372c5482/activesupport/lib/active_support/deprecation/reporting.rb (L21)), generating the [deprecation warning](12372c5482/activesupport/lib/active_support/deprecation/reporting.rb (L22)), and [checking if the warning is disallowed](12372c5482/activesupport/lib/active_support/deprecation/reporting.rb (L23)).

In very hot paths, this could cause performance issues. This PR lets you turn off deprecation reporting entirely for a specific environment.

```ruby
config.active_support.report_deprecations = false
```

^ so has the same outcome as:

```ruby
config.active_support.deprecation = :silence
config.active_support.disallowed_deprecation = :silence
```

But it will short circuit [here](12372c5482/activesupport/lib/active_support/deprecation/reporting.rb (L19)).
2021-07-29 16:00:02 -05:00
Rafael França 12372c5482
Merge pull request #42905 from dgorelik/patch-1
s/octopus/cactus
2021-07-29 14:26:10 -04:00
Daniel Gorelik b802b54092
s/octopus/cactus 2021-07-29 08:17:06 -04:00
Jean Boussier 5d1e8884bd Fix MemCacheStore local cache duplication
Followup: https://github.com/rails/rails/pull/42833

The previous fix wasn't working in practice because the LocalCache
middleware doesn't use `with_local_cache` but directly set a
regular `LocalStore` instance in the registry.

So instead we redecorate it on every access. It may cause some extra
allocations, but since it only happens in 6.1 mode, it's not as
much of a concern.
2021-07-29 11:57:59 +02:00
Rafael França 80585daf2d
Merge pull request #42358 from ghiculescu/credentials-backwards-compat
Credentials: support hash style access in more cases
2021-07-28 21:09:43 -04:00
Rafael França 646e9d3d62
Merge pull request #42030 from diegotoral/configurable-default-option
Add support for defining default values as option for ActiveSupport::Configurable accessors
2021-07-28 20:30:21 -04:00
Jean Boussier f7cedc6b43
Merge pull request #42626 from Shopify/as-file-store-remove-local-cache
Remove LocalCache in FileStore
2021-07-28 17:06:56 +02:00
Jean Boussier 8a22369071
Merge pull request #42870 from pedrosnk/pm/import_of_active_support_test_assertions
assert_changes works on including ActiveSupport::Assertions class
2021-07-28 15:59:21 +02:00
Santiago Bartesaghi 92f12d77c4 Fix :nodoc: [ci skip] 2021-07-27 16:52:58 -03:00
Jorge Manrubia a29884d733 Remove mechanism to disable test parallelization when runnin gonly 1 test
#42761 made the old system of disable paralleling testing when
only one test file was included obsolete.
2021-07-27 10:33:09 -07:00
Étienne Barrié 39b382cf78 Remove leak when using CurrentAttributes in thread variables
The test for CurrentAttributes using thread-local variables leaks
an instance in Thread.current.

Usually instances are reset in the test helper but the objects remain:
activesupport/lib/active_support/current_attributes/test_helper.rb:11

In this situation we use clear_all to make sure we don't leave instances
behind when the configuration is changed.
2021-07-27 11:50:37 +02:00
Pedro Medeiros f6ffdcfcff assert_changes works on including Assertions class
assert_not_equal is an alias for refute_equal that is defined only on
the class ActiveSupport::TestCase. This commit ensures
ActiveSupport::Testing::Assertions#assert_changes doesn't depends on
ActiveSupport::TestCase to work.
2021-07-25 14:27:18 -04:00
Dino Maric a6c0e84f02 FIX: Setting remove_deprecated_time_with_zone_name in new framework defaults
Setting `remove_deprecated_time_with_zone_name` didn't work because
the value is checked in a framework initialiser, which runs before application initialiser.

This PR moves the setting inside the `config.after_initialize` block.
I've also added 2 tests for this behaviour.

Fixes #42820
2021-07-24 16:47:49 +02:00
Jean Boussier 5db5de5341
Merge pull request #42845 from jonathanhefner/fix-descendants-garbage-collection-test
Isolate descendants garbage collection test
2021-07-23 18:11:33 +02:00
Ryuta Kamizono 93b16e71f9
Merge pull request #42842 from jonathanhefner/fix-file-update-checker-test-double-waits
Avoid double wait in EventedFileUpdateCheckerTest
2021-07-23 12:34:01 +09:00
Jonathan Hefner 60fc40ea58 Isolate descendants garbage collection test
This prevents the test from being affected by Ruby-internal thread
locals set by other tests.

Example failure: https://buildkite.com/rails/rails/builds/79505#cb261462-8e40-4adc-99fc-81708a473cc6/1076-1085

Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
2021-07-22 14:32:22 -05:00
Jonathan Hefner 86c732a606 Avoid double wait in EventedFileUpdateCheckerTest
Waiting after touching the file system is a concern of
`EventedFileUpdateCheckerTest`.  Therefore, only call `wait` inside
`EventedFileUpdateCheckerTest`.  This avoids calling `wait` an extra
time when calling `touch`.

Before:

    $ bin/test test/evented_file_update_checker_test.rb test/file_update_checker_test.rb

    Finished in 43.357019s, 0.9918 runs/s, 2.5371 assertions/s.
    43 runs, 110 assertions, 0 failures, 0 errors, 0 skips

After:

    $ bin/test test/evented_file_update_checker_test.rb test/file_update_checker_test.rb

    Finished in 34.351007s, 1.2518 runs/s, 3.2022 assertions/s.
    43 runs, 110 assertions, 0 failures, 0 errors, 0 skips
2021-07-22 12:29:27 -05:00
Jean Boussier fcacb93295
Merge pull request #39428 from etiennebarrie/thread-local-current-attributes
Allow using thread variables for CurrentAttributes instances
2021-07-22 16:40:10 +02:00
Jean Boussier 733774f35e MemCacheStore: Properly duplicate local cache values in 6.1 mode
Followup: https://github.com/rails/rails/pull/42649

I found a way to preserve the `deep_dup` behavior in 6.1 mode.
So we no longer need to skip these tests.
2021-07-21 17:55:09 +02:00
Étienne Barrié 8195cd5f99 Allow using thread variables for CurrentAttributes instances 2021-07-21 16:53:32 +02:00
Eugene Kenny 8dab534ca8
Merge pull request #42827 from jdufresne/author-id
Correct Inflector.humanize keep_id_suffix argument docs
2021-07-21 08:56:35 +01:00
Jean Boussier 17db990ed0
Merge pull request #42649 from Shopify/local-cache-refactor
Refactor local cache to avoid serializing entries twice
2021-07-21 08:56:09 +02:00
Jon Dufresne a4a8478801 Correct Inflector.humanize keep_id_suffix argument docs
The "id" word is not capitalized. Observe:

    irb(main):001:0> ActiveSupport::Inflector.humanize('author_id', keep_id_suffix: true)
    => "Author id"
2021-07-20 20:42:27 -07:00
Ryuta Kamizono e50b0e3ab3 Fixup CHANGELOGs [ci skip] 2021-07-21 10:08:08 +09:00
Ryuta Kamizono a206aecedf chore: Use `e.g.` which is the more used spelling
```
% git grep -i '\be\.g\.' | wc -l
290
```
2021-07-21 09:17:54 +09:00
Diego Toral 99525cb6ff ActiveSupport::Configurable default value option
Sometimes it can be very strange or long have to define default values
for config accessors as blocks, specially when config is a simple value
like 1, true, :symbol. This commit adds the ability to specify those
values by just passing a ` default` option when defining the accessor.

It also makes config accessor's interface similar to other Rails
methods like `class_attribute`, which also has the instance_reader,
instance_writer and instance_accessor options.
2021-07-20 10:36:58 -03:00
Jean Boussier 81b70f13ca Refactor local cache to avoid serializing entries repeatedly
Since `LocalCache` store needs to call `dup_value!` on write (to avoid
mutating the original value), we end up serializing each cache entry twice.
Once for the local cache, and a second time for the actual backend. So the
write performance is quite bad.

So the idea here is than rather than to store `Entry` instances, the local
cache now instead store whatever payload was sent to the real backend.

This means that we now only serialize the `Entry` once, and if the cache
store was configured with an optimized coder, it will be used for the local
cache too.

Current Rails `main`:
```
fetch in rails 7.0.0.alpha
                         52.423  (± 1.9%) i/s -    265.000  in   5.058089s
write in rails 7.0.0.alpha
                         12.412  (± 0.0%) i/s -     62.000  in   5.005204s
```

Current Rails `main` with local cache disabled:
```
fetch in rails 7.0.0.alpha
                         52.047  (± 3.8%) i/s -    260.000  in   5.000138s
write in rails 7.0.0.alpha
                         25.513  (± 0.0%) i/s -    128.000  in   5.018942s
```

This branch:
```
fetch in rails 7.0.0.alpha
                         50.259  (± 4.0%) i/s -    255.000  in   5.085783s
write in rails 7.0.0.alpha
                         25.805  (± 0.0%) i/s -    130.000  in   5.039486s
```

So essentially, the local cache overhead on write has been eliminated.

Benchmark:
```
require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"
  gem "rails", github: "rails/rails", branch: "main"
  gem 'benchmark-ips'
  gem "mysql2"
  gem "pry"
end

require "active_record"
require "logger"
require 'benchmark/ips'

ActiveRecord::Base.establish_connection(adapter: "mysql2", database: 'test', host: 'localhost', user: 'root', password: '')
ActiveRecord::Base.logger = Logger.new(nil)

ActiveRecord::Schema.define do
  create_table :users, force: true do |t|
    t.string :name
    t.integer :phone
  end
end

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end

class User < ApplicationRecord
end

1_000.times { |i| User.create(name: "test #{i}") }

cache = ActiveSupport::Cache::FileStore.new(ARGV[0] || '/tmp/rails-cache')
cache.clear
unless ENV['DISABLE_LOCAL_CACHE']
  ActiveSupport::Cache::Strategy::LocalCache::LocalCacheRegistry.set_cache_for(
    cache.middleware.local_cache_key,
    ActiveSupport::Cache::Strategy::LocalCache::LocalStore.new
  )
end

h = {}
h = User.last(Integer(ENV.fetch('SIZE', 1000))).each { |u| h[u.id] = u }

puts "== Benchmarking read_entry code and write_entry code in rails #{Rails.version}"

Benchmark.ips do |x|
  x.report("fetch in rails #{Rails.version}") {
    cache.fetch('key', compress: false) { h }
  }

  x.report("write in rails #{Rails.version}") {
    cache.write("key+#{Time.now}", h, compress: false) { h }
  }
end
```
2021-07-20 12:59:08 +02:00
Eileen M. Uchitelle 4a906cbbbc
Merge pull request #42796 from schneems/schneems/faster-try-yet-again
Fix NilClass#try and NilClass#try! performance slowdown in Ruby 2.7+
2021-07-16 14:51:15 -04:00
Jorge Manrubia 675d9ffb6e
Add an option threshold: to .parallel() setup method (#42789)
This adds an additional method to configure the parallelization
threshold. Before this, the only way of configuring the threshold was
via an option:

```
config.active_support.test_parallelization_minimum_number_of_tests
```
2021-07-16 11:32:23 -07:00
Richard Schneeman bb513b8541 Fix performance slowdown in Ruby 2.7+
In #34068 I introduced code that improved performance in Ruby 2.5. But recently @Jeremyevans pointed out that it made code slower in 2.7+ which Rails targets https://gist.github.com/jeremyevans/40675ac1f69b4ac405d3c6ba060cdd35. Here's the twitter thread https://twitter.com/jeremyevans0/status/1414731600693108737.

This change essentially reverts #34068

```
$ cat scratch.rb
class FooCurrent
  def try(_method_name = nil, *)
    nil
  end
end

class FooUpdated
  def try(*)
    nil
  end
end

require 'benchmark/ips'

foo_updated = FooUpdated.new
foo_current = FooCurrent.new

Benchmark.ips do |x|
  x.report("updated") { foo_updated.try(:anything) }
  x.report("current") { foo_current.try(:anything) }
  x.compare!
end

$ ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin19]
$ ruby scratch.rb
Warming up --------------------------------------
             updated   854.461k i/100ms
             current   687.183k i/100ms
Calculating -------------------------------------
             updated      8.418M (± 2.1%) i/s -     42.723M in   5.077403s
             current      6.619M (± 9.6%) i/s -     32.985M in   5.048477s

Comparison:
             updated:  8418315.3 i/s
             current:  6619074.1 i/s - 1.27x  (± 0.00) slower
```
2021-07-16 11:08:32 -05:00
Akshay Mohite b3aacdc512 Used already defined method parallelized? and fixed semantics of the test name.
- Related to https://github.com/rails/rails/pull/42761
- Used `parallelized?` method instead of calling a method `should_parallelize?` to figure out if parallezation is enabled.
- Fixed semantics of the test name corresponding to the change
- Updated test name as per the code review suggestion.
2021-07-14 22:35:21 +05:30
Eileen M. Uchitelle c18339791f
Merge pull request #42761 from basecamp/smart-parallel-tests
Parallelize tests only when there are enough to justify the parallelization overhead
2021-07-14 10:18:24 -04:00
Jorge Manrubia ecc5afed30 Parallelize tests only when overhead is justified
Parallelizing tests has a cost in terms of database setup and fixture
loading. This change makes Rails disable parallelization when the number
of tests is below a configurable threshold.

When running tests in parallel each process gets its own database
instance. On each execution, each process will update each database
schema (if needed) and load all the fixtures. This can be very expensive
for non trivial datasets.

As an example, for HEY, when running a single file with 18 tests,
running tests in parallel in my box adds an overhead of 13 seconds
versus not parallelizing them. Of course parallelizing is totally worthy
when there are many tests to run, but not when running just a few tests.

The threshold is configurable via
config.active_support.test_parallelization_minimum_number_of_tests,
which is 30 50 by default.

This also adds some tracing to know how tests are being executed:

When in parallel:

```
Running 2829 tests in parallel in 8 processes
```

When not in parallel:

```
Running 15 tests in a single process (parallelization threshold is 30)
```
2021-07-14 13:36:28 +02:00
John Hawthorn 2379bc5d2a Avoid using class var in LoggerThreadSafeLevel
Class variables are confusing and can be slow. In this case we were just
using the class variable as a global to implement Fiber-local variables
on top of. Instead we can use Thread#[] directly to store our Fiber-locals.
2021-07-12 10:18:02 -07:00
Alex Ghiculescu 4b42beb3b8 Log a warning when assertions are incorrectly nested and errors are raised
Follow up to https://github.com/rails/rails/pull/37313

- Adds regression tests
- Logs a warning in cases where assertions are nested in a way that's likely to be confusing
2021-07-12 10:37:43 -05:00
Ryuta Kamizono db767c332a Fix CI failure caused by error_highlight gem
Since https://github.com/ruby/ruby/pull/4586, error.message includes the
line of code that raised.

https://bugs.ruby-lang.org/issues/17930
2021-07-02 17:44:10 +09:00
Yasuo Honda 08299d1ba4 Address `NameError: uninitialized constant Digest::UUID::OpenSSL`
Follow up #41722

This commit addresses these Active Support test errors.

```ruby
% ruby -v
ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-darwin21]
% cd activesupport
% bundle exec ruby -w test/core_ext/digest/uuid_test.rb
Run options: --seed 50574

E

Error:
DigestUUIDExt#test_v3_uuids:
NameError: uninitialized constant Digest::UUID::OpenSSL
    /Users/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/core_ext/digest/uuid.rb:40:in `uuid_v3'
    test/core_ext/digest/uuid_test.rb:8:in `test_v3_uuids'

rails test test/core_ext/digest/uuid_test.rb:7

F

Failure:
DigestUUIDExt#test_invalid_hash_class [test/core_ext/digest/uuid_test.rb:22]:
[ArgumentError] exception expected, not
Class: <NameError>
Message: <"uninitialized constant DigestUUIDExt::OpenSSL">
---Backtrace---
test/core_ext/digest/uuid_test.rb:23:in `block in test_invalid_hash_class'
---------------

rails test test/core_ext/digest/uuid_test.rb:21

E

Error:
DigestUUIDExt#test_v5_uuids:
NameError: uninitialized constant Digest::UUID::OpenSSL
    /Users/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/core_ext/digest/uuid.rb:45:in `uuid_v5'
    test/core_ext/digest/uuid_test.rb:15:in `test_v5_uuids'

rails test test/core_ext/digest/uuid_test.rb:14

Finished in 0.006611s, 453.7891 runs/s, 151.2630 assertions/s.
3 runs, 1 assertions, 1 failures, 2 errors, 0 skips
%
```
2021-07-02 10:06:42 +09:00
Dirkjan Bussink 0523532a3c
Always use OpenSSL constants for Digest operations
As also previously discussed in
https://github.com/rails/rails/pull/40770#issuecomment-748347066, this
moves the usage of Digest constants to always use the OpenSSL version of
those Digest implementations.
2021-06-30 13:57:54 +02:00
Steve Laing 21ca4a49ac Add support for ordinal date values in AS::TimeZone.iso8601
Date._iso8601 will attempt to parse certain args as ordinal dates eg. '21087' => 2021-03-28. Add ActiveSupport::TimeZone.iso8601 support for these
ordinal values to be consistent with Date._iso8601 and raise ArgumentError where the day of year is invalid.
2021-06-28 18:00:51 +01:00
Jean Boussier a2148b9d0a Remove LocalCache in FileStore 2021-06-28 15:22:07 +02:00
Alex Ghiculescu d132095ce7 `Time#change` should pass the `zone` property through if it's set 2021-06-25 11:49:54 -05:00
Jean Boussier 99913f6a5e Report async queries lock wait duration
This duration is very important to figure wether the `load_async`
actually improved something.
2021-06-25 13:59:47 +02:00
Guillermo Iguaran acee501edd
Merge pull request #42532 from zzak/zzak/35035
Allow any module or class to be converted to JSON in a simple way
2021-06-23 22:47:04 -07:00
Mike Dalessio 8489a5e114
Fix number_to_currency to use negative format when rounding 0.5
Previously this function would fail to apply the negative format
correctly if the value being rounded was 0.5 exactly (modulo
precision).

This fixes the logic to use `>= 0.5` instead of `> 0.5`
2021-06-23 12:55:16 -04:00
Mike Dalessio 9a05443d1e
Fix number_to_currency to avoid negative format when displaying zero.
This is a more-complete version of the fix in #37865 which originally
addressed #37846.

Also see context at #39350 with respect to alternate input formats.

Closes #42577
2021-06-23 12:54:44 -04:00
Alex Ghiculescu 25b47c25ba Optimized Cache::Entry should support old dalli_store values
Same bug as https://github.com/rails/rails/pull/42559, but a very different fix due to https://github.com/rails/rails/pull/42025. To recap, the issue:

- While using the `dalli_store`, you set any value in the Rails cache with no expiry.
- You change to the `mem_cache_store`.
- You upgrade to Rails 7.
- You try to read the same cache key you set in step 1, and it crashes on read.

https://github.com/rails/rails/pull/42025 was backward compatible with entries written using the `mem_cache_store`, but *not* the `dalli_store` which did not use `ActiveSupport::Cache::Entry`. This PR attempts to fix that.
2021-06-22 15:17:33 -05:00
Alex Ghiculescu 9a87546bd3 Test cleanup for cache store tests 2021-06-22 13:48:06 -05:00
Zachary Scott f186a00aac Add CHANGELOG for #42532 2021-06-18 20:54:43 +09:00
Tyler Rick cb40ae38c1 Allow any module or class to be converted to JSON in a simple way 2021-06-18 14:06:50 +09:00
Oli Peate a8ae85a331 Support clearing acronyms in ActiveSupport::Inflector::Inflections
Previously calling ActiveSupport::Inflector::Inflections.clear(:acronyms)
reset the instance variable to an empty Array, which is not the correct
default. The next time an acronym is added a TypeError is thrown.
2021-06-15 10:22:19 +01:00
sho shimohata 443169784d add space 2021-06-15 12:55:20 +09:00
Rafael França 0bd2bd3d71
Merge pull request #42405 from c960657/time-travel
Allow travel/travel_to blocks after standalone travel/travel_to
2021-06-08 18:49:41 -04:00
Christian Schmidt 7e6dd6b21f Travel back after block 2021-06-08 16:54:42 +02:00
Jean Boussier 517a2803f4 Improve `AS::TimeWithZone` error message on `NoMethodError`
Because we re-use the message generated by the `Time` instance
it causes `TimeWithZone` to still pretend being a `Time` instance
even with `remove_deprecated_time_with_zone_name = true` which is
confusing.
2021-06-08 10:03:34 +02:00
Rafael França 5c09cfd96f
Merge pull request #42370 from sunny/better-error-message-when-encrypted-file-key-is-blank
Raise missing key error when master key env variable is blank
2021-06-07 16:59:35 -04:00
Christian Schmidt a829bb7639 Allow travel blocks after standalone travelt 2021-06-05 15:58:41 +02:00
Sunny Ripert afdc2af9e2 Raise missing key error when master key env var is blank 2021-06-03 16:21:53 +02:00
Alex Ghiculescu c87e16bf0e Credentials: support hash style access in more cases
Fixes https://github.com/rails/rails/issues/42351

https://github.com/rails/rails/pull/42106 broke if you wanted to treat a set of nested credentials as a hash. This PR fixes it.
2021-06-02 10:34:22 -05:00
Adam Hess 6489ee522a Always use %f formatter for ISO8601 durations since they can't be in scientific notation
Manually formats the seconds. This avoids using the %g formatter which can convert large numbers or very small fractions into scientific notation which is not supported by iso8601
2021-06-02 07:09:16 -07:00
Zachary Scott bfdb634034 NumberToRoundedConverter should handle -Float::INFINITY
cc https://github.com/rails/rails/pull/42316#issuecomment-851606043
2021-06-01 16:08:21 +09:00
Petrik 99fd13d967 Fix typo in ActionableError [skip ci]
"let's" is short for "let us".
2021-05-31 20:44:00 +02:00
Andrew White 2af84159e8
Merge pull request #42316 from federicoaldunate/fix_decimal_to_float_converter 2021-05-31 12:07:29 +01:00
Federico Aldunate bd6277d568 Use BigDecimal compatible operation in NumberToRoundedConverter 2021-05-30 10:29:09 -03:00
Santiago Bartesaghi d49724c496 Minor docs style fix [ci skip] 2021-05-26 17:16:26 -03:00
Eugene Kenny 42a71d1428
Merge pull request #42277 from georgeclaghorn/assert-no-changes-from
Add from: option to ActiveSupport::TestCase#assert_no_changes
2021-05-24 21:25:57 +01:00
Maxime Garcia a69e725124
Minor: Typo in ActiveSupport::SecureCompareRotator doc 2021-05-24 15:02:27 +02:00
George Claghorn 21aea0db55 Add from: option to ActiveSupport::TestCase#assert_no_changes
Permit asserting on the initial value that is expected not to change.
2021-05-23 16:26:52 -04:00
Jean Boussier 1e56b1d115 Fix ruby-master test suite (Psych 4.0.0)
Ruby master ships with Psych 4.0.0 which makes `YAML.load`
defaults to safe mode (https://github.com/ruby/psych/pull/487).

However since these YAML files are trustworthy sources
we can parse them with `unsafe_load`.
2021-05-19 14:21:21 +02:00
Jean Boussier 22737122a2 Fix compatibility with Psych 4
Psych 4 load in safe mode by default:
https://github.com/ruby/psych/pull/487

So aliases need to be explicitly allowed.
2021-05-18 10:03:42 +02:00
Michael Lutaaya eb43eb689c
[ci skip] Fix typo in MessageVerifier docs 2021-05-14 07:10:29 -04:00
jithindasad 153f4fe284 update tests for SecureRandom.base58 method 2021-05-12 01:05:22 +05:30
Ryuta Kamizono 908ccc194e
Merge pull request #42173 from okuramasafumi/improve-docs-of-activesupport-callbacks
[ci-skip] Improve doc for `ActiveSupport::Callbacks.skip_callback`
2021-05-08 18:39:29 +09:00
Andrew White 1fd8a3f6db
Merge pull request #42080 from alberto-mota/remove_sum
Deprecates `Enumerable#sum` and `Array#sum`
2021-05-08 10:16:13 +01:00
OKURA Masafumi abd4027e10 [ci-skip] Improve doc for ActiveSupport::Callbacks.skip_callback
Reuse class previously defined in the same file to make it easy
to see the change of the output.
Also add the example not to skip callback with if option.
2021-05-08 18:11:53 +09:00
OKURA Masafumi 3b3a43eb09 Add missing require to active_support/callbacks.rb
At line 353, `blank?` method is called.
We need to `require "active_support/core_ext/object/blank"`
for `blank?` to be available.
2021-05-08 13:42:23 +09:00
Jean Boussier fdb5c0463b Special case SafeBuffer#concat(nil) to avoid the bulk of deprecations
After trying out https://github.com/rails/rails/pull/42123
it appears that the bulk of the deprecations are for cases such as:

```ruby
output << some_helper
```

Where `some_helper` happens to sometime return `nil`.

While a regular String would indeed raise a `TypeError`
on such case, I wonder if it wouldn't be worth to special
case this specific scenario as it is quite harmless and would
drastically reduce the amount of deprecated code.
2021-05-06 10:49:21 +02:00
John Bampton 6e85b6b86e Add spell checking with codespell as a GitHub Action
`codespell` works with a small custom dictionary and seems to find perhaps more spelling mistakes than `misspell` which really only fixes commonly misspelled English words.

Not all spell checkers can check all file types and most spell checkers can't find all the errors.

https://github.com/codespell-project/codespell
https://pypi.org/project/codespell/
2021-05-04 14:46:21 +10:00
Alberto Mota afa83350de Deprecates `Enumerable#sum` and `Array#sum`
Ruby (2.4+) includes a native implementation of `sum` with significant
performance gains. Rails 7.1 will be removing `Enumerable#sum` and
`Array#sum` in favor of Ruby's native implementation.

This commit adds a deprecation warning to calls with non-numeric
arguments without a suitable initial argument as those will be required
once Rails removes this functionality.

Some examples that will now trigger a deprecation warning:
    >> %w[foo bar].sum
    >> [[1, 2], [3, 4, 5]].sum

To avoid the deprecation warning they should now invoked as follows:
    >> %w[foo bar].sum('')
    >> [[1, 2], [3, 4, 5]].sum([])

In order to prepare for the deprecation on Rails 7.1, it also
deprecates `[nil].sum == 0`, which in Ruby's native implementation
throws a `TypeError`.
2021-05-03 10:26:39 -07:00
Jean Boussier e12b8d8130
Merge pull request #42123 from Shopify/safe-buffer-implicit-casting
Stop implicitly coercing objects to string in Safebuffer
2021-05-03 14:33:27 +02:00
Jean Boussier 147f207a57 Deprecate implicitly coercing objects to string in ActiveSupport::SafeBuffer 2021-05-03 14:16:03 +02:00
Ryuta Kamizono 917e81a808 Fix and improve the method signature for `try` and `try!`
Expand `try(*a, &b)` to `try(*args, &block)`, and fix invalid `a*`.
2021-05-03 03:31:27 +09:00
Jonathan Hefner d5bb6f4e34
Merge pull request #42111 from rthbound/correction_in_docs_for_to_sentence_method
Corrects #to_sentence documentation for :words_connector [ci-skip]
2021-04-30 12:24:01 -05:00
Ryan T. Hosford e442489cf6 Correction to docs for #to_sentence, :words_connector 2021-04-30 11:33:02 -05:00
Alex Ghiculescu 94d1d52c03 Allow access to nested secrets by method calls
In a new Rails app, the generated credentials file contains an example of some [nested secrets](f95c0b7e96/railties/lib/rails/generators/rails/credentials/credentials_generator.rb (L46)).

Currently you can't access them nicely the way you would top level secrets:

```
2.7.3 :001 > Rails.application.credentials.aws
 => {:access_key_id=>123, :secret_access_key=>345}
2.7.3 :002 > Rails.application.credentials.aws.access_key_id
Traceback (most recent call last):
        1: from (irb):2
NoMethodError (undefined method `access_key_id' for {:access_key_id=>123, :secret_access_key=>345}:Hash)
2.7.3 :003 > Rails.application.credentials.secret_key_base
 => "abcd..."
```

It would make secrets easier to use if you could, so this PR adds support for that. `Rails.application.credentials.aws.access_key_id` will now return `123` in the above example.
2021-04-29 14:30:43 -05:00
Jean Boussier fbf3bf8cac Document the new Active Support cache format 2021-04-26 11:20:59 +02:00
Jean Boussier 3b71f3eb68 Implement an optimized Cache::Entry coder
Active Support's cache have for long been limited because
of its format. It directly serialize its `Entry` object with
`Marshal`, so any internal change might break the format.

The current shortcommings are:

  - The minimum entry overhead is quite ridiculous:
    `Marshal.dump(ActiveSupport::Cache::Entry.new("")).bytesize # => 107`
  - Only the internal `value` is compressed, but unless it's a String, to do so
    it first need to be serialized. So we end up with `Marshal.dump(Zlib.deflate(Marshal.dump(value)))`
    which is wasteful.
2021-04-25 08:27:58 +02:00
Ryuta Kamizono bbbc861f71 Enable `Performance/MapCompact` cop
Follow up to #42053.
2021-04-23 16:33:02 +09:00
Jean Boussier 738ca3595f Eagerly close Dalli connections in MemCachedStoreTest
Otherwise the test suite is flaky when ran repeatedly
on the same machine because of file descriptors exhaustion.
2021-04-22 15:32:22 +02:00
Jean Boussier 6e9f9b46b9 Get rid of another SecureRandom.hex in MemCachedStoreTest
This random value doesn't need to be "secure", and calling
SecureRandom so much cause /dev/urandom exhaustion on macOS
2021-04-22 15:15:57 +02:00
Jean Boussier a0e4920296 Refactor Cache::Entry compression handling
Rather than immediately compressing the cache value
in the constructor, this operation is delayed until
we need to serialize the entry.
2021-04-22 13:46:46 +02:00
Jean Boussier 18313071fa Stop internationalizing Duration#inspect
This can cause infinite recursions if you do have a
complex i18n backend that calls `Duration#inspect`.

There is not really any point making `inspect` internationalized
anyway, as most apps will have `:en` as default locale.
2021-04-21 21:44:44 +02:00
Jean Boussier 5649be94ff Replace SecureRandom.random_bytes by Random.bytes in cache store tests
It cause cause /dev/urandom exhaustion on some systems (mostly macOS).
2021-04-21 15:46:38 +02:00
Jean Boussier 84ba451520
Merge pull request #42014 from Shopify/local-cache-rafactor-take-2
Refactor LocalCache to avoid calling Marshal.dump as much
2021-04-20 19:58:46 +02:00
Eileen M. Uchitelle 153a19f07a
Merge pull request #41897 from ricardotk002/allow-parallel-tests-to-fail-fast
Allow test parallelization with processes to fail fast
2021-04-20 12:17:13 -04:00
Asherah Connor 2e14c53fc6
Add `Enumerable#sole` (#40914)
* Add `Enumerable#sole`, from `ActiveRecord::FinderMethods#sole`

* distinguish single-item Enumerable and two-item with nil last

Add a test for same.

* add symmetry, against rubocop's wishes
2021-04-19 11:26:34 +02:00
Jean Boussier 7ce660cf85 Refactor LocalCache to avoid calling Marshal.dump as much (take 2)
The local cache need to protect against mutations of both
the initial received value, and the value returned.

See:

  - https://github.com/rails/rails/pull/36656
  - https://github.com/rails/rails/pull/37587

Because of this, the overhead of the local cache end up being
quite significant. On a single read, the value will be deep duped
twice. So unless the value is one of the type benefiting from a
fast path, we'll have to do two `Marshal.load(Marshal.dump(value))`
roundtrips, which for large values can be very expensive.

By using a specialized `LocalEntry` type instead, we can store
the `Marshal` payload rather than the original value. This way
the overhead is reduced to a single `Marshal.dump` on writes
and a single `Marshal.load` on reads.
2021-04-19 10:22:48 +02:00
Ricardo Díaz cbec080dc4 Allow test parallelization with processes to fail fast
Running tests in parallel with processes wasn't failing fast when the
option was enabled. The problem was that even when the reporter raised
the `Interrupt` exception, the queue was not emptied, so workers keep
processing jobs as if nothing happened.

This patch basically intercepts the `Interrupt` exception that may
come from the reporter, and tells the server to clear the jobs queue,
so that it can continue the shutdown process as usual. The exception
must then continue its journey so that the backtrace is displayed.
2021-04-16 19:23:57 -05:00
Zachary Scott 43e29f0f5d
Merge pull request #41945 from jbampton/fix-grammar
chore: fix grammar, spelling and minor whitespace fix
2021-04-14 09:19:15 +09:00
Rafael Mendonça França 94b954576a
Autocorrect Rubocop roles 2021-04-13 18:32:25 +00:00
Andrew White b259fbcf09
Merge pull request #41957 from rails/simplify-find-timezone
Simplify Time.find_timezone! logic
2021-04-13 19:13:31 +01:00
Jean Boussier c1501e04d0 Add a test case for race_condition_ttl with local_cache enabled 2021-04-13 18:07:12 +02:00
Jean byroot Boussier 62eb0b9c57
Revert "Refactor LocalCache to avoid calling Marshal.dump as much" 2021-04-13 18:03:51 +02:00
Andrew White f6893cd242
Simplify Time.find_timezone! logic
By pushing the checks for TZInfo::Timezone and ActiveSupport::TimeZone
down into the case statement inside the `[]` method we can radically
simplify the logic inside of the `find_timezone!` method.

There's an edge case where passing an invalid argument to `[]` via the
`find_timezone!` method generates a slightly different message for the
`ArgumentError` exception and this is maintained in the unlikely case
someone was relying on the difference.
2021-04-13 16:25:58 +01:00
Ryuta Kamizono a295612ebf
Merge pull request #41942 from caffkane/as-twz-dep-warn-correction
Correct misspelling in as-twz-deprecation message
2021-04-13 22:26:09 +09:00
John Bampton 54e526e473 chore: fix grammar, spelling and minor whitespace fix 2021-04-13 21:35:50 +10:00
Jean Boussier 8d34f769ce Revert "Merge pull request #41931 from MarcelEeken/deep-merge-changing-original-hash"
This reverts commit 483d36ae09, reversing
changes made to b171b842da.
2021-04-13 12:12:03 +02:00
Andrew White 06b294a24c
Freeze ActiveSupport::Duration#parts hash
Durations are meant to be value objects and should not be mutated.
2021-04-13 09:22:42 +01:00
Andrew White 697edcb30f
Fix ActiveSupport::TimeZone#utc_to_local
When utc_to_local_returns_utc_offset_times is false and the time
instance had fractional seconds the new UTC time instance was out
by a factor of 1,000,000 as the Time.utc constructor takes a usec
value and not a fractional second value.
2021-04-13 08:58:35 +01:00
Logan Kane 1b01e47e0d Correct misspelling in as-twz-deprecation message 2021-04-12 21:08:02 -07:00
Jean Boussier 93e5388653 Restore the Entry#bytesize comments removed in #41882 2021-04-12 23:15:02 +02:00
Rafael França 8210d0a9d8
Merge pull request #41938 from Shopify/as-twz-name-deprecation
Allow to opt-in to the new TimeWithZone.name and fix XmlMini serialization
2021-04-12 16:26:39 -04:00
Jean Boussier 3457a4676d Allow to opt-in to the new TimeWithZone.name and fix XmlMini serialization 2021-04-12 22:03:31 +02:00
Rafael França 483d36ae09
Merge pull request #41931 from MarcelEeken/deep-merge-changing-original-hash
Deep duplicate in `deep_merge` so no references remain to the original hash in the result
2021-04-12 15:53:35 -04:00
Rafael Mendonça França 4354e3ae49
Don't define methods using the method modifier in the same line as the method
Our style guide use block method modifiers, not inline method modifiers.
2021-04-12 18:49:54 +00:00
Marcel Eeken 71ab41a099
Deep duplicate in `deep_merge` so no references remain to the original hash in the result
When deep merging a Hash, first a duplicate is created. The duplicate only
does a shallow copy, so deeper level structures are not duplicated but
remain references.

This can lead to unexpected modifications of the original hash when a deeply
nested hash is merged with another hash, and the newly returned hash gets modified.
```
  x = { a: { b: "foo" } }
  y = { d: { e: "bar" } }

  z = x.deep_merge(y)
  # z => { a: { b: "foo" }, d: { e: "bar" } }

  z[:a][:b] = "baz"
  # z => { a: { b: "baz" }, d: { e: "bar" } }
  # x => { a: { b: "baz" } }
```
2021-04-12 15:03:32 +02:00
John Bampton 13b1d9dc35 chore: fix grammar and spelling 2021-04-12 05:30:44 +10:00
Jean Boussier 3f59640016 Stop checking if ruby2_keywords is defined 2021-04-11 13:42:02 +02:00
Jean Boussier 466a54f766
Merge pull request #41882 from Shopify/local-store-dup-value
Refactor LocalCache to avoid calling Marshal.dump as much
2021-04-10 20:33:07 +02:00
Jean Boussier 084ba0ead0 Refactor LocalCache to avoid calling Marshal.dump as much 2021-04-08 18:06:24 +02:00
Jean Boussier bade613012 Make sure Inflector.underscore returns a String
If you were to pass it an underscore symbol, it
would be immediately returned without modification.
2021-04-08 16:26:45 +02:00
Andrew White 3dd0af563b
Merge pull request #41873 from rails/prevent-deprecation-warning-with-yaml-twz
Use YAML.load_tags/dump_tags to prevent deprecation warnings
2021-04-08 12:04:26 +01:00
Jean Boussier 7057ccf656 Directly delegate `constantize` to `Object.const_get`
All the complexity of that method was to work around various
problems caused by Ruby's constant lookup semantic as well
as the classic autoloader shortcommings.

Now that Rails require Ruby 2.7 I don't think we need anything
more than just `Object.const_get`.

```ruby
require 'benchmark/ips'
require 'active_support/all'

module Foo
  module Bar
    module Baz
    end
  end
end

def patched_constantize(name)
  Object.const_get(name)
end

Benchmark.ips do |x|
  x.report('orig') { ActiveSupport::Inflector.constantize("Foo::Bar::Baz") }
  x.report('patched') { patched_constantize("Foo::Bar::Baz") }
  x.compare!
end
```

```
Warming up --------------------------------------
                orig    69.668k i/100ms
             patched   391.385k i/100ms
Calculating -------------------------------------
                orig    705.027k (± 1.9%) i/s -      3.553M in   5.041486s
             patched      3.935M (± 1.1%) i/s -     19.961M in   5.072912s

Comparison:
             patched:  3935235.5 i/s
                orig:   705027.2 i/s - 5.58x  (± 0.00) slower
```
2021-04-08 09:58:52 +02:00
Andrew White db9ba18659
Use YAML.load_tags/dump_tags to prevent deprecation warnings
The default behavior of the Psych gem for Ruby classes is to call the
`name` method to generate a tag for encoding. However this causes a
stream of deprecation warnings whenever ActiveSupport::TimeWithZone
instances are encoded into YAML. By utilising the load_tags/dump_tags
configuration we can prevent Psych from calling the `name` method and
thereby prevent the triggering of the deprecation warnings.
2021-04-07 23:31:09 +01:00
Jean Boussier fe8f47b425
Merge pull request #41831 from Shopify/as-cache-clock-gettime
Allow to set cache expiry as an absolute timestamp
2021-04-07 09:10:02 +02:00
Xavier Noria 27624077e6 Delete orphan autoloading fixtures
Rails now delegates autoloading to Zeitwerk, and therefore does not need to test
autoloading itself. Zeitwerk has test coverage, in Rails we only need to test
the integration.

We are gradually trimming AS::Dependencies, and the AS test suite. With the
removal of DependenciesTestHelpers and client code in af27a25, these fixtures
became orphan.

Three of them are left. They are to be autoloaded with Module#autoload because
they raise errors when the file is evaluated. Their current use cases are
already committed.
2021-04-06 20:14:10 +02:00
Jean Boussier 9de17ac4a4 Allow to set cache expiry as an absolute timestamp
Sometime it can be useful to set a cache entry expiry
not relative to current time, but as an absolute timestamps,
e.g.:

  - If you want to cache an API token that was provided to
    you with a precise expiry time.
  - If you want to cache something until a precise cutoff
    time, e.g. `expires_at: Time.now.at_end_of_hour`

This leaves the `@created_at` variable in a weird state,
but this is to avoid breaking the binary format.
2021-04-06 10:49:05 +02:00
Andrew White 3f4b41a6f5
Deprecate ActiveSupport::TimeWithZone.name
In c00f2d2 the `name` method was overridden to return 'Time' instead of
the real class name 'ActiveSupport::TimeWithZone'. The reasoning for
this is unclear and it can cause confusion for developers assuming that
name is returning the real class name. Since we don't know why this
was added, we're deprecating the method first to give developers a
chance to provide us with feedback and look to fix any issues that arise.
2021-04-04 16:57:51 +01:00
Xavier Noria af27a25f19 Remove DependenciesTestHelpers 2021-04-03 19:24:12 +02:00
Xavier Noria 5f70349b05 Remove with_autoloading_fixtures from the AS::Testing::ConstantLookup test suite
The rewritten test is not super clean with the manual cleanup etc.. If this is a
one-off it's not a big deal. However, if in subsequent rewrites I spot more
occurrences of this pattern, then I'll refactor.
2021-04-03 19:24:12 +02:00
Tietew 92b8cda4c9
secure_compare: Check byte size instead of length
Match fixed_length_secure_compare's guard clause.

References #39142.
2021-04-02 12:45:29 -04:00
Lee Quarella 65f350166a Remove overwriting test_order
Reverts a change from
2327ebfdc6
which can overwrite `test_order` that may have been manually set in
config. This can cause a situation where the user is depending on a
particular `test_order` but is unknowingly forced into another.
2021-03-31 11:50:08 -04:00
Jean Boussier d612542336
Merge pull request #41801 from Shopify/optimize-numeric-to-s
Optimize ActiveSupport::NumericWithFormat#to_s
2021-03-31 09:22:43 +02:00
Jean Boussier 31c20e248a Optimize ActiveSupport::NumericWithFormat#to_s
`case format when nil` is very efficient because it end up calling `NilClass === nil`
which pretty much translates to `nil.is_a?(NilClass)`.

On the other hand `format.nil?` benefit from a dedicated op code, so it's quite faster.

In this case `Integer#to_s` is much more often called without any arguments,
so it's worth optimizing for the most common case.

```ruby
class Integer
  alias_method :faster_to_s, :to_s
end
require 'active_support/all'
require 'benchmark/ips'

module FasterNumericWithFormat
  def faster_to_s(format = nil, options = nil)
    if format.nil?
      return super()
    end

    case format
    when Integer, String
      super(format)
    when :phone
      ActiveSupport::NumberHelper.number_to_phone(self, options || {})
    when :currency
      ActiveSupport::NumberHelper.number_to_currency(self, options || {})
    when :percentage
      ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
    when :delimited
      ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
    when :rounded
      ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
    when :human
      ActiveSupport::NumberHelper.number_to_human(self, options || {})
    when :human_size
      ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
    when Symbol
      super()
    else
      super(format)
    end
  end
end

Integer.prepend(FasterNumericWithFormat)

Benchmark.ips do |x|
  x.report('orig no-arg') { 42.to_s }
  x.report('fast no-arg') { 42.faster_to_s }
  x.compare!
end

Benchmark.ips do |x|
  x.report('orig :human') { 42.to_s(:human) }
  x.report('fast :human') { 42.faster_to_s(:human) }
  x.compare!
end
```

Ruby 2.7.2
```
Warming up --------------------------------------
         orig no-arg   567.569k i/100ms
         fast no-arg   692.636k i/100ms
Calculating -------------------------------------
         orig no-arg      5.709M (± 1.3%) i/s -     28.946M in   5.070660s
         fast no-arg      6.892M (± 0.7%) i/s -     34.632M in   5.024961s

Comparison:
         fast no-arg:  6892287.7 i/s
         orig no-arg:  5709450.0 i/s - 1.21x  (± 0.00) slower

Warming up --------------------------------------
         orig :human   575.000  i/100ms
         fast :human   619.000  i/100ms
Calculating -------------------------------------
         orig :human      6.176k (± 1.6%) i/s -     31.050k in   5.028656s
         fast :human      6.179k (± 1.8%) i/s -     30.950k in   5.010372s

Comparison:
         fast :human:     6179.1 i/s
         orig :human:     6176.3 i/s - same-ish: difference falls within error

```
2021-03-30 15:41:20 +02:00
John Hawthorn 3a770b2197 Fix LogSubscriber for buffered event w/ nil logger
LogSubscriber overrides start/finish to avoid instrumenting when its
logger is nil. In order to support buffered notification events, as used
by async queries, we need to apply a similar override to
LogSubscriber#publish_event.
2021-03-29 17:31:07 -07:00
Steve Laing d4186a76c8 Raise ArgumentError from TimeZone.iso8601 when invalid value can be parsed by Date._iso8601
Date._iso8601 will return a hash for some values eg. '12936' but this will not contain the expected :mon and :mday keys.
Check for these keys and raise an ArgumentError if they aren't present as this is consistent with other invalid input behaviour.
2021-03-26 09:10:45 +00:00
Eileen M. Uchitelle ad9e52066c
Merge pull request #41684 from ricardotk002/disable-parallel-testing
Disable parallel testing when running individual files
2021-03-23 09:06:57 -04:00
Jean Boussier a40fca290d Use triple-dot delegation in ForkTracker 2021-03-23 08:52:29 +01:00
Ryuta Kamizono 19fd39b672 `to_yaml` requires `require "yaml"`
https://buildkite.com/rails/rails/builds/75966#6b542bd0-82ce-4463-badf-7a68af7d3208/1055-1977
2021-03-23 08:51:39 +09:00
Ryuta Kamizono 3e71243b10 Parsing `type="yaml"` node requires `require "yaml"` 2021-03-23 08:45:46 +09:00
Ryuta Kamizono d7f5f4f97f Fix `test_from_trusted_xml_allows_symbol_and_yaml_types` failure
Caused by #41712.

https://buildkite.com/rails/rails/builds/75962#984c08aa-f57f-4f1c-ab31-7674fac12bbe/975-1397
2021-03-23 08:29:09 +09:00
Rafael Mendonça França 741099e995
Really make OrderedHash private to the framework
Related to 0dd7654032.
2021-03-22 22:13:23 +00:00
Ryuta Kamizono 1ef30c19b5
Merge pull request #41712 from okuramasafumi/remove-ordered-hash
Remove requires and references to OrderedHash
2021-03-22 22:01:26 +09:00
OKURA Masafumi 0dd7654032 Remove some references to OrderedHash
OrderedHash is deprecated but there are some requires and references
to OrderedHash, which might be confusing.
As described in
https://github.com/rails/rails/issues/22681#issuecomment-166059717
OrderedHash is internal only so references in the docs should be
removed.
2021-03-22 21:14:32 +09:00
Ryuta Kamizono 8c7883d3fc ✂️ [ci skip] 2021-03-22 04:46:11 +09:00
Ryuta Kamizono 1dcad65f80
Merge pull request #41707 from okuramasafumi/add-missing-require-to-hash_with_indifferent_access
Add missing require to hash_with_indifferent_access
2021-03-21 15:19:44 +09:00
OKURA Masafumi 8a56380c53
Add documentation to HashWithIndifferentAccess#except
https://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html#method-i-except
Currently HashWithIndifferentAccess#except has no documentation.
Since it's behavior is different from Hash#except, so it deserves
its own documentation.
2021-03-20 10:37:13 -04:00
OKURA Masafumi e4de1ca9b5 Add missing require to hash_with_indifferent_access
When requiring only "active_support/hash_with_indifferent_access",
calling `slice!` method on `HashWithIndifferentAccess` object
causes `NoMethodError`.
This is caused by `slice!` method calls `super` which is defined
in "active_support/core_ext/hash/slice" that' not required by this file.
Adding `require "active_support/core_ext/hash/slice"` to hwia
resolves this issue.

Note: since all tests `require_relative "abstract_unit"` that requires
"active_support/core_ext/hash/slice" eventually, it's pretty hard to
test method behavior without require.
2021-03-20 22:10:38 +09:00
Xavier Noria 6d38553b09 Removes the monkey-patch for Marshal.load
Marshal.load autoloads out of the box with Zeitwerk. See

    https://github.com/fxn/zeitwerk/blob/master/test/lib/zeitwerk/test_marshal.rb

for similar coverage.
2021-03-18 22:08:25 +01:00
Ricardo Díaz 2327ebfdc6 Disable parallel testing when running individual files
Setting up the parallel workers could be an overhead when running
individual files.

This patch disables that process in case the number of files to run
is less than one.

Results running a sample file:

Before:

```
actionpack $ bin/test test/controller/parameters/accessors_test.rb
Run options: --seed 48261

........................................................................

Finished in 0.211923s, 339.7460 runs/s, 552.0873 assertions/s.
72 runs, 117 assertions, 0 failures, 0 errors, 0 skips
```

After

```
actionpack $ bin/test test/controller/parameters/accessors_test.rb

Run options: --seed 5461

........................................................................

Finished in 0.008411s, 8560.2189 runs/s, 13910.3557 assertions/s.
72 runs, 117 assertions, 0 failures, 0 errors, 0 skips
```
2021-03-18 02:06:42 -05:00
Eileen M. Uchitelle 404a7f34c7
Merge pull request #41590 from Shopify/log-subscriber-publish
Forward sql.active_record notifications back into the calling thread
2021-03-10 16:16:36 -05:00
Ryuta Kamizono 55d913d34c
Merge pull request #41648 from alkesh26/fixed-incorrect-changelog-output
[ci skip] corrected the output of maximum in ActiveSupport changelog
2021-03-10 19:23:50 +09:00
Xavier Noria 482e081aaa Deletes AS::Dependencies.warnings_on_first_load 2021-03-10 07:55:29 +01:00
alkeshghorpade 40770b6878 corrected the output of maximum in ActiveSupport changelog 2021-03-10 10:57:53 +05:30
Xavier Noria dc7817cb42 Deletes logging from AS::Dependencies 2021-03-09 10:02:03 +01:00
Xavier Noria 43a7f68ae3 Deletes AS::Dependencies::Blamable
This is an internal class which is no longer needed.
2021-03-08 17:10:42 +01:00
Xavier Noria 3c90308b17 Deletes AS::Dependencies::ClassCache
This is an internal class which is no longer needed.
2021-03-08 07:54:28 +01:00