my_stuff-cache 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,85 @@
1
+ # Copyright 2011-present Fred Emmott. All Rights Reserved.
2
+
3
+ module MyStuff
4
+ module Cache
5
+ # Base implementation.
6
+ #
7
+ # You probably want a subclass instead:
8
+ # - MyStuff::Cache::NullCache (not likely)
9
+ # - MyStuff::Cache::MemoryCache
10
+ # - MyStuff::Cache::MemcachedCache
11
+ class Base
12
+ # Try to get ids from cache, falling back to the given block.
13
+ #
14
+ # See #get_with_multi_fallback for documentation.
15
+ #
16
+ # Unlike get_with_multi_fallback, fallback gets called once for each
17
+ # id. You almost certainly want to use #get_with_multi_fallback
18
+ # instead.
19
+ def get_with_fallback ids, key_pattern, options = {}, &fallback
20
+ get_with_multi_fallback(ids, key_pattern, options) do |ids|
21
+ result = ids.map{|id| fallback.call(id) }
22
+ result
23
+ end
24
+ end
25
+
26
+ # Try to get ids from cache, falling back to to the given block.
27
+ #
28
+ # - +ids+ is an array of ids
29
+ # - +key_pattern+ is a printf string to turn an id into a cache key
30
+ #
31
+ # The following options are supported:
32
+ # +update_cache+:: If fallback is called, cache the result (default
33
+ # true)
34
+ # +force_update+:: Fetch from the database, even if there's a value
35
+ # in cache.
36
+ # +ttl+: Keep fetched values in cache for the specified number of
37
+ # seconds. Defaults to forever (0). May be completely ignored.
38
+ #
39
+ # The block gets passed the list of ids which missed the cache.
40
+ def get_with_multi_fallback ids, key_pattern, options = {}, &fallback
41
+ options = {
42
+ :update_cache => true,
43
+ }.merge(options)
44
+
45
+ to_cache = Hash.new
46
+ if options[:force_update]
47
+ data = Hash[ids.zip([nil] * ids.size)]
48
+ else
49
+ data = Hash[ids.zip(get(ids.map{|x| key_pattern % x}))]
50
+ end
51
+ misses = data.select{|k,v| !v}.keys
52
+ from_fallback = fallback.call(misses)
53
+ Hash[misses.zip(from_fallback)].each do |k,v|
54
+ to_cache[key_pattern % k] = v
55
+ data[k] = v;
56
+ end
57
+ set(to_cache) unless to_cache.empty? || !options[:update_cache]
58
+ ids.map{|k| data[k]}
59
+ end
60
+
61
+ # Fetch values from cache.
62
+ #
63
+ # Returns an array of values. If a key is not in the cache, nil is
64
+ # returned instead.
65
+ #
66
+ # +keys+ is an array of cache keys.
67
+ #
68
+ # Currently, no options are supported.
69
+ def get keys, options = {}
70
+ raise NotImplementedError.new
71
+ end
72
+
73
+ # Set values in the cache.
74
+ #
75
+ # +values+ is a hash of cache key => values.
76
+ #
77
+ # The following options are supported:
78
+ # +ttl+: Keep fetched values in cache for the specified number of
79
+ # seconds. Defaults to forever (0). May be completely ignored.
80
+ def set values, options = {}
81
+ raise NotImplementedError.new
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright 2011-present Fred Emmott. All Rights Reserved.
2
+
3
+ autoload :Memcached, 'memcached'
4
+
5
+ module MyStuff
6
+ module Cache
7
+ # Memcache-base cached.
8
+ #
9
+ # If you want to use this, you know what it does.
10
+ class MemcachedCache < MyStuff::Cache::Base
11
+ # Create an instance of this cache.
12
+ #
13
+ # +memcached+ is a Memcached object, provided by the memcached gem.
14
+ def initialize memcached
15
+ @mc = memcached
16
+ end
17
+
18
+ def get keys, options = {}
19
+ begin
20
+ results = @mc.get(keys) unless keys.empty?
21
+ keys.map{|k| results[k]}
22
+ rescue Memcached::Error => e
23
+ LOG :warning, e
24
+ [nil] * keys.size
25
+ end
26
+ end
27
+
28
+ def set values, options = {}
29
+ options[:ttl] ||= 0
30
+ begin
31
+ values.each do |k,v|
32
+ @mc.set(k, v, options[:ttl])
33
+ end
34
+ rescue Memcached::Error => e
35
+ LOG :warning, e
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ # Copyright 2011-present Fred Emmott. All Rights Reserved.
2
+
3
+ module MyStuff
4
+ module Cache
5
+ # Hash-based cache.
6
+ #
7
+ # This will not be shared between instances of the cache - for example,
8
+ # this means that it won't be shared between all requests in a
9
+ # Passenger or pool-based setup.
10
+ class MemoryCache < MyStuff::Cache::Base
11
+ def initialize
12
+ @cache = Hash.new
13
+ end
14
+
15
+ def get keys, options = {}
16
+ keys.map{|key| @cache[key]}
17
+ end
18
+
19
+ def set values, options = {}
20
+ @cache.merge! values
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ # Copyright 2011-present Fred Emmott. All Rights Reserved.
2
+
3
+ module MyStuff
4
+ module Cache
5
+ # No-op implementation that implements the API, but does no caching.
6
+ class NullCache < ::MyStuff::Cache::Base
7
+ def get keys, options = {}
8
+ [nil] * keys.size
9
+ end
10
+
11
+ def set keys, options = {}
12
+ # nop
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ # Copyright 2011-present Fred Emmott. All Rights Reserved.
2
+
3
+ require 'my_stuff/cache/base'
4
+
5
+ # Code for MyStuff.ws
6
+ module MyStuff
7
+ # Simplistic caching module.
8
+ #
9
+ # You probably want to use ActiveSupport::Cache instead. The two major
10
+ # advantages of this are in Base#get_with_fallback (compared to
11
+ # ActiveSupport::Cache::Store#fetch)
12
+ # - you can specify a key pattern
13
+ # - it takes a list of IDs, so the implementation might use a multiget
14
+ # (MemcachedCache does this)
15
+ #
16
+ # See MyStuff::Cache::Base for interface.
17
+ module Cache
18
+ autoload :NullCache, 'my_stuff/cache/null_cache'
19
+ autoload :MemoryCache, 'my_stuff/cache/memory_cache'
20
+ autoload :MemcachedCache, 'my_stuff/cache/memcached_cache'
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: my_stuff-cache
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Fred Emmott
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-08-15 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: A thin, multi-backend caching library
17
+ email:
18
+ - mail@fredemmott.co.uk
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - lib/my_stuff/cache/memory_cache.rb
27
+ - lib/my_stuff/cache/base.rb
28
+ - lib/my_stuff/cache/memcached_cache.rb
29
+ - lib/my_stuff/cache/null_cache.rb
30
+ - lib/my_stuff/cache.rb
31
+ homepage: https://github.com/fredemmott/my_stuff-cache
32
+ licenses: []
33
+
34
+ post_install_message:
35
+ rdoc_options: []
36
+
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.8.6
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: MyStuff.ws's caching library
58
+ test_files: []
59
+