| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
`depend_on` message format is `"No such file to load -- %s.rb"`.
But `require_dependency` message is missing `.rb` suffix.
```
% git grep -n 'No such file to load'
actionview/test/actionpack/abstract/helper_test.rb:112: assert_equal "No such file to load -- very_invalid_file_name.rb", e.message
activesupport/lib/active_support/dependencies.rb:245: def require_dependency(file_name, message = "No such file to load -- %s.rb")
activesupport/lib/active_support/dependencies.rb:333: def depend_on(file_name, message = "No such file to load -- %s.rb")
```
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
Style/SpaceBeforeBlockBraces
Style/SpaceInsideBlockBraces
Style/SpaceInsideHashLiteralBraces
Fix all violations in the repository.
|
|
|
|
|
|
|
|
|
| |
A few have been left for aesthetic reasons, but have made a pass
and removed most of them.
Note that if the method `foo` returns an array, `foo << 1`
is a regular push, nothing to do with assignments, so
no self required.
|
| |
|
| |
|
|
|
|
|
| |
The current code base is not uniform. After some discussion,
we have chosen to go with double quotes by default.
|
| |
|
|
|
|
|
|
|
|
| |
In a previous patch, all log-related stuff was removed. However,
some logs are still useful to understand the code. Therefore, in
this patch, I put those log messages back as comments.
[ci skip]
|
|
|
|
|
|
|
|
|
|
| |
If the code reaches that line new_constants is no longer needed.
We only need here to iterate over it to discard stuff and done.
Note that constant_watch_stack.new_constants returns a new
reference each time it is invoked, so that #clear call was not
cleaning state in some internal structure (which would have been
a bit dirty as well at this level of coupling).
|
|
|
|
|
|
|
|
|
|
|
|
| |
This array literal cannot be reached. The previous begin either
returns to the caller via the explicit return in the ensure
block if all goes well, or else propagates whatever make the
begin block abort execution.
I have investigated the origin of this a bit. In the past the
ensure block didn't have a return call, see for example c08547d.
Later on the return was added in 4da4506, but the trailing
literal was left there.
|
|
|
|
|
| |
In this patch, all log-related stuff in `ActiveSupport::Dependencies`
is removed because the logging is no longer useful.
|
|
|
|
|
| |
After Ruby 1.9, we can easily get the constants that have been
defined locally by `Module.constants(false)`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Cleans up four items I came across in ActiveSupport::Dependencies:
- DependenciesTest#
test_dependency_which_raises_exception_isnt_added_to_loaded_set:
Fixes current implementation which will pass no matter what since the
filepath is never added to "loaded" or "history" without being
expanded first.
- Remove DependenciesTest#test_unhook. Seems leftover from when
alias_method_chain was used in Loadable and ModuleConstMissing.
The test will always pass since Module never responds to those methods
- WatchStack#new_constants documentation: update self to @stack.
Looks like self was leftover from when WatchStack inherited from Hash
- Remove ActiveSupport namespace from call to
Dependencies.constant_watch_stack.watching? since the namespace is not
needed, Dependencies is called two other times in the same method
without it (even on the same line) and it brings the line to within
80 characters
|
| |
|
|
|
| |
It improves readability of docs
|
|
|
|
|
|
|
| |
The thread_safe gem is being deprecated and all its code has been merged
into the concurrent-ruby gem. The new class, Concurrent::Map, is exactly
the same as its predecessor except for fixes to two bugs discovered
during the merge.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When the autoload_paths start to grows, this methods is quite a hotspot
>> ActiveSupport::Dependencies.autoload_paths.size
=> 49
>> Benchmark.ips { |x| x.report('baseline') { ActiveSupport::Dependencies.loadable_constants_for_path(File.expand_path('app/models/shop')) }}
Calculating -------------------------------------
baseline 90.000 i/100ms
-------------------------------------------------
baseline 1.073k (±20.2%) i/s - 4.950k
After the patch
Calculating -------------------------------------
patched 883.000 i/100ms
-------------------------------------------------
patched 11.050k (±19.7%) i/s - 50.331k
|
|\
| |
| | |
We need stricter locking before we can unload
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Specifically, the "loose upgrades" behaviour that allows us to obtain an
exclusive right to load things while other requests are in progress (but
waiting on the exclusive lock for themselves) prevents us from treating
load & unload interchangeably: new things appearing is fine, but they do
*not* expect previously-present constants to vanish.
We can still use loose upgrades for unloading -- once someone has
decided to unload, they don't really care if someone else gets there
first -- it just needs to be tracked separately.
|
|/
|
|
|
|
| |
That's outside our remit, and dangerous... if a caller has their own
locking to protect against the natural race danger, we'll deadlock
against it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I wrote a utility that helps find areas where you could optimize your program using a frozen string instead of a string literal, it's called [let_it_go](https://github.com/schneems/let_it_go). After going through the output and adding `.freeze` I was able to eliminate the creation of 1,114 string objects on EVERY request to [codetriage](codetriage.com). How does this impact execution?
To look at memory:
```ruby
require 'get_process_mem'
mem = GetProcessMem.new
GC.start
GC.disable
1_114.times { " " }
before = mem.mb
after = mem.mb
GC.enable
puts "Diff: #{after - before} mb"
```
Creating 1,114 string objects results in `Diff: 0.03125 mb` of RAM allocated on every request. Or 1mb every 32 requests.
To look at raw speed:
```ruby
require 'benchmark/ips'
number_of_objects_reduced = 1_114
Benchmark.ips do |x|
x.report("freeze") { number_of_objects_reduced.times { " ".freeze } }
x.report("no-freeze") { number_of_objects_reduced.times { " " } }
end
```
We get the results
```
Calculating -------------------------------------
freeze 1.428k i/100ms
no-freeze 609.000 i/100ms
-------------------------------------------------
freeze 14.363k (± 8.5%) i/s - 71.400k
no-freeze 6.084k (± 8.1%) i/s - 30.450k
```
Now we can do some maths:
```ruby
ips = 6_226k # iterations / 1 second
call_time_before = 1.0 / ips # seconds per iteration
ips = 15_254 # iterations / 1 second
call_time_after = 1.0 / ips # seconds per iteration
diff = call_time_before - call_time_after
number_of_objects_reduced * diff * 100
# => 0.4530373333993266 miliseconds saved per request
```
So we're shaving off 1 second of execution time for every 220 requests.
Is this going to be an insane speed boost to any Rails app: nope. Should we merge it: yep.
p.s. If you know of a method call that doesn't modify a string input such as [String#gsub](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37) please [give me a pull request to the appropriate file](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37), or open an issue in LetItGo so we can track and freeze more strings.
Keep those strings Frozen
![](https://www.dropbox.com/s/z4dj9fdsv213r4v/let-it-go.gif?dl=1)
|
| |
|
|
|
|
|
| |
We don't need to fully disable concurrent requests: just ensure that
loads are performed in isolation.
|
|
|
|
|
|
|
| |
Module#const_defined? accepts constant paths in modern Ruby, we no longer
need our qualified_* extensions.
References #17845.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The check for circular loading should depend on a stack of files being
loaded at the moment, rather than the collection of loaded files.
This showed up indirectly in #16468, where a misspelled helper would
incorrectly result in a circularity error message.
References #16468
|
|
|
|
|
|
|
| |
Ruby's original behaviour is that :
* It only returns a const name, not a qualified aname
* It returns a symbol, not a string
|
| |
|
| |
|
| |
|
|\
| |
| |
| |
| |
| |
| | |
Conflicts:
guides/source/active_record_validations.md
guides/source/api_documentation_guidelines.md
guides/source/configuring.md
|
| |
| |
| |
| | |
kind of exception we should expect for this internal comment.
|
|/
|
|
| |
unexpected circular dependency error
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
#13204]
load_missing_constant is a private method that basically plays the role of const_missing.
This method has an error condition that is surprising: it raises if the class or module
already has the missing constant. How is it possible that if the class of module has
the constant Ruby has called const_missing in the first place?
The answer is that the from_mod argument is self except for anonymous modules, because
const_missing passes down Object in such case (see the comment in the source code of the
patch for the rationale).
But then, it is better to pass down Object *if Object is also missing the constant* and
otherwise err with an informative message right away.
|
| |
|
| |
|
|\
| |
| | |
Allow Pathname for require dependency
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Previously, an autoloaded constant `HTML::SomeClass` would not be marked
as autoloaded by AS::Dependencies. This is because the
`#loadable_constants_for_path` method uses `String#camelize` on the
inferred file path, which in turn means that, unless otherwise directed,
AS::Dependencies watches for loaded constants in the `Html` namespace.
By passing the original qualified constant name to `#load_or_require`,
this inference step is avoided, and the new constant is picked up in the
correct namespace.
|
| | |
|
| | |
|