Skip to content
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

Introduce compressor option to ActiveRecord::Encryption::Encryptor #51735

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

heka1024
Copy link
Contributor

@heka1024 heka1024 commented May 4, 2024

Motivation / Background

There are more performant algorithms than zlib, like zstd or snappy. So I made it possible to configure the compressor to take advantage of these more performant algorithms.

Detail

Make compressor as argument which default value is zlib.

Additional information

Checklist

Before submitting the PR make sure the following are checked:

  • This Pull Request is related to one change. Unrelated changes should be opened in separate PRs.
  • Commit message has a detailed description of what changed and why. If this PR fixes a related issue include it in the commit message. Ex: [Fix #issue-number]
  • Tests are added or updated if you fix a bug or add a feature.
  • CHANGELOG files are updated for the changed libraries if there is a behavior change or additional feature. Minor bug fixes and documentation changes should not be included.

Discussion

What do you thinks about make compressor as property of ActiveRecord::Encryption ?

Copy link
Member

@flavorjones flavorjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming of the custom compressor's methods seems inconsistent to me. Would you consider using Encryptor's convention and name them compress/uncompress instead of ZLib's deflate/inflate?

I also think this PR should update the Rails Guides page on encryption, guides/source/active_record_encryption.md to explain how to implement a custom compressor.

@rails-bot rails-bot bot added the docs label May 7, 2024
@heka1024 heka1024 force-pushed the encryption-compressor branch 2 times, most recently from 883a321 to 3231918 Compare May 7, 2024 08:58
@heka1024
Copy link
Contributor Author

heka1024 commented May 7, 2024

Hi, @flavorjones ! I changed signature of compressor (compress/uncompress) and make compressor configurable. And add some document about compression. Could you review it? I'd really appreciate it if you could provide feedback!

activerecord/CHANGELOG.md Outdated Show resolved Hide resolved
@heka1024 heka1024 force-pushed the encryption-compressor branch 5 times, most recently from a34e1dd to d2de562 Compare May 14, 2024 05:50
@zzak
Copy link
Member

zzak commented May 19, 2024

CI failures seem unrelated, you might want to rebase just to be sure as I think most of those have been fixed

@heka1024 heka1024 force-pushed the encryption-compressor branch 4 times, most recently from 5664b8c to d0a8297 Compare May 19, 2024 06:46
@heka1024
Copy link
Contributor Author

CI failures seem unrelated, you might want to rebase just to be sure as I think most of those have been fixed

@zzak I just rebased it, and it looks like all CI failures are fixed now. 😄

Copy link
Member

@flavorjones flavorjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so I'm only realizing now that Rails already has prior art for this sort of compression API, see the docs for ActiveSupport::Cache::Store.new and the :compressor option.

In summary, "Must respond to deflate and inflate"

So I hate to ask, especially since I asked you to change it in the first place, but can you update this PR to use that naming convention? I sincerely apologize for not realizing this sooner.

activerecord/CHANGELOG.md Outdated Show resolved Hide resolved
guides/source/active_record_encryption.md Outdated Show resolved Hide resolved
guides/source/active_record_encryption.md Outdated Show resolved Hide resolved
@heka1024 heka1024 force-pushed the encryption-compressor branch 3 times, most recently from a7ff27d to a0be4ad Compare May 20, 2024 14:30
guides/source/active_record_encryption.md Outdated Show resolved Hide resolved
@flavorjones flavorjones added the ready PRs ready to merge label May 20, 2024
@heka1024 heka1024 force-pushed the encryption-compressor branch 2 times, most recently from 666952d to 18b4cc2 Compare May 21, 2024 00:15
@heka1024
Copy link
Contributor Author

There is a ci failure but it looks like unrelated.

Failure:
--
  | ActiveRecord::ConnectionAdapters::ReaperTest#test_connection_pool_starts_reaper_in_fork [test/cases/reaper_test.rb:161]:
  | Expected #<Process::Status: pid 79 SIGABRT (signal 6) (core dumped)> to be success?.

Copy link
Member

@eileencodes eileencodes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feature seems like a good idea to me, thanks for working on it @heka1024

I left a comment about the API design and I also think this should provide a config option so apps that want the same custom compressor for every model can just set it once.

end

class User
encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compressor: ZstdCompressor)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API doesn't feel right. Having to initialize a new Encryptor in your app to set the compressor feels cumbersome and un-Rails like. I have two suggestions:

  1. I think if we want a compressor option for every model then Rails should do the initialization for the app. The AR code would check if the compressor option is set and then Rails would do the initialization for the application. Then it's a much cleaner API because it becomes:
encrypts :name, compressor: ZstdCompressor
  1. Rails should provide a config option so that applications can set all encryptors to use the same custom compressor.
config.active_record_encryption.compressor = ZstdCompressor

Copy link
Contributor Author

@heka1024 heka1024 May 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eileencodes Thank you for review! Your talk at the 2023 Rails conference inspired me to contribute to Rails, and I'm glad I got a review 😄

  1. This API seems nicer than the earlier one. I'll implement it. Additionally, I think we should accept the compress option in the encrypts method, as introduced in Allow encryption without compression #50876. I'll handle that in this PR. So, we can use like this :
encrypts :title, compress: false
encrypts :content, compressor: ZstdCompressor
  1. I've already implemented this feature in Config. Should I just add it to the CHANGELOG?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heka1024 New config parameters require a little more documentation work than other features. Specifically, you'll need to update guides/source/configuring.md.

There is a linting tool you should run to make sure configuring.md changes are correct, run tools/railspect configuration .

@flavorjones flavorjones removed the ready PRs ready to merge label May 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants