Skip to content

Commit

Permalink
Merge pull request #2361 from alexzherdev/2358-sha1
Browse files Browse the repository at this point in the history
Add config to use SHA1 instead of MD5 for caching
  • Loading branch information
bf4 authored Oct 29, 2019
2 parents 5ce94fd + 628eff2 commit 6b093c9
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Breaking changes:

Features:

- [#2361](https://github.com/rails-api/active_model_serializers/pull/2361) Add `ActiveModelSerializers.config.use_sha1_digests` to allow customization of the hashing algorithm used for serializer caching (@alexzherdev)

Fixes:

- [#2344](https://github.com/rails-api/active_model_serializers/pull/2344) Fixes #2341 introduced since #2223 (@wasifhossain)
Expand Down
12 changes: 12 additions & 0 deletions docs/general/configuration_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ ActiveModelSerializers.config.serializer_lookup_chain.unshift(

See [lookup_chain.rb](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/lookup_chain.rb) for further explanations and examples.

#### use_sha1_digests

Determines which hashing algorithm to use internally when caching serializers.

Possible values:

- `true`
- `false` (default)

When `true`, ActiveModelSerializers will use SHA1. Otherwise, it will default to using MD5.
Be warned that changing this value may result in serializer caches being invalidated.

## JSON API

##### jsonapi_resource_type
Expand Down
3 changes: 2 additions & 1 deletion lib/active_model/serializer/concerns/caching.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def _cache_digest
def digest_caller_file(caller_line)
serializer_file_path = caller_line[CALLER_FILE]
serializer_file_contents = IO.read(serializer_file_path)
Digest::MD5.hexdigest(serializer_file_contents)
algorithm = ActiveModelSerializers.config.use_sha1_digests ? Digest::SHA1 : Digest::MD5
algorithm.hexdigest(serializer_file_contents)
rescue TypeError, Errno::ENOENT
warn <<-EOF.strip_heredoc
Cannot digest non-existent file: '#{caller_line}'.
Expand Down
29 changes: 29 additions & 0 deletions test/cache_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -446,17 +446,41 @@ def test_a_serializer_rendered_by_two_adapter_returns_differently_fetch_attribut
# rubocop:enable Metrics/AbcSize

def test_uses_file_digest_in_cache_key
reset_cache_digest(@blog_serializer)
render_object_with_cache(@blog)
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{file_digest}"
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
end

def test_uses_sha1_digest_in_cache_key_when_configured
reset_cache_digest(@blog_serializer)
previous_use_sha1_digests = ActiveModelSerializers.config.use_sha1_digests
ActiveModelSerializers.config.use_sha1_digests = true
render_object_with_cache(@blog)
file_digest = Digest::SHA1.hexdigest(File.open(__FILE__).read)
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{file_digest}"
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
ensure
ActiveModelSerializers.config.use_sha1_digests = previous_use_sha1_digests
end

def test_cache_digest_definition
reset_cache_digest(@post_serializer)
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
assert_equal(file_digest, @post_serializer.class._cache_digest)
end

def test_cache_sha1_digest_definition
reset_cache_digest(@post_serializer)
previous_use_sha1_digests = ActiveModelSerializers.config.use_sha1_digests
ActiveModelSerializers.config.use_sha1_digests = true
file_digest = Digest::SHA1.hexdigest(File.open(__FILE__).read)
assert_equal(file_digest, @post_serializer.class._cache_digest)
ensure
ActiveModelSerializers.config.use_sha1_digests = previous_use_sha1_digests
end

def test_object_cache_keys
serializable = ActiveModelSerializers::SerializableResource.new([@comment, @comment])
include_directive = JSONAPI::IncludeDirective.new('*', allow_wildcard: true)
Expand Down Expand Up @@ -715,5 +739,10 @@ def render_object_with_cache(obj, options = {})
def adapter
@serializable_resource.adapter
end

def reset_cache_digest(serializer)
return unless serializer.class.instance_variable_defined?(:@_cache_digest)
serializer.class.remove_instance_variable(:@_cache_digest)
end
end
end

0 comments on commit 6b093c9

Please sign in to comment.