Commit Graph

9180 Commits

Author SHA1 Message Date
Jonathan Hefner d9823326e8 Support :urlsafe option for MessageEncryptor
This adds a `:urlsafe` option to the `MessageEncryptor` constructor.
When enabled, this option ensures that messages use a URL-safe encoding.
This matches the `MessageVerifier` `:urlsafe` option added in #45419.
2022-06-29 16:00:16 -05:00
Jonathan Hefner 815f5baf14 Refactor message parts logic in MessageEncryptor
Follow-up to #43924.

This commit refactors the logic around assembling and extracting the
parts of a message (namely: the encrypted data, the IV, and the auth
tag).  It also provides a small but reproducible performance increase
for a roundtrip.

Benchmark:

```ruby
require "benchmark/ips"
require "active_support/message_encryptor"

DATA = "x" * 100
ENCRYPTOR = ActiveSupport::MessageEncryptor.new(SecureRandom.random_bytes(32))

Benchmark.ips do |x|
  x.report("roundtrip") do
    ENCRYPTOR.decrypt_and_verify(ENCRYPTOR.encrypt_and_sign(DATA))
  end
end
```

Before:

```
Warming up --------------------------------------
           roundtrip     1.342k i/100ms
Calculating -------------------------------------
           roundtrip     13.525k (± 1.5%) i/s -     68.442k in   5.061532s
```

After:

```
Warming up --------------------------------------
           roundtrip     1.409k i/100ms
Calculating -------------------------------------
           roundtrip     14.125k (± 1.4%) i/s -     71.859k in   5.088419s
```
2022-06-28 14:28:47 -05:00
Jonathan Hefner 73ef37902e Replace MessageVerifier :urlsafe option tests
The `test_urlsafe` test could not fail when `urlsafe: false` because the
serialized input data did not contain a bit sequence that would encode
to a non-URL-safe character.  The `test_no_padding` *could* fail when
`urlsafe: false`, except when the default serializer uses JSON, because
the serialized input data would be a multiple of 3 bytes, thus not
requiring any padding.

This commit replaces those tests with a falsifiable test using a
carefully chosen input string.
2022-06-28 14:19:28 -05:00
Hartley McGuire 31d2468a25
Document that load hooks run if already triggered
After first learning of this in c2a3ff0 and later discussion about cross
component dependencies, it makes sense to document it explicitly.
2022-06-23 17:34:41 -04:00
eileencodes 9766eb4a83
Fix tests for minitest 5.16
In minitest/minitest@6e06ac9 minitest changed such that it now accepts
`kwargs` instead of requiring kwargs to be shoved into the args array.
This is a good change but required some updates to our test code to get
the new version of minitest passing.

Changes are as follows:

1) Lock minitest to 5.15 for Ruby 2.7. We don't love this change but
it's pretty difficult to get 2.7 and 3.0 to play nicely together with
the new kwargs changes. Dropping 2.7 support isn't an option right
now for Rails. This is safe because all of the code changes here are
internal methods to Rails like assert_called_with. Applications
shouldn't be consuming them as they are no-doc'd.
2) Update the `assert_called_with` method to take any kwargs but also
the returns kwarg.
3) Update callers of `assert_called_with` to move the kwargs outside the
args array.
4) Update the message from marshaled exceptions. In 5.16 the exception
message is "result not reported" instead of "Wrapped undumpable
exception".

Co-authored-by: Matthew Draper <matthew@trebex.net>
2022-06-23 08:32:11 -04:00
Jean Boussier 2f5dcb7255
Merge pull request #45424 from shouichi/remove-padding-from-urlsafe-message-verifier
Fix urlsafe MessageVerifier not to include padding
2022-06-22 23:55:23 +02:00
Jonathan Hefner 1003e974ed Tweak MessageVerifier :urlsafe option doc [ci-skip]
Follow-up to #45425.

This fixes a few typos, and slightly adjusts the wording.
2022-06-22 11:21:10 -05:00
Shouichi Kamiya 3234863a83 Document urlsafe option of MessageVerifier
Also clarify that MessageVerifier generates non-urlsafe strings by
default.

[skip ci]
2022-06-22 15:47:21 +09:00
Shouichi Kamiya 08afa160a5 Fix urlsafe MessageVerifier not to include padding
urlsafe option was introduced to MessageVerifier in
09c3f36a96 but it can generate strings
containing padding character ("=") which is not urlsafe.

Fix not to pad when base64 encode.
2022-06-22 15:15:02 +09:00
Shouichi Kamiya 09c3f36a96 Add urlsafe option to MessageVerifier initializer
MessageVerifier uses Base64.strict_encode64 and generated strings are
not urlsafe. Though the goal is to make MessageVerifier generated
strings urlsafe, We can not simply switch to Base64.urlsafe_encode64
because it will be a breaking change. Thus, as a first step, urlsafe
option is added to the MessageVerifier initializer.
2022-06-21 21:40:35 +09:00
John Crepezzi df0de681dc Remove the multi-call form of assert_called_with
The `assert_called_with` helper allows passing a multi-dimensional array to
mock multiple calls to the same method for a given block. This works
fine now, but when adding support for real kwargs arguments to line up with
recent upgrades in Minitest, this approach is no longer workable because
we can't pass multiple sets of differing kwargs.

Rather than complicated this method further, this commit removes the
multi-call form of `assert_called_with` and modifies the tests that
currently make use of that functionality to just use the underlying
`Minitest::Mock` calls.

Co-authored-by: Eileen M. Uchitelle <eileencodes@gmail.com>
2022-06-16 11:13:57 -04:00
Asherah Connor ec34400abb
Behaviour constant deprecation fix (#45367)
* Add failing test for Behaviour deprecated alias

* Correct DeprecatedConstantProxy use

* DeprecatedConstantProxy docs indicate "full" constant names
2022-06-15 10:21:17 -07:00
Jean Boussier 29425c1997
Merge pull request #45318 from mihaic195/fix/local-cache-method-signature
Fix local cache method signature
2022-06-13 20:33:17 +02:00
Jean Boussier 115be62709 Wrap rails runner in executor
The main reason is to automatically report uncaught exceptions
since `rails runner` is often used for cron tasks and such.
2022-06-10 14:16:49 +02:00
mihaic195 cd650611ea
Fix local cache method signature 2022-06-10 11:40:19 +01:00
Jean Boussier 34fb4c4f9a
Merge pull request #45245 from akostadinov/cache_hash
MemCacheStore shorten keys properly
2022-06-09 14:21:06 +02:00
Aleksandar N. Kostadinov 7dd149477d
MemCacheStore shorten keys properly
The logic for shortening long keys in MemCacheStore
is broken since the time it stopped using MD5 checksumming.

Memcached supports keys up to 250 chars length. The reason
things worked I believe is because the underlying Dalli
library is doing it's own key shortening. Which uses its own
hashing function and in fact limits keys to 249 chars, see
petergoldstein/dalli@74b2625f11

This patch in a similar way properly truncates keys to 250
characters and avoids double hashing on Dalli side. Also
makes key name more predictable and independent from the
underlying Dalli version.
2022-06-09 15:06:06 +03:00
Jean Boussier 82095de39f
Merge pull request #45293 from ghiculescu/cache_format_version_setting
Correctly read the `cache_format_version` setting on boot
2022-06-08 20:55:15 +02:00
Alex Ghiculescu 08352a2478 Correctly read the `cache_format_version` setting on boot
Fixes https://github.com/rails/rails/issues/45289
2022-06-08 13:21:29 -05:00
fatkodima 799b5c1df4 Enable connection pooling by default for MemCacheStore and `RedisCacheStore` 2022-06-07 11:40:17 +03:00
John Hawthorn 6a2393ff6b Fix includes of deprecation proxy modules
Previously, including/prepending/extending one of these deprecated
constants would silently succeed, since it is a module.

This adds a defintion for append_features/prepend_features/extended so
that it can forward the inclusion onto the target module.
2022-06-02 18:13:31 -07:00
John Hawthorn dbf2edb7f2 Make Notifier::Fanout faster and safer
This commit aims to improve ActiveSupport::Notifications::Fanout. There
are three main goals here: backwards compatibility, safety, and
performance.

* Backwards compatibility

This ActiveSupport::Notifications is an old and well used interface.
Over time it has collected a lot of features and flexibility, much of
which I suspect is not used anywhere by anyone, but it is hard to know
specifics and we would at minimum need a deprecation cycle.

For this reason this aims to fully maintain compatibility. This includes
both the ability to use an alternate notification implementation instead
of Fanout, the signatures received by all types of listeners, and the
interface used on the Instrumenter and Fanout itself (including the
sometimes problematic start/finish).

* Safety

There have been issues (both recent and past) with the "timestacks"
becoming invalid, particularly when subscribing and unsubscribing within
events. This is an issue when topics are subscribed/unsubscribed to
while they are in flight.

The previous implementation would record a separate timestamp or event
object for each listener in a thread local stack. This meant that it was
essential that the listeners to start and finish were identical.

This issue is avoided by passing the listeners used to `start` the event
to `finish` (`finish_with_state` in the Instrumenter), to ensure they
are the same set in `start`/`finish`.

This commit further avoids this issue. Instead of pushing individual
times onto a stack, we now push a single object, `Handle`, onto the
stack for an event. This object holds all the subscribers (recorded at
start time) and all their associated data. This means that as long as
start/stop calls are not interleaved.

This commit also exposes `build_handle` as a public interface. This
returns the Handle object which can have start/stop called at any time
and any order safely. The one reservation I have with making this public
is that existing "evented" listeners (those receiving start/stop) may
not be ready for that (ex. if they maintain an internal thread-local
stack).

* Performance

This aims to be faster and make fewer allocations then the existing
implementation.

For time-based and event-object-based listeners, the previous
implementation created a separate object for each listener, pushing
and popping it on a thread-local stack. This is slower both because we
need to access the thread local repeatedly (hash lookups) and because
we're allocating duplicate objects.

The new implementation works by grouping similar types of listeners
together and shares either the `Event` or start/stop times between all
of them. The grouping was done so that we didn't need to allocate Events
or Times for topics which did have a listener of that type.

This implementation is significantly faster for all cases, except for
evented, which is slower.

For topics with 10 subscriptions:

*main*:

               timed     66.739k (± 2.5%) i/s -    338.800k in   5.079883s
     timed_monotonic    138.265k (± 0.6%) i/s -    699.261k in   5.057575s
        event_object     48.650k (± 0.2%) i/s -    244.250k in   5.020614s
             evented    366.559k (± 1.0%) i/s -      1.851M in   5.049727s
        unsubscribed      3.696M (± 0.5%) i/s -     18.497M in   5.005335s

*This branch*:

               timed    259.031k (± 0.6%) i/s -      1.302M in   5.025612s
     timed_monotonic    327.439k (± 1.7%) i/s -      1.665M in   5.086815s
        event_object    228.991k (± 0.3%) i/s -      1.164M in   5.083539s
             evented    296.057k (± 0.3%) i/s -      1.501M in   5.070315s
        unsubscribed      3.670M (± 0.3%) i/s -     18.376M in   5.007095s

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
Co-authored-by: Theo Julienne <theojulienne@github.com>
2022-06-01 18:54:44 -07:00
Mike Dalessio 5f8f6764d8
Strings returned from `strip_tags` are correctly tagged `html_safe?`
Because these strings contain no HTML elements and the basic entities
are escaped, they are safe to be included as-is as PCDATA in HTML
content. Tagging them as html-safe avoids double-escaping entities
when being concatenated to a SafeBuffer during rendering.

Fixes https://github.com/rails/rails-html-sanitizer/issues/124
2022-05-31 10:02:07 -04:00
Dirceu Pereira Tiegs 33411ad2b3
Fix with_options bug when first argument is a Proc
An ArgumentError was being raised when methods were called with (proc,
options) inside a with_options block:

    def my_method(arg1, **kwargs)
      [arg1, kwargs]
    end

    # this would raise instead of merging options
    with_options(hello: "world") do
      my_method(proc {}, {fizz: "buzz"})
    end

Fixes #45183
2022-05-28 16:07:34 -04:00
Gannon McGibbon 90c0bde47c Rename behaviour to behavior in test case names 2022-05-26 17:14:18 -04:00
Jean Boussier d4a660f1cb
Merge pull request #45174 from fatkodima/fetch_multi-force
Add `force:` support to `ActiveSupport::Cache::Store#fetch_multi`
2022-05-25 10:02:48 -04:00
Matthew Draper b5d12eaee8
Merge pull request #45061 from matthewd/assert-on-main-thread
Bubble assertion failures back to the main thread
2022-05-25 20:33:04 +09:30
fatkodima 358556b971 Add `force:` support to `ActiveSupport::Cache::Store#fetch_multi` 2022-05-25 03:19:12 +03:00
Ajay Sharma ca0b6ca1bc Explicitly states that the return value is seconds
The previous documentation hints that the return value if `other` `acts_like` time is seconds with the example, but it doesn't explicitly say "seconds" anywhere.  Just trying to make it more obvious that the value is seconds, and not something like milliseconds or nanoseconds, etc.
2022-05-24 12:35:36 -07:00
fatkodima 059d1d16ab Deprecate `:pool_size` and `:pool_timeout` options for configuring connection pooling in cache stores 2022-05-18 00:10:04 +03:00
Andrej Blagojević f48bf3975f Add initial value support to MemCacheStore #increment and #decrement 2022-05-17 18:32:52 +00:00
Joey Paris 98244c1d4b Squash commits 2022-05-15 11:45:22 +01:00
Alan Savage ad7b40c4f7 Fix MemoryStore#write(name, val, unless_exist: true) with expired entry 2022-05-11 11:54:03 -07:00
Matthew Draper a34fec7413 Bubble assertion failures back to the main thread
Without some help, failures in a forked process make for some noise in
the output, but won't fail the build.

Instead of trying to transfer the whole exception back, I've gone for a
simpler solution of just sending _something_ (the exception class name)
back so we'll fail; the full failure will be visible in the child
process's stderr output.
2022-05-11 15:56:27 +09:30
fatkodima ded8301375 Set ttl for redis and memcache cache stores when using `expires_at` 2022-05-10 14:37:11 +03:00
eileencodes 944bcb54f6
Fix tag helper regression
Vue.js, alpinejs, and potentially other JS libraries support tags
starting with `@` symbols. This was broken by the recent security release in
649516ce0f

I've only added `@` to the list even though there are potentially other
safe characters. We can add more if necessary (and if safe).

Fixes:
* #45014
* #44972
2022-05-05 10:42:41 -04:00
Jean Boussier c9a2bc284c Error reporting API: Add a source attribute
Ref: https://github.com/rails/rails/pull/43625#issuecomment-1109595539

Some users may not be interested by some internal errors.
By providing a `source` attribute we allow to easilly filter
these errors out.
2022-05-05 10:57:21 +02:00
Jean Boussier 1b884cfe8a
Merge pull request #44983 from shiro16/dalli-store-optimised-cache-read_multi
Fixed: MemCacheStore#read_multi_entries NoMethodError: undefined method `expired?` for nil:NilClass
2022-05-03 19:06:57 +02:00
Jean Boussier 70fc351619
Merge pull request #44980 from ghiculescu/isolation-level-config
Allow setting some Active Support settings via initializers
2022-05-03 09:53:52 +02:00
Chunwai Li de12c18a99 Emphasize cacheable objects in guide and API docs
Clarify to users what objects may be cached, and highlight the option used to cache default non-serializable data.

Purpose: Improving new-to-Rails users' experience, as this detail may not be obvious, costing them time and effort spent debugging.

Co-authored-by: Hartley McGuire <skipkayhil@gmail.com>
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2022-05-02 15:15:59 -05:00
Alex Ghiculescu 2187bc78e1 Allow setting some active support settings via initializers 2022-05-01 09:02:21 +10:00
ext-shiro16 0beacc31b4 Fixed: NoMethodError: undefined method for nil:NilClass 2022-04-30 01:43:54 +09:00
ext-shiro16 070d049b36 add test case raw values from dalli store use read_multi_entries 2022-04-30 01:43:31 +09:00
Alvaro Martin Fraguas 649516ce0f
Fix and add protections for XSS in names.
Add the method ERB::Util.xml_name_escape to escape dangerous characters
in names of tags and names of attributes, following the specification of
XML.

Use that method in the tag helpers of ActionView::Helpers. Rename the option
:escape_attributes to :escape, to simplify by applying the option to the whole
tag.
2022-04-26 12:34:42 -07:00
Steven Harman 3b012a5254
Respect the formatter keyword arg on init
The stdlib Logger::new allows passing a :formatter keyword argument to
set the logger's formatter. ActiveSupport::Logger::new ignores this
argument by always setting the formatter to an instance of
SimpleFormatter. Instead, we should only set it when none is yet set.
2022-04-22 19:55:36 -04:00
Andrei Maxim dd851f3584
Access JDOM fields as constants in order to be compatibile with JRuby 9.3.x.x 2022-04-21 05:33:59 +03:00
Jonathan Hefner cdabe88d98
Merge pull request #44893 from ghousemohamed/add-docs-for-run-load-hooks
Add API docs for `run_load_hooks` [ci-skip]
2022-04-14 11:42:59 -05:00
Xavier Noria 2953ae5c8a Define config.enable_reloading to be !config.cache_classes
Every time I write `config.cache_classes` I have to pause for a moment to make
sure I get it right. It makes you think.

On the other hand, if you read `config.enable_reloading = true`, does the
application reload? You do not need to spend 1 cycle of brain CPU to nod.
2022-04-14 18:11:36 +02:00
Ghouse Mohamed 6a71188f9c Add API docs for run_load_hooks 2022-04-14 21:39:14 +05:30
Ryuta Kamizono 6bb0e0efb2
Merge pull request #44872 from entretechno/utc-12
Update ActiveSupport time zone tests for UTC-12 (International Date Line West)
2022-04-13 17:52:23 +09:00
Hartley McGuire afce06bdb2
fix warnings when eager loading on ruby 2.7
before:

```
ruby -w -Itest -Ilib -I../activesupport/lib -I../actionpack/lib
-I../actionview/lib -I../activemodel/lib
test/application/loading_test.rb

Run options: --seed 11862

............/home/hartley/dev/github.com/skipkayhil/rails/activesupport/lib/active_support/dependencies/autoload.rb:75:
warning: instance variable @_eagerloaded_constants not initialized
/home/hartley/dev/github.com/skipkayhil/rails/activesupport/lib/active_support/dependencies/autoload.rb:75:
warning: instance variable @_eagerloaded_constants not initialized
.../home/hartley/dev/github.com/skipkayhil/rails/activesupport/lib/active_support/dependencies/autoload.rb:75:
warning: instance variable @_eagerloaded_constants not initialized
/home/hartley/dev/github.com/skipkayhil/rails/activesupport/lib/active_support/dependencies/autoload.rb:75:
warning: instance variable @_eagerloaded_constants not initialized
/home/hartley/dev/github.com/skipkayhil/rails/activesupport/lib/active_support/dependencies/autoload.rb:75:
warning: instance variable @_eagerloaded_constants not initialized
...

Finished in 2.819071s, 6.3851 runs/s, 13.1249 assertions/s.
18 runs, 37 assertions, 0 failures, 0 errors, 0 skips
```

after:

```
ruby -w -Itest -Ilib -I../activesupport/lib -I../actionpack/lib
-I../actionview/lib -I../activemodel/lib
test/application/loading_test.rb

Run options: --seed 34841

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

Finished in 3.407082s, 5.2831 runs/s, 10.8597 assertions/s.
18 runs, 37 assertions, 0 failures, 0 errors, 0 skips
```
2022-04-12 23:51:34 -04:00
Jeremiah c75f94ab83 Update ActiveSupport time zone tests for UTC-12 (International Date Line West) 2022-04-11 09:35:41 -05:00
Gannon McGibbon 8d791726e1 Fix style in test/core_ext/enumerable_test.rb 2022-04-06 13:21:49 -04:00
Jean Boussier 94884da8f8 Handle renaming of `global_constant_state` in Ruby 3.2
Ref: https://github.com/ruby/ruby/pull/5766
2022-04-06 09:22:00 +02:00
Robin Dupret 4067f564a5 Fix next Rails version in intended removal
Following-up #44728
2022-04-03 14:35:21 +02:00
Pierre Jambet c1db4440e7
Improve default message for assert_changes
The default message would not tell you what the actual value is, just
what it expected it to have changed to or from.

It now tells you what the actual value is, similar to the output you'd
get from a matcher such as `assert_equal`
2022-03-31 15:58:38 -04:00
John Bampton 2d55c05c37 Fix case of `YAML` 2022-03-29 16:04:19 +10:00
John Bampton 3b7f55c179 Change `yaml` to `YAML` 2022-03-29 15:19:22 +10:00
Donatas Povilaitis 49fa92bb32 Fix `Range#overlaps?` for beginless ranges
- `#first` raises an error when called on a beginless range.
  Using `#begin` to get the first element instead.
- Adding additional equality condition to cover the case when both
  ranges are beginless
2022-03-23 22:40:24 +02:00
Ghouse Mohamed 70b8a76d98 Extends Ruby reserved keywords list in Module ext in Active Support 2022-03-23 22:14:16 +05:30
Hartley McGuire 458f4c48ec remove testing HWIA serialization for old psych
Psych 2.2.2 has been a default gem since Ruby 2.4.0, so testing against
< 2.0.9 is unnecessary
2022-03-22 23:31:45 -04:00
Andrew White 1943962a10
Deprecate preserving the pre-Ruby 2.4 behavior of `to_time`
With Ruby 2.4+ the default for +to_time+ changed from converting to the
local system time to preserving the offset of the receiver. At the time
Rails supported older versions of Ruby so a compatibility layer was
added to assist in the migration process. From Rails 5.0 new applications
have defaulted to the Ruby 2.4+ behavior and since Rails 7.0 now only
supports Ruby 2.7+ this compatibility layer can be safely removed.

To minimize any noise generated the deprecation warning only appears when
the setting is configured to `false` as that is the only scenario where
the removal of the compatibility layer has any effect.
2022-03-20 10:07:59 +00:00
Aaron Patterson 9ea0ee8135
Merge pull request #44724 from pixeltrix/allow-redis-url-configuration
Allow overriding of redis url when running tests
2022-03-19 14:53:24 -07:00
Andrew White 1c0c909bbb
Allow overriding of redis url when running tests
The tests for the redis cache store are hard-coded to use redis://localhost:6379/0
and redis://localhost:6379/1. This prevents them from running within a docker compose
environment where typically the url would be redis://redis:6379/0.
2022-03-19 10:31:27 +00:00
Kaíque Kandy Koga d78f266d19 Use duck_string instead of string 2022-03-18 20:28:33 -03:00
Aaron Patterson da22687eef
Merge pull request #44718 from ghousemohamed/extend-test-cases-for-object-in-activesupport
Add missing test cases for Object in activesupport
2022-03-18 16:14:06 -07:00
Ghouse Mohamed 5fa817241d Extends test cases for Object in activesupport 2022-03-18 15:34:04 +05:30
Rafael Mendonça França 50ba8d4e30
Merge pull request #44703 from ghousemohamed/test-should-test-for-multibyte-char
Fixes test cases for ActiveSupport multibyte chars
2022-03-16 17:15:35 -04:00
Rafael Mendonça França 5e770a3853
Merge pull request #44695 from Edouard-chin/ec-tagger-logger-broadcast
Fix TaggedLogging functionality when broadcasting to another logger:
2022-03-16 13:57:03 -04:00
Ghouse Mohamed ab99a4f37e multibyte_chars_test should test with ActiveSupport::Multibyte::Chars class as proxy 2022-03-16 19:46:52 +05:30
Rafael Mendonça França 5c1bd20f0d
Merge pull request #44693 from ghousemohamed/fix-docs-related-gem-versions
Fix `#version` method docs and some typos [ci-skip]
2022-03-15 16:28:07 -04:00
Ghouse Mohamed 6ee6cb554b Fix #version docs and some typos 2022-03-16 01:48:37 +05:30
Edouard CHIN 75aa3a07ec Fix TaggedLogging functionality when broadcasting:
- This PR fixes two issues with the Tagged Logging feature in
  conjunction with broadcasting logs.

  For the sake of clarity I'll define the "main logger" and
  the "broadcasted logger" in this snippet:

  ```ruby
    main_logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(io))
    broadcaster_logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(io))

    main_logger.extend(Activesupport::Logger.broadcast(broadcasted_logger))
  ```

  1) The first issue that this PR fixes, is that the tags on the "main logger"
     don't propagate to the "broadcasted logger" when you pass in a block.

     ```ruby
     main_logger.tagged("FOO") { |logger| logger.info("Hello") }

     # Outputs:
     # [Foo] Hello <- By the main logger
     # Hello       <- By the broadcasted logger
     ```

     A fix was made in 70af536b5d
     but that only works for the non block version

  2) It's quite common for the "broadcasted logger" to have a diffent
     log formatter that the "main logger". In example you'd want to
     output JSON logs in one and raw text in the other.

     That wasn't possible before. All loggers had to have the same
     instance of the formatter. The formatter was set on all loggers
     thanks to [this](3fc9d12875/activesupport/lib/active_support/logger.rb (L45-L48)) and it's [associated test](3fc9d12875/activesupport/test/broadcast_logger_test.rb (L58-L64))
     This requirement was needed to make the Tagged Logging feature
     work; the tags being set in a thread variable whose name
     uses the `object_id` 3fc9d12875/activesupport/lib/active_support/tagged_logging.rb (L59)
     (different formatter instance -> different object_id -> different variables)

     In this PR, I have removed the code that sets the same formatter
     instance on all logger. The "broadcaster logger" just need to
     have the `current_tags` point to the `current_tags` of the
     "main logger", I'm doing that by redefing the `current_tags`
     method each time the "main logger" uses a different formatter.

     The advantages by doing so is that custom made formatter
     can now call this `current_tags` method, which will return
     all the tags and process them the way they want.

     ```ruby
       class JSONLogFormatter
         def call(_, _, _, msg)
	   tags = current_tags # Can now retrieve the tags

	   { message: msg, tags: tags }.to_json
	 end
       end

       broadcasted_logger = Logger.new(io)
       broadcaster_logger.formatter = JSONLogFormatter.new
       main_logger = Logger.new(io)
       main_logger.extend(ActiveSupport::Logger.broadcast(broadcasted_logger))
     ```

     The behavior remains the same as before if a logger uses the
     Rails vanilla formatter or the Tagged Logging formatter.
2022-03-15 21:09:18 +01:00
Hartley McGuire 1faf619813 remove extra core_ext/object/blank requires
activerecord/lib/active_record/connection_adapters/postgresql/column.rb
- usage added in 64fd666
- unneeded because of active_support/rails: 8f58d6e

railties/lib/rails/rack/logger.rb
- usage added in c83d9a1
- usage removed in c131211

activesupport/lib/active_support/number_helper/number_converter.rb
- the NumberHelper was split into multiple classes in 2da9d67, however
  the require was left in NumberConverter even though
  NumberToPhoneConverter is the only class where it's used

activesupport/lib/active_support/duration/iso8601_serializer.rb
- usage added in 04c512d
- usage removed in 51e991f
2022-03-14 21:58:10 -04:00
Jonathan Hefner 5de5583f8b
Merge pull request #44678 from ghousemohamed/improvements-to-timezone-rdoc-activesupport
More rdoc improvements to activesupport [ci-skip]
2022-03-13 13:02:25 -05:00
Ghouse Mohamed 9d6cc4114b More rdoc improvements to activesupport 2022-03-13 23:22:48 +05:30
Ghouse Mohamed 475756db96 Fixed rdoc highlighting for ActiveSupport::KeyGenerator class 2022-03-13 22:02:49 +05:30
Kaíque Kandy Koga d89be419ba Add examples of default values using blocks for mattr_reader, mattr_writer and mattr_accessor 2022-03-09 18:58:08 -03:00
Ghouse Mohamed 42b2869d06 Removed unwanted requires of and fixed rubocop errors 2022-03-10 01:19:55 +05:30
Aaron Patterson 44e5a31d85
Merge pull request #44644 from tonobo/active_support_inheritable_options_add_dig
ActiveSupport::OrderedOptions handle custom #dig
2022-03-09 10:48:12 -08:00
Tim Foerster 5c15b586aa
ActiveSupport::OrderedOptions handle custom #dig
Common access via #[](arg) is being casted to symbol, same behavior should be provided on using #dig in order be consistent
2022-03-09 12:42:03 +01:00
Jean Boussier 6bbf8d647d Implement ErrorReporter#disable
Ref: https://github.com/rails/rails/pull/43625#discussion_r809532572

It can be used by error reporting service integration when they wish
to handle the error higher in the stack.

For instance Sidekiq has its own error handling interface with a
little bit of extra context information.
2022-03-07 16:10:27 +01:00
Jean Boussier e17fe9eb6e
Merge pull request #44459 from lewispb/default-error-reporting-handled-kwarg
Set a default value for ActiveSupport::ErrorReporter#report handled kwarg
2022-03-06 16:46:31 +01:00
Jean Boussier 25396b1c2a Avoid adding constants to Enumerable
Ref: https://github.com/aws/aws-sdk-ruby/pull/2670

Some gems like aws-sdk-core use `Object#extend(Enumerable)`.
It's not a very good pattern, but it's somehwat handled ok by Ruby.

However if Enumerable has constants, then any time the module is
extended, the global constant cache is flushed and this has a very
negative impact on performance for the virtual machine, and even
worse for JITs.
2022-03-04 13:33:17 +01:00
Jean Boussier 5772ecd7d5
Merge pull request #44593 from ghiculescu/patch-7
[docs] FileStore does not implement local cache
2022-03-02 10:29:32 +01:00
Jean Boussier db0c46461a
Merge pull request #44575 from Shopify/eager-auto-load
Modernize ActiveSupport::Autoload
2022-03-02 08:36:49 +01:00
Alex Ghiculescu dab0dd72da
[docs] FileStore does not implement local store
Oversight in https://github.com/rails/rails/pull/42626
2022-03-01 18:51:15 -07:00
Aaron Patterson ea9f0103fd
Revert "Revert "Merge pull request #42843 from buckley-w-david/message-verifier-default-serializer""
This reverts commit fd4e63cc28.
2022-03-01 15:14:43 -08:00
Aaron Patterson fd4e63cc28
Revert "Merge pull request #42843 from buckley-w-david/message-verifier-default-serializer"
This reverts commit a40d7815ac, reversing
changes made to ad2529be4b.
2022-03-01 13:58:40 -08:00
Saba Kiaei 5256c90327 Switch ActiveSupport::MessageVerifier's default serialization to JSON 2022-03-01 13:02:17 -05:00
Jean Boussier 9f7222b1ed Modernize ActiveSupport::Autoload
We no longer need to define instance variables to avoid uninitialized
instance variable warnings.

Also rather than to keep a hash of `constant -> path` forever, we
can simply keep a list of constants and call `const_get` for each of
them.

And finally we can clear the list we kept, as it's just wasted memory.
2022-03-01 09:06:04 +01:00
Jean Boussier f4d13563cd Don't setup i18n reloader if `config.cache_classes = true`
If Ruby code isn't reloaded I don't think i18n data should.

The reloader cause some small overhead in production.
2022-02-28 11:01:34 +01:00
Jonathan Hefner 497ab719d0
Merge pull request #44509 from jonathanhefner/apidocs-cross-link-docs
Cross-link API docs [ci-skip]
2022-02-23 12:08:41 -06:00
Matthew Draper e4140140af Warm-up to avoid autoloads interfering with class serial 2022-02-22 21:00:16 +10:30
Hartley McGuire 079a065257 remove unused requires in ActiveSupport::Cache
core_ext/array/wrap
- added in b1164adda1
- usage removed in fa986ae0ca

core_ext/numeric/time
- added in ee51b51b60, but usage was only
  in mem_cache_store so moved require there
2022-02-21 14:13:56 -05:00
Jonathan Hefner a199aaedb8 Cross-link API docs [ci-skip]
RDoc will automatically format and link API references as long as they
are not already marked up as inline code.

This commit removes markup from various API references so that those
references will link to the relevant API docs.
2022-02-21 11:45:25 -06:00
Jonathan Hefner 0c6ea785b6 Remove EventedFileUpdateChecker#updated? caveat [ci-skip]
Since #39718, `EventedFileUpdateChecker#updated?` no longer always
returns `true` after a fork.
2022-02-21 11:11:11 -06:00
Jonathan Hefner a801aa7cde Mark up inline code [ci-skip] 2022-02-21 11:11:11 -06:00
Jonathan Hefner e37adfed4e Add Oxford commas [ci-skip] 2022-02-21 11:11:11 -06:00
Jonathan Hefner 07bee949c4 Replace backticks with RDoc markup [ci-skip]
RDoc does not support backticks the way that Markdown does.  Instead,
inline code must be wrapped with `+` or `<tt>`.
2022-02-21 11:11:11 -06:00
Jonathan Hefner 0d3effc97e Replace "overwrite" with "override" [ci-skip]
"Overwrite" means "destructively replace", and is more suitable when,
for example, talking about writing data to a location.

"Override" means "supersede", and is more suitable when, for example,
talking about redifining methods in a subclass.
2022-02-21 11:11:11 -06:00
Jonathan Hefner 5fdbd217d1 Fix typos [ci-skip] 2022-02-21 11:11:11 -06:00
Jean Boussier d32767884d Copy over the IsolatedExecutionState in AC::Live
Fix: https://github.com/rails/rails/issues/44496

It's really unfortunate, but since thread locals were copied
since a decade and we moved most of them into IsolatedExecutionState
we now need to copy it too to keep backward compatibility.

However I think it's one more sign that AC::Live should be
rethought.
2022-02-21 11:40:52 +01:00
Jean Boussier c9c1768a91
Fix a typo in `Pathname#blank?` documentation [ci-skip] 2022-02-20 17:34:28 +01:00
Jean Boussier 0ac4c04143 `Pathname.blank?` only returns true for `Pathname.new("")`
Fix: https://github.com/rails/rails/issues/44452

We don't ignore blank path strings because as surprising as it is, they
are valid paths:

```ruby
>> path = Pathname.new(" ")
=> #<Pathname: >
>> path.write("test")
=> 4
>> path.exist?
=> true
```

Previously it would end up calling `Pathname#empty?` which returned true
if the path existed and was an empty directory or file.

That behavior was unlikely to be expected.
2022-02-19 09:54:58 +01:00
Rafael Mendonça França 0170745b37
No need to use blank? here
This file is required when `active_support` is required. That should
avoid to load core_ext if possible, so if there is no good reason to
use the blank core_ext, better to not use it.
2022-02-17 21:29:44 +00:00
John Hawthorn 9f0b8eb584 Deprecate Event#{children,parent_of} 2022-02-17 08:20:01 -08:00
John Hawthorn 51e28dc322 Remove child event tracking from AS::Subscriber
Previously ActiveSupport::Subscriber would manage its own events, keep
them in a thread-local stack, and track "child" events of the same
subscriber.

I don't think this was particularly useful, since it only considered
notifications delivered to the same subscriber, and I can't find
evidence of this being used in the wild. I think this was intended to
support tracing, but any uch tool would want to do this itself (at
minimum in order to support multiple namespaces).

Additionally, this has caused a few users to OOM in production
environments, notably when queueing many jobs from another job.
2022-02-17 08:20:01 -08:00
Lewis Buckley 1e89366053
Set a default value for .report handled kwarg 2022-02-17 12:51:22 +00:00
Matthew Draper 86fd8d0143
Merge pull request #44340 from matthewd/defer-xmlmini
Defer loading XmlMini until it's needed
2022-02-17 13:41:57 +10:30
John Hawthorn e1a4061d1d Implement inspect for Notifications::Fanout
A few classes hold a reference to this object (anything with a
subscription), causing the `inspect` or pretty print output to be
unreasonably large and slow.

This implements a simple representation for the Notifications::Fanout
object as users usually don't care about its internals.

Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2022-02-16 17:01:30 -08:00
Matthew Draper a45a4203ac Defer loading XmlMini until it's needed
It's used for {Array,Hash}#to_xml, but that doesn't seem worth loading
by default.
2022-02-17 11:12:26 +10:30
Jean Boussier 10e361179d Fix MemCacheStoreTest stubbing
The stub wasn't called because it was defined on the `@cache` client
rather than on `cache`'s client.

This should reduce `MemCacheStoreTest` flakiness a bit.
2022-02-16 13:23:12 +01:00
Jean Boussier e7547876da
Merge pull request #44442 from nvasilevski/fix-some-assertionless-tests
[Active Support] Add explicit assertions to tests with no assertions
2022-02-16 09:11:52 +01:00
Yasuo Honda f8f438fced Support dalli 3.2.1
This commit addresses these failures which reproduces at Rails CI
at https://buildkite.com/rails/rails/builds/84688#59b6e442-d63a-463e-acfa-222f66113378

This change has been made to dalli 3.2.1
https://github.com/petergoldstein/dalli/pull/899

```ruby
$ bundle update dalli --conservative
$ git diff
diff --git a/Gemfile.lock b/Gemfile.lock
index 172339f7d2..cb5a0dc9c6 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -200,7 +200,7 @@ GEM
       railties (>= 6.0.0)
     curses (1.4.3)
     daemons (1.4.1)
-    dalli (3.2.0)
+    dalli (3.2.1)
     dante (0.2.0)
     debug (1.4.0)
       irb (>= 1.3.6)
$ bin/test test/cache/stores/mem_cache_store_test.rb
Run options: --seed 5584

................................F

Failure:
OptimizedMemCacheStoreTest#test_falls_back_to_localhost_if_address_provided_as_nil [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:231]:
Expected: ["127.0.0.1:11211"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:227

..................................................................F

Failure:
OptimizedMemCacheStoreTest#test_falls_back_to_localhost_if_no_address_provided_and_memcache_servers_undefined [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:223]:
Expected: ["127.0.0.1:11211"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:219

.............................................................................................................................F

Failure:
OptimizedMemCacheStoreTest#test_forwards_string_addresses_if_present [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:216]:
Expected: ["first", "second"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:212

..SF

Failure:
OptimizedMemCacheStoreTest#test_uses_provided_dalli_client_if_present [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:209]:
Expected: ["custom_host"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:206

.............S..F

Failure:
OptimizedMemCacheStoreTest#test_falls_back_to_localhost_if_no_address_provided_and_memcache_servers_defined [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:239]:
Expected: ["custom_host"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:235

..........................................................................S.......................................................................F

Failure:
MemCacheStoreTest#test_falls_back_to_localhost_if_no_address_provided_and_memcache_servers_defined [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:239]:
Expected: ["custom_host"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:235

F

Failure:
MemCacheStoreTest#test_forwards_string_addresses_if_present [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:216]:
Expected: ["first", "second"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:212

............S.....F

Failure:
MemCacheStoreTest#test_falls_back_to_localhost_if_no_address_provided_and_memcache_servers_undefined [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:223]:
Expected: ["127.0.0.1:11211"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:219

............F

Failure:
MemCacheStoreTest#test_falls_back_to_localhost_if_address_provided_as_nil [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:231]:
Expected: ["127.0.0.1:11211"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:227

...................................................................F

Failure:
MemCacheStoreTest#test_uses_provided_dalli_client_if_present [/home/yahonda/src/github.com/rails/rails/activesupport/test/cache/stores/mem_cache_store_test.rb:209]:
Expected: ["custom_host"]
  Actual: nil

bin/test test/cache/stores/mem_cache_store_test.rb:206

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

Finished in 8.884504s, 58.5289 runs/s, 241.3191 assertions/s.
520 runs, 2144 assertions, 10 failures, 0 errors, 4 skips

You have skipped tests. Run with --verbose for details.
$
```
2022-02-16 12:46:43 +09:00
Nikita Vasilevsky 4219696649 [Active Support] Add explicit assertions to tests with no assertions 2022-02-15 23:44:25 +00:00
Petrik f9b234e022 Fix misspelling of value is tests 2022-02-15 14:50:33 +01:00
Jean Boussier d4ef8c26a5
Merge pull request #44366 from avalanche123/patch-1
Fix deserialization in LocalCache#read_multi_entries
2022-02-12 10:43:39 +01:00
Aaron Patterson f9a2ad0394
Fix reloader to work with new Executor signature
This is a follow up to [CVE-2022-23633].
2022-02-11 11:48:19 -08:00
Jean Boussier 10c64a472f
ActionDispatch::Executor don't fully trust `body#close`
Under certain circumstances, the middleware isn't informed that the
response body has been fully closed which result in request state not
being fully reset before the next request.

[CVE-2022-23633]
2022-02-11 10:08:04 -08:00
Ryuta Kamizono af1355e76f
Merge pull request #44386 from ghousemohamed/patch-3
Fix flaky test case in CacheStoreBehavior
2022-02-11 12:24:43 +09:00
Ghouse Mohamed c8fde9a682 Fixes flaky test case in cache_store_behaviour 2022-02-10 22:59:02 +05:30
Bulat Shakirzyanov 3933a41ad5
fix LocalCache#read_multi_entries
In cache stores prepending `LocalCache`, serialized `Entry`
instances are stored in `LocalCache::LocalStore`. This
speeds up hot key lookups without a network roundtrip in a
context of a single given request.

However, with these entries being stored in their serialized
form, `#read_multi_entries` returns them directly to cache
consumers.

Instead, we will now deserialize these entries first.
2022-02-09 12:44:44 -05:00
Nikita Vasilevsky 6758397019 Increment assertions count on assert_nothing_raised 2022-02-09 01:01:10 +00:00
Rafael Mendonça França de7c495209
Merge pull request #44354 from rails/to-fs-as-the-primary
Make #to_fs the default replacement for #to_s(:format)
2022-02-08 11:50:24 -05:00
Rafael Mendonça França 0dfcd54052
Keep to_formatted_s working as before and add tests for it 2022-02-08 16:22:35 +00:00
Hartley McGuire a4feb9e111 fix MessageEncryptor isolation tests
5d0c2b0 added a usage of String#starts_with? which won't work in
isolation tests because its a core extension alias
2022-02-07 17:47:21 -05:00
Zack 5d0c2b0dd2 Change MessageEncryptor default serializer to JSON for Rails 7.1
These changes include adding a hybrid serializer class
named JsonWithMarshalFallback in order for existing apps
to have an upgrade path from Marshal to JSON.
2022-02-07 12:19:36 -05:00
David Heinemeier Hansson d61ab614c2 Fix signature 2022-02-07 15:30:02 +01:00
David Heinemeier Hansson 43ea6e6893 Note the alias the other way 2022-02-07 12:47:43 +01:00
David Heinemeier Hansson 2fee3de7da Missed two spots 2022-02-07 12:47:08 +01:00
David Heinemeier Hansson 41478f7074 Make #to_fs the default replacement for #to_s(:format)
#to_formatted_s is too cumbersome.
2022-02-07 12:41:21 +01:00
Jean Boussier 2b3af27d82
Merge pull request #44219 from machty/fiber-connection-pool
Fiber-safe ConnectionPool
2022-02-05 11:13:50 +01:00
Lewis Buckley 91f80a899f
[ci skip] Improve ActiveSupport::MessageVerifier docs (#44332)
* [ci skip] Refer to Rails.application.message_verifier in MessageVerifier docs

* [ci skip] Clarify authentication example

* [ci skip] Use meaningful example data for message verifier docs

* [ci skip] Link to Rails.application.message_verifier docs

* [ci skip] Clarify order of message signing and verification

* [ci skip] Re-order sections in order of expected use

* [ci skip] Recommend using a purpose to reduce risks

* [ci skip] More consistent parentheses
2022-02-04 17:03:25 +01:00
Jean Boussier e67bdf0cba Appease rubocop 2022-02-01 14:35:04 +01:00
David Heinemeier Hansson fdb98d218e
Add TestCase#stub_const (#44294)
* Add TestCase#stub_const

* Note the concurrency issue

* Changelog entry
2022-02-01 12:20:06 +01:00
machty 449101e753 Fiber-safe ConnectionPool
Replaces a few hard-wired references to Thread/Thread.current within
ActiveRecord::ConnectionPool with IsolationExecutionState.
A few tweaks were required to IsolationExecutionState so that
I could implement the various cache key methods with a reference
to the current thread/fiber.
2022-01-31 15:24:41 -04:00
Lewis Buckley 8df6b6464f
Fix backtrace cleaner example
Fixes:

TypeError (wrong argument type Pathname (expected Regexp))

when using the example given as-is.
2022-01-30 17:05:37 +00:00
Stephen Sugden d5b65c082e Use YAML.unsafe_load for encrypted configuration
Fix: https://github.com/rails/rails/pull/44063
2022-01-26 11:53:19 +01:00
Jean Boussier bbdcfc071d Optimize `Object#instance_values`
`Array#to_h` is substantially faster than `Hash::[]` because having a stricter interface
it can preallocate the hash with the right size.

We also freeze the strings early so that `Hash#[]` doesn't have to dup them.

```ruby
require 'benchmark/ips'

puts RUBY_VERSION

class Object
  def instance_values
    Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
  end

  def instance_values_opt
    instance_variables.to_h do |ivar|
      [ivar[1..-1].freeze, instance_variable_get(ivar)]
    end
  end
end

SMALL = Object.new
2.times { |i| SMALL.instance_variable_set(:"@variable_#{i}", i) }

LARGE = Object.new
15.times { |i| LARGE.instance_variable_set(:"@variable_#{i}", i) }

{
  'SMALL' => SMALL,
  'LARGE' => LARGE
}.each do |size, object|
  puts "=== #{size} ==="
  Benchmark.ips do |x|
    x.report('original') { object.instance_values }
    x.report('patched') { object.instance_values_opt }
    x.compare!
  end
end
```

```
3.1.0
=== SMALL ===
Warming up --------------------------------------
            original    95.429k i/100ms
             patched   116.046k i/100ms
Calculating -------------------------------------
            original    963.241k (± 1.3%) i/s -      4.867M in   5.053433s
             patched      1.246M (± 0.8%) i/s -      6.266M in   5.031372s

Comparison:
             patched:  1245570.0 i/s
            original:   963240.9 i/s - 1.29x  (± 0.00) slower

=== LARGE ===
Warming up --------------------------------------
            original    15.799k i/100ms
             patched    18.285k i/100ms
Calculating -------------------------------------
            original    157.163k (± 1.3%) i/s -    789.950k in   5.027176s
             patched    181.587k (± 1.1%) i/s -    914.250k in   5.035344s

Comparison:
             patched:   181587.4 i/s
            original:   157163.4 i/s - 1.16x  (± 0.00) slower
```
2022-01-26 10:40:15 +01:00
Jean Boussier 25adbd8cb1 Optimize `Object#instance_variable_names`
First we use `map!` to avoid allocating a second `Array`.

Then if possible we use `Symbol#name` (Ruby 3.0+) to avoid allocating one `String` per variable.

```ruby
require 'benchmark/ips'

puts RUBY_VERSION

class Object
  def instance_variable_names
    instance_variables.map(&:to_s)
  end

  if Symbol.method_defined?(:name)
    puts "Symbol#name available"
    def instance_variable_names_opt
      variables = instance_variables
      variables.map!(&:name)
      variables
    end
  else
    puts "Symbol#name NOT available"
    def instance_variable_names_opt
      variables = instance_variables
      variables.map! { |s| s.to_s.freeze }
      variables
    end
  end
end

EMPTY = Object.new

SMALL = Object.new
2.times { |i| SMALL.instance_variable_set(:"@v#{i}", i) }

LARGE = Object.new
15.times { |i| LARGE.instance_variable_set(:"@v#{i}", i) }

{'EMPTY' => EMPTY, 'SMALL' => SMALL, 'LARGE' => LARGE}.each do |size, object|
  puts "=== #{size} ==="
  Benchmark.ips do |x|
    x.report('original') { object.instance_variable_names }
    x.report('patched') { object.instance_variable_names_opt }
    x.compare!
  end
end
```

```
2.7.4
Symbol#name NOT available
=== EMPTY ===
Warming up --------------------------------------
            original   724.324k i/100ms
             patched   848.630k i/100ms
Calculating -------------------------------------
            original      7.327M (± 1.2%) i/s -     36.941M in   5.042732s
             patched      8.506M (± 0.9%) i/s -     43.280M in   5.088726s

Comparison:
             patched:  8505865.6 i/s
            original:  7326561.6 i/s - 1.16x  (± 0.00) slower

=== SMALL ===
Warming up --------------------------------------
            original   203.493k i/100ms
             patched   191.396k i/100ms
Calculating -------------------------------------
            original      2.060M (± 1.1%) i/s -     10.378M in   5.038283s
             patched      1.926M (± 0.9%) i/s -      9.761M in   5.069539s

Comparison:
            original:  2060092.1 i/s
             patched:  1925628.2 i/s - 1.07x  (± 0.00) slower

=== LARGE ===
Warming up --------------------------------------
            original    49.485k i/100ms
             patched    41.184k i/100ms
Calculating -------------------------------------
            original    495.882k (± 1.5%) i/s -      2.524M in   5.090599s
             patched    411.758k (± 0.9%) i/s -      2.059M in   5.001395s

Comparison:
            original:   495882.3 i/s
             patched:   411758.0 i/s - 1.20x  (± 0.00) slower
```

```
3.1.0
Symbol#name available
=== EMPTY ===
Warming up --------------------------------------
            original   615.493k i/100ms
             patched   708.028k i/100ms
Calculating -------------------------------------
            original      6.146M (± 1.1%) i/s -     30.775M in   5.007957s
             patched      7.086M (± 1.0%) i/s -     36.109M in   5.096263s

Comparison:
             patched:  7086187.0 i/s
            original:  6145919.7 i/s - 1.15x  (± 0.00) slower

=== SMALL ===
Warming up --------------------------------------
            original   261.532k i/100ms
             patched   345.988k i/100ms
Calculating -------------------------------------
            original      2.607M (± 1.1%) i/s -     13.077M in   5.017455s
             patched      3.504M (± 0.7%) i/s -     17.645M in   5.036049s

Comparison:
             patched:  3503979.3 i/s
            original:  2606558.7 i/s - 1.34x  (± 0.00) slower

=== LARGE ===
Warming up --------------------------------------
            original    58.156k i/100ms
             patched    87.136k i/100ms
Calculating -------------------------------------
            original    581.008k (± 0.8%) i/s -      2.908M in   5.005101s
             patched    873.801k (± 1.0%) i/s -      4.444M in   5.086316s

Comparison:
             patched:   873801.4 i/s
            original:   581008.4 i/s - 1.50x  (± 0.00) slower
```
2022-01-26 09:56:44 +01:00
Orhan Toy 2b1caa660c Remove AS::LoggerThreadSafeLevel#add patch
The change in
eb18cb3e47
was released with 2.7.0.rc1 and as Rails now has Ruby 2.7.0 as the
minimum version, we can remove this patch.
2022-01-25 00:20:33 +01:00
Jean Boussier d3b602b909 Fix Class#descendants documentation 2022-01-24 11:33:19 +01:00
Jonathan Hefner 22d5dfb503 Fix flakey EventedFileUpdateChecker GC test
Example failure: https://buildkite.com/rails/rails/builds/84109#4a72a57f-20d3-44e1-b0a1-61c6a0baf3b3/1191-1201

Similar to #42845, this should ensure that there are no transient
references to the `EventedFileUpdateChecker`, and that Ruby performs a
full garbage collection cycle.
2022-01-20 17:39:15 -06:00
Daniel Pepper 44a2971e5c
atomic write race condition 2022-01-16 16:54:58 -08:00
Frank Groeneveld 69e339d996
Explicitly list negative currency format
This makes it more clear for translators how to translate the negative format.
2022-01-10 08:11:36 +01:00
Gert Goet 53ede786fc Ensure codeblocks are rendered as such for (min|max)imum
Make indentation consistent for all codeblocks in file.

[ci-skip]
2022-01-07 12:33:40 +01:00
Kev 0ab5a3a4ab Allow subsecond resolution in `travel_to` helper
The `travel_to` helper didn’t support subsecond time traveling in order
to prevent problems with external services, such as MySQL. This,
however, makes it impossible to test features that use durations less
than a second ("subsecond").

This therefore allows `travel_to` to stub `Time.now` with the accurate
time passed to it as `date_or_time` if the `with_usec` optional argument
is set to true:

    Time.now.inspect # => 2022-01-05 22:36:54.613371959 +0000
    travel_to(0.1.seconds.from_now, with_usec: true)
    Time.now.inspect # => 2022-01-05 22:36:54.713371959 +0000
2022-01-06 00:53:35 +01:00
Rafael Mendonça França 0d6af17d66
Merge pull request #43924 from jcmfernandes/message-encryptor-perf-improvements
Improve the performance of ActiveSupport::MessageEncryptor
2022-01-04 18:31:12 -05:00
Mike Dalessio 5e69b7e000
doc: clarify usage of Object.acts_like?
Related to #42292

[skip ci]
2022-01-04 12:26:06 -05:00
Ryuta Kamizono 65766ebcc8 Bump license years to 2022 [ci-skip] 2022-01-01 15:22:15 +09:00
Ryuta Kamizono 9d2533203c Revert "Update the deprecation message for `Enumerable#sum` and `Array#sum`"
This reverts commit 20e20d56ab.

The deprecation message doesn't say when it will be removed, but just
say when it has deprecated.
2021-12-23 16:19:17 +09:00
Ryuta Kamizono 20e20d56ab Update the deprecation message for `Enumerable#sum` and `Array#sum`
Rails 7.0 has already been released.
2021-12-23 16:07:19 +09:00
Jean Boussier bc07139db3 Remove feature checking for Class#descendants
Ref: https://bugs.ruby-lang.org/issues/14394#note-38

Based on Matz's last comment, it's not so clear whether `Class#descendants`
will come back in the same form or at all. So let's not assume anything.
2021-12-22 14:12:13 +01:00
Jean Boussier 912b02ab58 Fix a mistake in DescendantsTracker#descendants for Ruby 3.1 2021-12-21 13:06:52 +01:00
Joao Fernandes 0a0dc95499 Improve the performance of ActiveSupport::MessageVerifier
We can avoid using String#split by calculating the indexes of the
encrypted data, IV, and auth tag in the payload. This increases the
resistance of the solution against ill-formed payloads that don't
include the separator.

This is a follow up to the work in PR #42919.
2021-12-21 11:13:00 +00:00
Jean Boussier 68e9df0257 Ruby 3.1: Handle `Class#subclasses` existing without `Class#descendants`
Since `#subclasses` was introduced a bit after `#descendants`, the feature testing
code assumed that if the former was present, the later would be too.

However it was decided to revert `#descendants` for now, but to keep `#subclasses`
https://bugs.ruby-lang.org/issues/14394#note-33

Since this was totally unexpected, the `#descendants` core_ext and `DescendantsTracker#descendants`
are broken on Active Support 7.0.0 / Ruby 3.1.0-dev.

We now test the existence of both methods to handle this new situation. Since
for now it's planned for `#descendants` to make it back in Ruby 3.2, we keep
checking for it.
2021-12-21 11:41:56 +01:00
Rafael Mendonça França 5f5bd542b3
Fix logger format with Ruby 3.1 2021-12-20 22:36:33 +00:00
Alex Ghiculescu af71e5ef96 Fix flakey Memcache tests 2021-12-13 15:06:03 -06:00
Hartley McGuire 14024c0b80 rm tmpfile added in 340b39e
This appears to have been accidentally added as an artifact of
1d164fdfe1/activesupport/test/file_update_checker_shared_tests.rb (L224)
2021-12-12 21:32:59 -05:00
Rafael Mendonça França a35a380c2c
Remove CHANGELOG that is included in 7.0 2021-12-10 19:03:45 +00:00
Caleb Buxton ffc1e5f889
fix: equivalent negative durations add to the same time (#43795)
* bug: illustrate negative durations don't add to the same time

* fix: equivalent negative durations add to the same time

Co-authored-by: Caleb <me@cpb.ca>
Co-authored-by: Braden Staudacher <braden.staudacher@chime.com>

* Updates CHANGELOG with fix to `ActiveSupport::Duration.build`
2021-12-10 14:03:04 -05:00
Jean Boussier 151ba1ab0c DescendantsTracker: fix the TruffleRuby implementation
Ref: https://github.com/rails/rails/pull/43723

This was pretty much a typo...
2021-12-09 09:38:49 +01:00
Jonathan Hefner 1a4e27e216 Fix assert_called_with with empty args array
`[].all?(Array)` returns `true`.  Thus when an empty `args` array was
passed to `assert_called_with`, `expect` would not be called on the mock
object, eventually leading to an "unmocked method" error.

This commit allows an empty array to be passed as `args`, which behaves
the same as passing `[[]]`.
2021-12-08 12:15:36 -06:00
sampatbadhe 0055b72a3b replace duplicate entries of to_formatted_s with to_fs 2021-12-08 12:31:05 +05:30
Rafael Mendonça França de065c9f7e
Merge pull request #42919 from jcmfernandes/avoid-double-string-split-message-verifier
Avoid unnecessary double string split in ActiveSupport::MessageVerifier#verified
2021-12-07 11:23:19 -05:00
Rafael Mendonça França 83d85b2207
Start Rails 7.1 development 2021-12-07 15:52:30 +00:00
Joao Fernandes 02eda1b950 Extract components from signed messages by calculating their indexes
ActiveSupport::MessageVerifier#verified is causing signed_message to be
split twice: first inside #valid_message? and then inside #verified.
This is ultimately unnecessary.

We can avoid String#split all together by calculating the indexes of the
data and the digest in the payload. This increases the resistance of the
solution against ill-formed payloads that don't include the separator.
2021-12-07 09:44:53 +00:00
Ryuta Kamizono 30ff804ca7 Fix typo in the rdoc for `Pathname#existence` [ci-skip] 2021-12-07 16:01:41 +09:00
Richard Macklin 4954317aac Fix test name in PathnameExistenceTest
This was likely a copy-paste typo from
00fb4e6bbd/activesupport/test/core_ext/object/blank_test.rb (L32)
introduced in 1a14bcb8cd
2021-12-06 21:45:00 -08:00
Rafael Mendonça França 83a3df0136
Add config to disable the `to_s` override in Ruby core classes
This will allow users to take advantage early of Ruby 3.1 optimization
in string interpolation.
2021-12-06 19:22:07 +00:00
Rafael Mendonça França 9aae3ae183
Alias to_formatted_s as to_fs 2021-12-06 19:22:06 +00:00
Rafael Mendonça França 58ecdd0cf2
Deprecate `to_s(format)` in favor of `to_formatted_s(format)`
Ruby 3.1 is going to introduce an [optimization][] that makes interpolation
of some types of objects faster, unless there is a custom implementation
of to_s. Since Rails is overriding `to_s` for a bunch of core classes it
means that this optimization in Rails applications will be disabled.

In order to allow Rails applications to use this optimization in
the future we are deprecating all the reasons we override `to_s` in
those core classes in favor of using `to_formatted_s`.

[optimization]: b08dacfea3
2021-12-06 19:22:05 +00:00
Rafael Mendonça França c2e12e0191
Use `to_formatted_s(:db)` instead of `to_s(:db)` internally
Ruby 3.1 introduced an optimization to string interpolation for some
core classes in b08dacfea3.

But since we override `to_s` in some of those core classes to add behavior
like `to_s(:db)`, all Rails applications will not be able to take advantage
of that improvement.

Since we can use the `to_formatted_s` alias for the Rails specific behavior
it is best for us to deprecate the `to_s` core extension and allow Rails
applications to get the proformace improvement.

This commit starts removing all the `to_s(:db)` calls inside the framework
so we can deprecate the core extension in the next commit.
2021-12-06 19:22:04 +00:00
Sam Bostock 7007d1b2b5
Document ActiveSupport::Testing::Deprecation
Co-authored-by: Sam Jordan <sam.jordan@shopify.com>
Co-authored-by: Sam Bostock <sam.bostock@shopify.com>
2021-12-03 15:04:25 -05:00
Jonathan Hefner 763c219539 Fix flakey test in notifications_test.rb
Example failure: https://buildkite.com/rails/rails/builds/82905#80d6c6ec-943d-4ba3-b360-1ef6c4aa5d89/1012-1022

The test designates the event end time as 0.01 seconds (i.e. 10
milliseconds) after the start time.  It then asserts that the event
duration is 10 ± 0.0001 milliseconds.  This sometimes fails due to
floating point precision errors.

This commit changes the assertion to instead check that the duration is
within 1% of the expected value.
2021-11-30 14:03:32 -06:00
Timo Schilling 115c562927
Fix type in Pathname#existence documentation 2021-11-30 08:37:28 +01:00
Rafael Mendonça França be3ed75ec7
Merge pull request #43718 from esparta/fix_race_conditions_test_cache_v
ActiveSupport::Cache, fix race conditions on test/cache - part V
2021-11-29 16:51:21 -05:00
Rafael Mendonça França 223ba6f81d
Fix documentation of Pathname#existence 2021-11-29 21:49:31 +00:00
Alex Ghiculescu 5046d1cce9 Wrap ActionController::TestCase with Rails executor
Update actionpack/lib/action_controller/test_case.rb

Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
2021-11-26 17:54:47 -06:00
Rafael Mendonça França c14cb9150e
Revert "Add missing `require "active_support` in XmlMini"
This reverts commit 0181f0edd5.

Users of Active Support should always require the top level file of
the framework before requiring anything else inside it, so we don't
need to require that top level file here.
2021-11-26 19:21:10 +00:00
Vipul A M bd04720c7f
Merge pull request #43731 from shunyama/fix/tiny-typo-fix
[skip ci] Fixed tiny typo
2021-11-26 11:23:07 -05:00
shunyama 4b89f16ad4 [skip ci] fix tiny typo 2021-11-27 00:57:08 +09:00
Jean Boussier 0181f0edd5 Add missing `require "active_support` in XmlMini 2021-11-26 11:51:57 +01:00
Espartaco Palma c677229b2c
ActiveSupport::Cache, Part V - change clear override for MemCached 2021-11-26 01:17:31 -08:00
Rafael Mendonça França 33157e2173
Merge pull request #43726 from timoschilling/add-pathname-existence
add Pathname#existence
2021-11-25 15:48:32 -05:00
Rafael Mendonça França df35d93adf
Merge pull request #43719 from kmcphillips/error-reporter-fallback-callable
Require the ErrorReporter#handle fallback to be a callable
2021-11-25 14:32:15 -05:00
Rafael Mendonça França 100ad4341d
Merge pull request #43324 from ghiculescu/patch-5
Be more explicit about lack of inheritance on `thread_mattr_accessor`
2021-11-25 13:46:36 -05:00
Kevin McPhillips d0eeee03be Require the ErrorReporter#handle fallback to be a callable 2021-11-25 13:33:51 -05:00
Jean Boussier ff5e909b63 DescendantsTracker: fix the TruffleRuby branch 2021-11-25 18:09:44 +01:00
Timo Schilling 1a14bcb8cd add Pathname#existence 2021-11-25 16:51:58 +00:00
Jean Boussier 617c8357f6
Merge pull request #43723 from Shopify/descendant-tracker-3.1
Fix DescendantTracker.clear on Ruby 3.1
2021-11-25 17:50:46 +01:00
Jean Boussier cb82f5f0a4 Fix DescendantTracker.clear on Ruby 3.1
Previously I assumed it was useless, however I was wrong.

The method is called by the reloader to give the illusion that
the GC is precise. Meaning a class that will be unloaded is
immediately made invisible without waiting for it to be garbage collected.

This is easy to do up to Ruby 3.0 because `DescendantTracker` keeps
a map of all tracked classes.

However on 3.1 we need to use the inverse strategy, we keep a WeakMap
of all the classes we cleared, and we filter the return value of `descendants`
and `subclasses`.

Since `clear` is private API and is only used when reloading is enabled,
to reduce the performance impact in production mode, we entirely remove
this behavior when `config.cache_classes` is enabled.
2021-11-25 17:32:52 +01:00
Jean Boussier eea74ec211 AS::Callbacks specialize call templates for better performance
By doing so we avoid a lot of extra work.

```
            baseline:  4092604.4 i/s
          opt-method:   693204.7 i/s - 5.90x  (± 0.00) slower
              method:   614761.0 i/s - 6.66x  (± 0.00) slower
```

Baseline is calling `run_callbacks` with no callbacks registered.

Full benchmark: https://gist.github.com/casperisfine/837a7a665c6b232dadcf980d73694748
2021-11-25 14:03:46 +01:00
Espartaco Palma 2bf5e6618e
ActiveSupport::Cache, fix race conditions on test/cache - part V 2021-11-24 16:51:29 -08:00
Rafael Mendonça França 4799156cc3
Merge pull request #43704 from esparta/fix_race_conditions_test_cache_iv
ActiveSupport::Cache, fix race conditions on test/cache - part IV
2021-11-24 17:02:38 -05:00
Jean Boussier 2fbe5d7f29
Merge pull request #43711 from Shopify/thread-accessor-isolated-state
Use IsolatedExecutionState in `thread_mattr_accessor`
2021-11-24 23:01:10 +01:00
Jean Boussier b9098f6ec4
Merge pull request #43712 from Shopify/as-cache-error-handling
Report Memcached and Redis cache errors to Rails.error
2021-11-24 23:00:57 +01:00
Kevin McPhillips ac751edab3
Allow a fallback value to be returned from Rails.error.handle 2021-11-24 11:19:00 -05:00
Jean Boussier c63da2005e Report Memcached and Redis cache errors to Rails.error
Ref: https://github.com/rails/rails/issues/43472

We swallow these exceptions because it makes sense for a cache to
fallback to a cache miss in case of transcient failures.

However there's value in reporting these to the application
owners so that they can be alerted that something undesirable happened.
2021-11-24 12:25:03 +01:00