duality 0.0.1
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.
- data/Gemfile +13 -0
- data/HISTORY.md +6 -0
- data/README.md +24 -0
- data/lib/duality.rb +86 -0
- metadata +129 -0
data/Gemfile
ADDED
data/HISTORY.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
duality
|
2
|
+
=======
|
3
|
+
|
4
|
+
a simple cache interface to setting and getting from two caches
|
5
|
+
|
6
|
+
* sets to both caches asynchronously
|
7
|
+
* gets from faster and then fails over to slower
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
require 'diskcached'
|
12
|
+
require 'memcached'
|
13
|
+
require 'duality'
|
14
|
+
|
15
|
+
$cache = Duality.new(Diskcached.new, Memcached.new("remotehost:11211")) # example caches
|
16
|
+
$cache.set('key', "content")
|
17
|
+
puts $cache.get('key')
|
18
|
+
|
19
|
+
## More Info
|
20
|
+
|
21
|
+
### [Documentation](http://rubyops.github.com/duality/doc/Duality.html)
|
22
|
+
### [Coverage](http://rubyops.github.com/duality/coverage/)
|
23
|
+
|
24
|
+
|
data/lib/duality.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
class Duality
|
3
|
+
|
4
|
+
VERSION = "0.0.1"
|
5
|
+
DEFAULT_TIMEOUT=1
|
6
|
+
@@fast, @@slow = nil
|
7
|
+
|
8
|
+
# Used to set cache connection timeout
|
9
|
+
# - default is 0.5 seconds
|
10
|
+
attr_accessor :timeout
|
11
|
+
|
12
|
+
def initialize fast, slow
|
13
|
+
# check params are caches
|
14
|
+
raise NotACache unless fast.respond_to?(:set) && fast.respond_to?(:get)
|
15
|
+
raise NotACache unless slow.respond_to?(:set) && slow.respond_to?(:get)
|
16
|
+
@fast = fast
|
17
|
+
@slow = slow
|
18
|
+
end
|
19
|
+
|
20
|
+
# Return set timeout or use default.
|
21
|
+
def timeout
|
22
|
+
@timeout||DEFAULT_TIMEOUT
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set to fast and slow.
|
26
|
+
# - timeout after #timeout
|
27
|
+
# - return true if both succeed
|
28
|
+
# - return false if either fail
|
29
|
+
def set key, value
|
30
|
+
Process.fork { @fast.set(key, value) }
|
31
|
+
Process.fork { @slow.set(key, value) }
|
32
|
+
begin
|
33
|
+
Timeout::timeout(timeout) do
|
34
|
+
return ((Process.waitall.select { |p| p[1] == 0 }).count == 2)
|
35
|
+
end
|
36
|
+
rescue Timeout::Error
|
37
|
+
raise CacheTimeout
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Get from fast or slow.
|
42
|
+
# - returns nil if none are found
|
43
|
+
def get key
|
44
|
+
content = nil
|
45
|
+
begin
|
46
|
+
content = @fast.get(key)
|
47
|
+
rescue Exception
|
48
|
+
end
|
49
|
+
|
50
|
+
return content unless content.nil?
|
51
|
+
|
52
|
+
begin
|
53
|
+
content = @slow.get(key)
|
54
|
+
rescue Exception
|
55
|
+
end
|
56
|
+
return content
|
57
|
+
end
|
58
|
+
|
59
|
+
# Add support for other methods from passed caches
|
60
|
+
# this adds support only, but no speed gains.
|
61
|
+
# - use "strict_" to ensure both caches contain method
|
62
|
+
def method_missing(meth, *args, &block)
|
63
|
+
if meth =~ /^strict_(.+)$/
|
64
|
+
meth = $1
|
65
|
+
return run_missing_method(meth, *args, &block) if @fast.respond_to?(meth) && @slow.respond_to?(meth)
|
66
|
+
elsif @fast.respond_to?(meth) || @slow.respond_to?(meth)
|
67
|
+
return run_missing_method(meth, *args, &block)
|
68
|
+
end
|
69
|
+
super
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def run_missing_method meth, *args, &block
|
74
|
+
fast = @fast.send(meth, *args, &block) rescue nil
|
75
|
+
slow = @slow.send(meth, *args, &block) rescue nil
|
76
|
+
return fast if fast == slow
|
77
|
+
return slow if fast.nil?
|
78
|
+
return fast
|
79
|
+
end
|
80
|
+
|
81
|
+
class NotACache < Exception
|
82
|
+
end
|
83
|
+
|
84
|
+
class CacheTimeout < Exception
|
85
|
+
end
|
86
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: duality
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Joshua Mervine
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: simplecov
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rdoc
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: diskcached
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: mongocached
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: a simple cache interface to setting and getting from two caches
|
95
|
+
email:
|
96
|
+
- joshua@mervine.net
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- lib/duality.rb
|
102
|
+
- README.md
|
103
|
+
- HISTORY.md
|
104
|
+
- Gemfile
|
105
|
+
homepage: http://github.com/rubyops/duality/
|
106
|
+
licenses: []
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ! '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 1.3.6
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 1.8.24
|
126
|
+
signing_key:
|
127
|
+
specification_version: 3
|
128
|
+
summary: Simple disk cache
|
129
|
+
test_files: []
|