cache_man 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|