-
-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce memory usage in Hanami::Action via dry-configurable and custom config_class #392
Conversation
8d5e47e
to
78dd1e4
Compare
…ize, avoid unneeded allocations for accepted_mime_types
78dd1e4
to
f8f7de2
Compare
FYI, it seems we had a test failure in a previous run of this (https://github.com/hanami/controller/actions/runs/3166800527/jobs/5156785405) — I'll look into this and address it before merging. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wonderful 👏🏻 I'm happy to see that the new config_class feature turned out to be useful here already 🙂
@solnic It's so good! Couldn't have done it without you :) |
FYI, I looked at this test and couldn't replicate locally (same Ruby version, RSpec command and seed), plus it doesn't seem related to my changes here, so I'm not following it up any further at this point. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@timriley Great achievement! 👏 🎉
🥹 |
Use the config now accessible directly on the `Hanami::Action` class as `Hanami::Action.config` (changed in hanami/controller#392). Also update usage of dry-configurable with `Undefined`: with the new `default_undefined` extension option, `Undefined` takes a special meaning inside dry-configurable. Avoid passing it in our case to make sure our existing behavior is preserved.
This PR takes advantage of the recent memory usage improvements in dry-configurable (see dry-rb/dry-configurable#138) by converting the previously custom
Configuration
class into settings defined on theHanam::Action
class.To preserve some of the existing custom configuration methods, we provide a custom config class to
Dry::Configurable
and keep those methods there.This custom config class also comes in handy as the place to keep the documentation for our settings, which I've converted into yard
@!attribute
macros for concision.We also move two existing bits of state into new dry-configurable settings:
before_callbacks
andafter_callbacks
from class attributes, since Hanami-utils' class attributes implementation is very inefficient with memory.accepted_formats
from being an class-level ivar, since this was the only remaining class-level state and it made sense to keep all this together via the class-level config object.As a consequence of the last change, we're also able to change
Hanami::Action
so it has a conventional#initialize
method again, rather than having a custom.new
method that has toallocate
the object and assign some ivars directly, which is a big win for ease of understanding the code :)Lastly, while we're here, we get rid of the @name ivar for actions, since it's no longer used anywhere.
Using the newly added
benchmarks/memory_profile_action.rb
(which creates 100Action
subclasses by default) we can see this branch allocates 0.338 MB of memory, versus 1.859 MB for the main branch.Even putting aside the memory improvements, I'd paint this as a useful refactor, because it reduces code, better leverages a library we're already using (dry-configurable), as well as centralises all the action class-level state, making it easier for us to manage.
🙋🏼 I've tidied up the commit history here so you should be able to review things commit by commit.