CachedResource is a Ruby gem whose goal is to increase the performance of interacting with web services via ActiveResource by caching responses based on request parameters. It can help reduce the lag created by making repeated requests across a network.
gem install cached_resourceCachedResource supports the following Ruby versions:
- 2.2.x
- 2.3.x
- 2.4.x
...and likely other modern Ruby versions. If you require 1.8.7 support, please use version 2.3.4.
CachedResource is designed to be framework agnostic, but will hook into Rails for caching and logging if available. The latest CachedResource officially supports the following Rails versions:
- 4.2.x
- 5.0.x
- 5.1.x
For previously supported versions, use 4.2.0 or below.
Set up CachedResource across all ActiveResources:
class ActiveResource::Base
cached_resource
endOr set up CachedResource for a single class:
class MyActiveResource < ActiveResource::Base
cached_resource
endCachedResource accepts the following options:
:enabledDefault:true:ttlThe time in seconds until the cache should expire. Default:604800:race_condition_ttlThe race condition ttl, to prevent dog pile effect or cache stampede. Default: 86400:ttl_randomizationEnable ttl randomization. Default:false:ttl_randomization_scaleA Range from which a random value will be selected to scale the ttl. Default:1..2:collection_synchronizeUse collections to generate cache entries for individuals. Update the existing cached principal collection when retrieving subsets of the principal collection or individuals. Default:false:collection_argumentsThe arguments that identify the principal collection request. Default:[:all]:loggerThe logger to which CachedResource messages should be written. Default: TheRails.loggerif available, or anActiveSupport::Logger:cacheThe cache store that CacheResource should use. Default: TheRails.cacheif available, or anActiveSupport::Cache::MemoryStore
You can set them like this:
cached_resource :cache => MyCacheStore.new, :ttl => 60, :collection_synchronize => true, :logger => MyLogger.newYou can also change them on the fly.
Turn CachedResource off. This will cause all responses to be retrieved normally (i.e. via the network). All responses will still be cached.
MyActiveResource.cached_resource.off!Turn CachedResource on.
MyActiveResource.cached_resource.on!Set the cache expiry time to 60 seconds.
MyActiveResource.cached_resource.ttl = 60Enable cache expiry time randomization, allowing it to fall randomly between 60 and 120 seconds.
MyActiveResource.cached_resource.ttl_randomization = trueChange the cache expiry time randomization scale so that the cache expiry time falls randomly between 30 and 180 seconds.
MyActiveResource.cached_resource.ttl_randomization_scale = 0.5..3Enable collection synchronization. This will cause a call to MyActiveResource.all to also create cache entries for each of its members. So, for example, a later call to MyActiveResource.find(1) will be read from the cache instead of requested from the remote service.
MyActiveResource.cached_resource.collection_synchronize = trueChange the arguments that identify the principal collection request. If for some reason you are concerned with a collection that is retrieved at a "non-standard" URL, you may specify the Ruby arguments that produce that URL. When collection_synchronize is true, the collection returned from a request that matches these arguments will be cached and later updated when one of its members or a subset is retrieved.
MyActiveResource.cached_resource.collection_arguments = [:all, :params => {:name => "Bob"}]Set a different logger.
MyActiveResource.cached_resource.logger = MyLogger.newSet a different cache store.
MyActiveResource.cached_resource.cache = MyCacheStore.newIf 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
endclass MyActiveResource < ActiveResource::Base
self.cached_resource = CachedResource::Configuration.new(:collection_synchronize => true)
endSit 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_cacheSometimes 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")rakeor to test all supported environments, make sure appraisal is setup
bundle exec appraisal installand then run
bundle exec appraisal rakeFor more details, head over to the appraisal documentation.
- quamen and this gist
- latimes and this plugin
Feedback is greatly appreciated! Check out this project's issue tracker if you've got anything to say.