cache_man 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -0,0 +1,3 @@
1
+ module CacheMan
2
+ VERSION = "0.0.2"
3
+ 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: []