CachedResource is a Ruby gem designed to enhance the performance of web service interactions through ActiveResource by caching responses based on request parameters. By reducing the need for repeated network requests, it minimizes latency and optimizes the efficiency of your application's data retrieval processes.
Installation
gem install cached_resource
Compatibility
CachedResource is designed to be framework agnostic, but will hook into Rails for caching and logging if available. CachedResource supports the following ActiveSupport/Rails (right) and Ruby (down) version combinations:
🛤️ 6.1 | 🛤️ 7.0 | 🛤️ 7.1 | |
---|---|---|---|
💎 3.0 | ✅ | ✅ | ✅ |
💎 3.1 | ✅ | ✅ | ✅ |
💎 3.2 | ✅ | ✅ | ✅ |
Configuration
Set up CachedResource across all ActiveResources:
class ActiveResource::Base
cached_resource(options)
end
Or set up CachedResource for a single class:
class MyActiveResource < ActiveResource::Base
cached_resource(options)
end
Options
CachedResource accepts the following options as a hash:
Option | Description | Default |
---|---|---|
:enabled |
Enables or disables caching. | true |
:cache_collections |
Set to false to always remake a request for collections. | true |
:cache |
The cache store that CacheResource should use. | The Rails.cache if available, or an ActiveSupport::Cache::MemoryStore
|
:cache_key_prefix |
A prefix to be added to the cache keys. | nil |
:collection_arguments |
The arguments that identify the principal collection request. | [:all] |
:collection_synchronize |
Use collections to generate cache entries for individuals. Update the existing cached principal collection when retrieving subsets of the principal collection or individuals. | false |
:logger |
The logger to which CachedResource messages should be written. | The Rails.logger if available, or an ActiveSupport::Logger
|
:race_condition_ttl |
The race condition ttl, to prevent dog pile effect or cache stampede. | 86400 |
:ttl_randomization_scale |
A Range from which a random value will be selected to scale the ttl. | 1..2 |
:ttl_randomization |
Enable ttl randomization. | false |
:ttl |
The time in seconds until the cache should expire. | 604800 |
For example:
cached_resource :cache => MyCacheStore.new, :ttl => 60, :collection_synchronize => true, :logger => MyLogger.new
You can also change them dynamically. Simply:
MyActiveResource.cached_resource.option = option_value
Additionally a couple of helper methods are available:
# Turn caching off
MyActiveResource.cached_resource.off!
# Turn caching on
MyActiveResource.cached_resource.on!
Caveats
If you set up CachedResource across all ActiveResources or any subclass of ActiveResource that will be inherited by other classes and you want some of those others to have independent CachedResource configurations, then check out the example below:
class ActiveResource::Base
cached_resource
end
class MyActiveResource < ActiveResource::Base
self.cached_resource = CachedResource::Configuration.new(:collection_synchronize: true)
end
Usage
Sit back and relax! If you need to reload a particular request you can pass :reload => true
into the options hash like this:
MyActiveResource.find(:all, :reload => true)
If you need to clear the entire cache just do the following:
MyActiveResource.clear_cache
Sometimes you might have a case the resource pathing is non-unique per call. This can create a situation where your caching the same result for multiple calls:
MyActiveResource.find(:one, from: "/admin/shop.json")
Since resources are cached with an argument based key, you may pass in extra data to be appended to the cache key:
MyActiveResource.find(:one, from: "/admin/shop.json", uid: "unique value")
Contribution
Testing
Locally
You can set TEST_RAILS_VERSION
to a value of the supported Rails versions in the Compatability Matrix, or bundler will automatically select a version.
Examples:
TEST_RAILS_VERSION=7.1 bundle exec rspec # runs test suite + linter
bundle exec rspec # Runs test suite
With Docker
docker build -t cached_resource_test -f Dockerfile.test .
docker run --rm -v ${PWD}/coverage:/app/coverage cached_resource_test
# Coverage report can be found in coverage/index.html
# RSpec reports can be found in coverage/spec_results/${ruby-version}-${rails-version}.index.html
# Linter reports can be found in coverage/linter-results.index.html
Code Coverage
Coverage can be found found within coverage/index.html
after every test run.
Linter
We use unconfigurable linting rules from Standard
To lint run: bundle exec rake standard
To automatically apply linter fixes: bundle exec rake standard:fix
Credit/Inspiration
- quamen and this gist
- latimes and this plugin
Feedback/Problems
Feedback is greatly appreciated! Check out this project's issue tracker if you've got anything to say.