Memoize ability_map, conditions, global_actions, delegations
Description
This MR memoizes:
DeclarativePolicy::Base.ability_map
DeclarativePolicy::Base.conditions
DeclarativePolicy::Base.global_actions
DeclarativePolicy::Base.delegations
In gitlab-org/gitlab#420623 (closed) after adding an ability to filter out notes the Exporter User is not permitted to read customers started reporting that their projects can not longer be exported & sidekiq node runs out of RAM during export. We filter out notes by iterating them with note.readable_by?(user)
. If enough notes are present, it causes memory usage to skyrocket.
This should also benefit notes rendering in the UI (and all other policy checks).
Example for 500 notes:
Before 800 Mb memory allocated:
require 'memory_profiler'
MemoryProfiler.report { Note.last(500).each { |note| note.readable_by?(User.first) } }.pretty_print(detailed_report: true)
Total allocated: 827235195 bytes (4897665 objects)
Total retained: 3871264 bytes (20684 objects)
allocated memory by gem
-----------------------------------
287181225 declarative_policy-1.1.0
145281644 other
133107381 activesupport-7.0.6
109408432 activerecord-7.0.6
allocated memory by location
-----------------------------------
181285568 /Users/georgekoltsov/.asdf/installs/ruby/3.1.4/lib/ruby/gems/3.1.0/gems/declarative_policy-1.1.0/lib/declarative_policy/base.rb:77
137862000 <internal:marshal>:35
86137016 /Users/georgekoltsov/.asdf/installs/ruby/3.1.4/lib/ruby/gems/3.1.0/gems/declarative_policy-1.1.0/lib/declarative_policy/base.rb:20
57233743 /Users/georgekoltsov/.asdf/installs/ruby/3.1.4/lib/ruby/gems/3.1.0/gems/marginalia-1.11.1/lib/marginalia/comment.rb:115
55162000 /Users/georgekoltsov/.asdf/installs/ruby/3.1.4/lib/ruby/gems/3.1.0/gems/activesupport-7.0.6/lib/active_support/cache.rb:1013
After 500 Mb memory allocated:
require 'memory_profiler'
MemoryProfiler.report { Note.last(500).each { |note| note.readable_by?(User.first) } }.pretty_print(detailed_report: true)
Total allocated: 540877937 bytes (4600274 objects)
Total retained: 192823 bytes (853 objects)
allocated memory by gem
-----------------------------------
145376235 other
129580961 activesupport-7.0.6
107732135 activerecord-7.0.6
...
allocated memory by location
-----------------------------------
137997693 <internal:marshal>:35
57103318 /Users/georgekoltsov/.asdf/installs/ruby/3.1.4/lib/ruby/gems/3.1.0/gems/marginalia-1.11.1/lib/marginalia/comment.rb:115
55217160 /Users/georgekoltsov/.asdf/installs/ruby/3.1.4/lib/ruby/gems/3.1.0/gems/activesupport-7.0.6/lib/active_support/cache.rb:1013
46574912 /Users/georgekoltsov/.asdf/installs/ruby/3.1.4/lib/ruby/gems/3.1.0/gems/activesupport-7.0.6/lib/active_support/core_ext/enumerable.rb:78
A rough 37% reduction in memory allocation.
Related Issues
See: #31 (closed)
Suggested version bump
-
Major (backwards incompatible changes) -
Minor (backwards compatible changes) -
Patch (API compatible changes)
Checklist
-
Tests have been added or updated to cover any changes in behavior -
This does not change the API to consume this library, or a suggested version bump has been provided -
The CHANGELOG.md
has been updated -
No new runtime dependencies have been introduced
Edited by Peter Leitzen