cache_man 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/cache_man.rb +13 -0
- data/lib/cache_man/cacheable.rb +62 -0
- data/lib/cache_man/errors.rb +10 -0
- data/lib/cache_man/fetchable.rb +45 -0
- data/lib/cache_man/version.rb +3 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 713ab0b91d633604cfa388ee97cb8a40593ed3b7
|
4
|
+
data.tar.gz: 204adbbc73dfb93c9add9c5e33d6e34b2469b774
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a44e638edc706522134b9ac36cd74602cbc5d1763451fefd58ecbe9079aa1863c214c92c4a8af976aee582336ee2681c77788bddbe3967184de43d8c2db52b74
|
7
|
+
data.tar.gz: af5c8cb28291832170bd0f93b693b36fea190496e1e1a6995bca4bbf887d73558de1bb31482603e417bab796cb249e74e1e8929414518e3e79a5f98e9dae1abe
|
data/lib/cache_man.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# This file contains the main namespace of the gem
|
2
|
+
# and other required modules/classes needed by the rest of the gem
|
3
|
+
require "cache_man/version"
|
4
|
+
require "active_support/concern"
|
5
|
+
require "active_support/core_ext/numeric/time"
|
6
|
+
require "rails"
|
7
|
+
|
8
|
+
module CacheMan
|
9
|
+
end
|
10
|
+
|
11
|
+
require "cache_man/errors.rb"
|
12
|
+
require "cache_man/cacheable"
|
13
|
+
require "cache_man/fetchable"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# This concern adds support for getting and setting cache for a model.
|
2
|
+
# It also adds support for a soft expiry of cache besides a hard expiry.
|
3
|
+
# The module allows an object to respond to the stale? method which informs other objects whether the cache has soft expired or not.
|
4
|
+
# The cache can be updated asynchronously if it has soft expired.
|
5
|
+
# For the asynchronously update of the cache, this gem depends on another gem called dispatch_rider.
|
6
|
+
# It depends on the cache settings defined in your application config to work properly.
|
7
|
+
# The concern only works for ducks that respond to id and find methods.
|
8
|
+
# So, ideally any ActiveModel or ActiveResource object should work.
|
9
|
+
module CacheMan
|
10
|
+
module Cacheable
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
@cache_duration = 20.minutes
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_reader :cache_duration
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def cache_client
|
21
|
+
Rails.cache
|
22
|
+
end
|
23
|
+
|
24
|
+
def cache_key(id)
|
25
|
+
"#{self.name.underscore}/#{id}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def cache(id)
|
29
|
+
resource = find(id)
|
30
|
+
resource.cache
|
31
|
+
resource
|
32
|
+
end
|
33
|
+
alias_method :new_cache, :cache
|
34
|
+
|
35
|
+
def get_cached(id)
|
36
|
+
cache_client.read(cache_key(id))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def cache_client
|
41
|
+
self.class.cache_client
|
42
|
+
end
|
43
|
+
|
44
|
+
def cache_key
|
45
|
+
self.class.cache_key(self.id)
|
46
|
+
end
|
47
|
+
|
48
|
+
# this is meant to be overriden to change the expiry (at least for now)
|
49
|
+
def cache_hard_expires_in
|
50
|
+
1.day
|
51
|
+
end
|
52
|
+
|
53
|
+
def cache
|
54
|
+
@cache_expires_at = Cacheable.cache_duration.since.to_i
|
55
|
+
self.cache_client.write(self.cache_key, self, expires_in: cache_hard_expires_in)
|
56
|
+
end
|
57
|
+
|
58
|
+
def stale?
|
59
|
+
@cache_expires_at && Time.now > Time.at(@cache_expires_at)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module CacheMan
|
2
|
+
class CacheManError < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class FinderNotFound < CacheManError
|
6
|
+
def initialize
|
7
|
+
super("There is no <model>.find method defined. Please implement a <model>.find method or a finder module in app/models/<model>/finder.rb")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# This concern adds support for a model to be fetched either from cache or from some other data store.
|
2
|
+
# The concern is only to be included in classes that implement a class method find to fetch the object from a data store other than cache.
|
3
|
+
# If such a class method does not exist, you can write your own custom finder module for the model.
|
4
|
+
# By convention, the finder module should be app/models/<model_name>/finder.rb
|
5
|
+
# The first attempt to fetch a model will be from cache.
|
6
|
+
# If that fails, then it will fallback to fetching from a different data store.
|
7
|
+
# If the cache has soft expired then it will return the stale object, but will let the cache update asynchronously.
|
8
|
+
module CacheMan
|
9
|
+
module Fetchable
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
included do
|
13
|
+
include Cacheable
|
14
|
+
begin
|
15
|
+
extend "#{name}::Finder".constantize
|
16
|
+
rescue NameError
|
17
|
+
raise FinderNotFound.new unless respond_to?(:find)
|
18
|
+
end
|
19
|
+
private_class_method :find
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def fetch(id)
|
24
|
+
cached_resource = get_cached(id)
|
25
|
+
if cached_resource.nil?
|
26
|
+
new_cache(id)
|
27
|
+
elsif cached_resource.stale?
|
28
|
+
recache(id) || cached_resource
|
29
|
+
else
|
30
|
+
cached_resource
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def recache(id)
|
35
|
+
begin
|
36
|
+
new_cache(id)
|
37
|
+
rescue
|
38
|
+
# request failed, should probably do something useful with it here
|
39
|
+
# fall back to using cached copy
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cache_man
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Suman Mukherjee
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: This is a gem that serves remote resources from a cache. If the cache
|
56
|
+
gets stale, then the stale cache is served and the cache gets updated in async.
|
57
|
+
email:
|
58
|
+
- sumanmukherjee03@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/cache_man/cacheable.rb
|
64
|
+
- lib/cache_man/errors.rb
|
65
|
+
- lib/cache_man/fetchable.rb
|
66
|
+
- lib/cache_man/version.rb
|
67
|
+
- lib/cache_man.rb
|
68
|
+
homepage: ''
|
69
|
+
licenses:
|
70
|
+
- MIT
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.0.3
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: The gem connects to a memcache server and tries to fetch the resource you
|
92
|
+
requested from the cache. It maintains a time stamp to figure out the expiry of
|
93
|
+
the cache. But the expiry is a soft expiry in most cases. If it is a soft expiry,
|
94
|
+
then it serves the stale asset and updates the cache in async. If it is a hard expiry,
|
95
|
+
then it fetches the resource from remote and serves the asset.
|
96
|
+
test_files: []
|