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.
@@ -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: []