frivol 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +7 -6
- data/CHANGES.md +15 -0
- data/Gemfile +4 -1
- data/README.rdoc +56 -24
- data/Rakefile +17 -0
- data/VERSION +1 -1
- data/frivol.gemspec +19 -6
- data/lib/frivol.rb +1 -3
- data/lib/frivol/backend/multi.rb +159 -0
- data/lib/frivol/backend/redis.rb +93 -0
- data/lib/frivol/backend/redis_distributed.rb +51 -0
- data/lib/frivol/backend/riak.rb +186 -0
- data/lib/frivol/class_methods.rb +10 -4
- data/lib/frivol/config.rb +8 -22
- data/lib/frivol/helpers.rb +32 -34
- data/test/fake_redis.rb +44 -19
- data/test/helper.rb +116 -6
- data/test/test_backend.rb +33 -0
- data/test/test_counters.rb +31 -0
- data/test/test_frivol.rb +24 -9
- data/test/test_frivolize.rb +11 -11
- data/test/test_multi_backend.rb +127 -0
- data/test/test_multi_backend_counters.rb +113 -0
- data/test/test_multi_backend_expiry.rb +128 -0
- data/test/test_riak.rb +41 -0
- data/test/test_threads.rb +6 -1
- metadata +30 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49b60bcea96f41ca6dfd54dc9b3b4c63db50c144
|
4
|
+
data.tar.gz: e47b8d3203ca595433192dbe55673fff5d2ad13e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4ebac79ca4b09b7685580b630ad763c75766b9daaf70b624c85d856bbcb44282ace07cc6ec2f890fb3c6519bac2ab4116b36580d910e9c2d128365ff9313801
|
7
|
+
data.tar.gz: e523e418a679e1b81e0645314e482e592f01f23fa89db470ec52ef382f394043ea8afe355195771bdf657b8aead9d2b10381296c00674915c4294d2e40f07c41
|
data/.travis.yml
CHANGED
@@ -2,14 +2,15 @@ language: ruby
|
|
2
2
|
bundler_args: --without development
|
3
3
|
before_install:
|
4
4
|
- 'echo ''gem: --no-ri --no-rdoc'' > ~/.gemrc'
|
5
|
+
services:
|
6
|
+
- redis-server
|
7
|
+
- riak
|
5
8
|
rvm:
|
6
|
-
- 1.8.7
|
7
|
-
- 1.9.2
|
8
9
|
- 1.9.3
|
9
10
|
- 2.0.0
|
10
|
-
|
11
|
-
-
|
12
|
-
- jruby-19mode
|
11
|
+
- 2.1.0
|
12
|
+
- 2.2.0
|
13
13
|
- ruby-head
|
14
|
+
- jruby-19mode
|
14
15
|
- jruby-head
|
15
|
-
|
16
|
+
script: bundle exec rake test:all
|
data/CHANGES.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
<!--- TODO: Date and version -->
|
2
|
+
# March 2014 (v)
|
3
|
+
<!--- TODO: Check on this version number -->
|
4
|
+
- Drop support for Redis < 2.2.6
|
5
|
+
- Add backends for Redis, Redis::Distributed and Riak
|
6
|
+
- FIXED: counters never expire if created with increment or decrement methods
|
7
|
+
|
8
|
+
# Previous
|
9
|
+
<!--- TODO: Fill in -->
|
10
|
+
|
11
|
+
|
12
|
+
# TODO/BUGS(?):
|
13
|
+
- Hook AR reload method to clear_storage?
|
14
|
+
- Add a way (maybe using MR) to expire keys in Riak
|
15
|
+
- BUG: Now, counters always have their expiry reset
|
data/Gemfile
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
gem 'multi_json'
|
4
|
-
gem 'redis'
|
5
4
|
gem 'rake'
|
6
5
|
|
7
6
|
group :development do
|
8
7
|
gem 'jeweler'
|
8
|
+
gem 'pry'
|
9
|
+
gem 'pry-debugger'
|
9
10
|
end
|
10
11
|
|
11
12
|
group :test do
|
12
13
|
gem 'test-unit'
|
14
|
+
gem 'redis'
|
15
|
+
gem 'riak-client'
|
13
16
|
end
|
data/README.rdoc
CHANGED
@@ -10,14 +10,27 @@ when a hot system is restarted. Frivol's design is such that it solves our probl
|
|
10
10
|
believe it is generic enough to be used in many Rails web projects and even in other types of
|
11
11
|
projects altogether.
|
12
12
|
|
13
|
+
As of version 0.4.0, Frivol supports various backends, including Redis::Destributed and Riak.
|
14
|
+
There's a Multi backend which will migrate keys from an old backend to a new one, like from
|
15
|
+
Redis to Redis::Destributed.
|
16
|
+
|
13
17
|
== Usage
|
18
|
+
|
19
|
+
=== Configuration
|
14
20
|
Configure Frivol in your configuration, for example in an initializer or in environment.rb
|
15
21
|
REDIS_CONFIG = {
|
16
22
|
:host => "localhost",
|
17
23
|
:port => 6379
|
18
24
|
}
|
19
|
-
Frivol::Config.
|
25
|
+
Frivol::Config.backend = Frivol::Backend::Redis.new(REDIS_CONFIG)
|
26
|
+
|
27
|
+
**Note:** This configuration has changed in version 0.4.0 with the introduction of <tt>Backend</tt>s
|
28
|
+
|
29
|
+
You can also use RedisDestributed or Riak backends. These are configured similarly. Finally there is a
|
30
|
+
Multi which works to migrate data from an old backend to a new one. For example, we used a Multi backend
|
31
|
+
to migrate from a single Redis instance to a RedisDistributed pair.
|
20
32
|
|
33
|
+
=== Standard Usage
|
21
34
|
Now include Frivol in whichever classes you'd like to make use of temporary storage. You can optionally
|
22
35
|
call the <tt>storage_expires_in(time)</tt> class method to set a default expiry. In your methods you can
|
23
36
|
now call the <tt>store(keys_and_values)</tt> and <tt>retrieve(keys_and_defaults)</tt> methods.
|
@@ -29,6 +42,33 @@ The default is not to expire the storage, in which case it will live for as long
|
|
29
42
|
<tt>delete_storage</tt>, as the name suggests will immediately delete the storage, while <tt>clear_storage</tt>
|
30
43
|
will clear the cache that Frivol keeps and force the next <tt>retrieve</tt> to return to Redis for the data.
|
31
44
|
|
45
|
+
==== Example
|
46
|
+
class BigComplexCalcer
|
47
|
+
include Frivol
|
48
|
+
storage_expires_in 600 # temporary storage expires in 10 minutes.
|
49
|
+
def initialize(key)
|
50
|
+
@key = key
|
51
|
+
end
|
52
|
+
def storage_key(bucket = nil)
|
53
|
+
"frivol-test-#{key}" # override the storage key because we don't respond_to? :id, and don't care about buckets
|
54
|
+
end
|
55
|
+
def big_complex_calc
|
56
|
+
retrieve :complex => :do_big_complex_calc # do_big_complex_calc is the method to get the default from
|
57
|
+
end
|
58
|
+
def last_calc_done
|
59
|
+
last = retrieve(:last => nil) # default is nil
|
60
|
+
return "never" if last.nil?
|
61
|
+
return "#{Time.now - Time.at(last)} seconds ago"
|
62
|
+
end
|
63
|
+
def do_big_complex_calc
|
64
|
+
# Wee! Do some really hard work here...
|
65
|
+
# ...still working...
|
66
|
+
store :complex => result, :last => Time.now.to_i # ...and let's keep the result for at least 10 minutes, as well as the last timme we did it
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
=== Buckets
|
32
72
|
Since version 0.1.5 Frivol can create different storage buckets. Note that this introduces a breaking change
|
33
73
|
to the <tt>storage_key</tt> method if you have overriden it. It now takes a +bucket+ parameter.
|
34
74
|
|
@@ -42,6 +82,7 @@ exactly like the standard +store+ and +retrieve+ methods. There will also be <tt
|
|
42
82
|
take a integer (value and default, respectively) and the increment does not take a parameter. Since version 0.2.1
|
43
83
|
there is also <tt>increment_my_counter_by</tt>, <tt>decrement_my_counter</tt> and <tt>decrement_my_counter_by<tt>.
|
44
84
|
|
85
|
+
=== Conditional retrieval
|
45
86
|
Fine grained control of storing and retrieving values from buckets can be controlled using the :condition and
|
46
87
|
:else options.
|
47
88
|
storage_bucket :my_bucket,
|
@@ -61,30 +102,21 @@ Frivol uses the +storage_key+ method to create a base key for storage in Redis.
|
|
61
102
|
<tt>"#{self.class.name}-#{id}"</tt> so you'll want to override that method if you have classes that don't
|
62
103
|
respond to id.
|
63
104
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
def last_calc_done
|
78
|
-
last = retrieve(:last => nil) # default is nil
|
79
|
-
return "never" if last.nil?
|
80
|
-
return "#{Time.now - Time.at(last)} seconds ago"
|
81
|
-
end
|
82
|
-
def do_big_complex_calc
|
83
|
-
# Wee! Do some really hard work here...
|
84
|
-
# ...still working...
|
85
|
-
store :complex => result, :last => Time.now.to_i # ...and let's keep the result for at least 10 minutes, as well as the last me we did it
|
86
|
-
end
|
105
|
+
=== Frivolize
|
106
|
+
The +frivolize+ method is similar to +memoize+ except that it uses the backend to store the data which can thus be
|
107
|
+
shared amongst multiple processes.
|
108
|
+
|
109
|
+
def long_running_result
|
110
|
+
# do lots of hard work
|
111
|
+
end
|
112
|
+
frivolize :long_running_result
|
113
|
+
|
114
|
+
The frivolize also is also able to take options to make counters and expire.
|
115
|
+
|
116
|
+
def long_running_count
|
117
|
+
# count something that takes a long time
|
87
118
|
end
|
119
|
+
frivolize :long_running_count, counter: true, expires_in: 10.minutes
|
88
120
|
|
89
121
|
== Time Extensions
|
90
122
|
These extensions allow the storing and retrieving of <tt>Time</tt> and
|
data/Rakefile
CHANGED
@@ -24,6 +24,23 @@ Rake::TestTask.new(:test) do |test|
|
|
24
24
|
test.verbose = true
|
25
25
|
end
|
26
26
|
|
27
|
+
namespace :test do
|
28
|
+
desc 'Test all backends and the Multi backend in all combinations'
|
29
|
+
task :all do
|
30
|
+
%w[
|
31
|
+
fake_redis redis redis_distributed riak multi
|
32
|
+
multi_redis_redis multi_redis_redis_distributed
|
33
|
+
multi_redis_riak multi_redis_distributed_riak
|
34
|
+
multi_riak_redis multi_riak_redis_distributed
|
35
|
+
].each do |backend|
|
36
|
+
puts "Testing #{backend}"
|
37
|
+
ENV['backend'] = backend
|
38
|
+
Rake::Task["test"].reenable
|
39
|
+
Rake::Task["test"].invoke
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
27
44
|
task :default => :test
|
28
45
|
|
29
46
|
begin
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/frivol.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: frivol 0.
|
5
|
+
# stub: frivol 0.4.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "frivol"
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.4.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Marc Heiligers"]
|
14
|
-
s.date = "
|
14
|
+
s.date = "2015-06-28"
|
15
15
|
s.description = "Simple Redis backed temporary storage intended primarily for use with ActiveRecord models to provide caching"
|
16
16
|
s.email = "marc@eternal.co.za"
|
17
17
|
s.extra_rdoc_files = [
|
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.files = [
|
22
22
|
".document",
|
23
23
|
".travis.yml",
|
24
|
+
"CHANGES.md",
|
24
25
|
"Gemfile",
|
25
26
|
"LICENSE",
|
26
27
|
"README.rdoc",
|
@@ -53,6 +54,10 @@ Gem::Specification.new do |s|
|
|
53
54
|
"doc/rdoc-style.css",
|
54
55
|
"frivol.gemspec",
|
55
56
|
"lib/frivol.rb",
|
57
|
+
"lib/frivol/backend/multi.rb",
|
58
|
+
"lib/frivol/backend/redis.rb",
|
59
|
+
"lib/frivol/backend/redis_distributed.rb",
|
60
|
+
"lib/frivol/backend/riak.rb",
|
56
61
|
"lib/frivol/class_methods.rb",
|
57
62
|
"lib/frivol/config.rb",
|
58
63
|
"lib/frivol/functor.rb",
|
@@ -60,6 +65,7 @@ Gem::Specification.new do |s|
|
|
60
65
|
"lib/frivol/time_extensions.rb",
|
61
66
|
"test/fake_redis.rb",
|
62
67
|
"test/helper.rb",
|
68
|
+
"test/test_backend.rb",
|
63
69
|
"test/test_buckets.rb",
|
64
70
|
"test/test_condition.rb",
|
65
71
|
"test/test_condition_with_counters.rb",
|
@@ -68,6 +74,10 @@ Gem::Specification.new do |s|
|
|
68
74
|
"test/test_extensions.rb",
|
69
75
|
"test/test_frivol.rb",
|
70
76
|
"test/test_frivolize.rb",
|
77
|
+
"test/test_multi_backend.rb",
|
78
|
+
"test/test_multi_backend_counters.rb",
|
79
|
+
"test/test_multi_backend_expiry.rb",
|
80
|
+
"test/test_riak.rb",
|
71
81
|
"test/test_seeds.rb",
|
72
82
|
"test/test_threads.rb"
|
73
83
|
]
|
@@ -80,20 +90,23 @@ Gem::Specification.new do |s|
|
|
80
90
|
|
81
91
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
82
92
|
s.add_runtime_dependency(%q<multi_json>, [">= 0"])
|
83
|
-
s.add_runtime_dependency(%q<redis>, [">= 0"])
|
84
93
|
s.add_runtime_dependency(%q<rake>, [">= 0"])
|
85
94
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
95
|
+
s.add_development_dependency(%q<pry>, [">= 0"])
|
96
|
+
s.add_development_dependency(%q<pry-debugger>, [">= 0"])
|
86
97
|
else
|
87
98
|
s.add_dependency(%q<multi_json>, [">= 0"])
|
88
|
-
s.add_dependency(%q<redis>, [">= 0"])
|
89
99
|
s.add_dependency(%q<rake>, [">= 0"])
|
90
100
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
101
|
+
s.add_dependency(%q<pry>, [">= 0"])
|
102
|
+
s.add_dependency(%q<pry-debugger>, [">= 0"])
|
91
103
|
end
|
92
104
|
else
|
93
105
|
s.add_dependency(%q<multi_json>, [">= 0"])
|
94
|
-
s.add_dependency(%q<redis>, [">= 0"])
|
95
106
|
s.add_dependency(%q<rake>, [">= 0"])
|
96
107
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
108
|
+
s.add_dependency(%q<pry>, [">= 0"])
|
109
|
+
s.add_dependency(%q<pry-debugger>, [">= 0"])
|
97
110
|
end
|
98
111
|
end
|
99
112
|
|
data/lib/frivol.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require "redis"
|
2
|
-
|
3
1
|
# == Frivol
|
4
2
|
module Frivol
|
5
3
|
require "frivol/config"
|
@@ -56,7 +54,7 @@ module Frivol
|
|
56
54
|
# Expire the stored data in +time+ seconds.
|
57
55
|
def expire_storage(time, bucket = nil)
|
58
56
|
return if time.nil?
|
59
|
-
Frivol::Config.
|
57
|
+
Frivol::Config.backend.expire storage_key(bucket), time
|
60
58
|
end
|
61
59
|
|
62
60
|
# The base key used for storage in Redis.
|
@@ -0,0 +1,159 @@
|
|
1
|
+
module Frivol
|
2
|
+
module Backend
|
3
|
+
# == Configuration
|
4
|
+
# This backend is used to migrate from one backend to another (and another) (and another).
|
5
|
+
# Essentially, this backend will check for the existence of the key in the newest backend,
|
6
|
+
# and if not found check in the older backends in order. If it's found in an older backend
|
7
|
+
# it will move the value to the new backend.
|
8
|
+
#
|
9
|
+
# I have used this in production to move from Redis to RedisDistributed.
|
10
|
+
# old_backend = Frivol::Backend::Redis.new(:db => 10)
|
11
|
+
# new_backend = Frivol::Backend::RedisDistributed.new(["redis://127.0.0.1:6379/11", "redis://127.0.0.1:6379/12"])
|
12
|
+
# Frivol::Config.backend = Frivol::Backend::Multi.new([ new_backend, old_backend ])
|
13
|
+
class Multi
|
14
|
+
# :nodoc:
|
15
|
+
BackendsNotUniqueError = Class.new(StandardError)
|
16
|
+
|
17
|
+
def initialize(backends)
|
18
|
+
unless backends.map(&:inspect).uniq.size == backends.size
|
19
|
+
raise BackendsNotUniqueError, "Backends are not unique: #{backends.map(&:inspect).join(', ')}"
|
20
|
+
end
|
21
|
+
@primary_backend = backends.shift
|
22
|
+
@other_backends = backends
|
23
|
+
end
|
24
|
+
|
25
|
+
# Hashes
|
26
|
+
def get(key, expiry = Frivol::NEVER_EXPIRE)
|
27
|
+
val = @primary_backend.get(key)
|
28
|
+
val = migrate(key, expiry) if val.nil?
|
29
|
+
val
|
30
|
+
end
|
31
|
+
|
32
|
+
def set(key, val, expiry = Frivol::NEVER_EXPIRE)
|
33
|
+
@other_backends.each { |be| be.del(key) }
|
34
|
+
@primary_backend.set(key, val, expiry)
|
35
|
+
end
|
36
|
+
|
37
|
+
def del(key)
|
38
|
+
@primary_backend.del(key)
|
39
|
+
@other_backends.each { |be| be.del(key) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def exists(key)
|
43
|
+
@primary_backend.exists(key) ||
|
44
|
+
@other_backends.detect { |be| be.exists(key) }
|
45
|
+
end
|
46
|
+
|
47
|
+
# Counters
|
48
|
+
def getc(key, expiry = Frivol::NEVER_EXPIRE)
|
49
|
+
val = @primary_backend.getc(key)
|
50
|
+
val = migratec(key, :getc, 0, expiry) if val.nil?
|
51
|
+
val
|
52
|
+
end
|
53
|
+
|
54
|
+
def setc(key, val, expiry = Frivol::NEVER_EXPIRE)
|
55
|
+
@other_backends.each { |be| be.delc(key) }
|
56
|
+
@primary_backend.setc(key, val, expiry)
|
57
|
+
end
|
58
|
+
|
59
|
+
def delc(key)
|
60
|
+
@primary_backend.delc(key)
|
61
|
+
@other_backends.each { |be| be.delc(key) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def existsc(key)
|
65
|
+
@primary_backend.existsc(key) ||
|
66
|
+
@other_backends.detect { |be| be.existsc(key) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def incr(key, expiry = Frivol::NEVER_EXPIRE)
|
70
|
+
if @primary_backend.existsc(key)
|
71
|
+
@primary_backend.incr(key)
|
72
|
+
else
|
73
|
+
migratec(key, :incrby, 1, expiry)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def decr(key, expiry = Frivol::NEVER_EXPIRE)
|
78
|
+
if @primary_backend.existsc(key)
|
79
|
+
@primary_backend.decr(key)
|
80
|
+
else
|
81
|
+
migratec(key, :decrby, 1, expiry)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def incrby(key, amt, expiry = Frivol::NEVER_EXPIRE)
|
86
|
+
if @primary_backend.existsc(key)
|
87
|
+
@primary_backend.incrby(key, amt)
|
88
|
+
else
|
89
|
+
migratec(key, :incrby, amt, expiry)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def decrby(key, amt, expiry = Frivol::NEVER_EXPIRE)
|
94
|
+
if @primary_backend.existsc(key)
|
95
|
+
@primary_backend.decrby(key, amt)
|
96
|
+
else
|
97
|
+
migratec(key, :decrby, amt, expiry)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Expiry/TTL
|
102
|
+
def expire(key, ttl)
|
103
|
+
@primary_backend.expire(key, ttl)
|
104
|
+
end
|
105
|
+
|
106
|
+
def ttl(key)
|
107
|
+
expiry = @primary_backend.ttl(key)
|
108
|
+
if expiry.nil?
|
109
|
+
@other_backends.each do |be|
|
110
|
+
expiry = be.ttl(key)
|
111
|
+
return expiry unless expiry.nil?
|
112
|
+
end
|
113
|
+
nil
|
114
|
+
else
|
115
|
+
expiry
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Connection
|
120
|
+
def flushdb
|
121
|
+
@primary_backend.flushdb
|
122
|
+
@other_backends.each { |be| be.flushdb }
|
123
|
+
end
|
124
|
+
|
125
|
+
def connection
|
126
|
+
@primary_backend.connection
|
127
|
+
end
|
128
|
+
|
129
|
+
# Migration
|
130
|
+
def migrate(key, expiry = Frivol::NEVER_EXPIRE)
|
131
|
+
backend = @other_backends.detect { |be| be.exists(key) }
|
132
|
+
if backend
|
133
|
+
val = backend.get(key)
|
134
|
+
ttl = backend.ttl(key)
|
135
|
+
@primary_backend.set(key, val, ttl)
|
136
|
+
@other_backends.each { |be| be.del key }
|
137
|
+
val
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def migratec(key, method = :incrby, amt = 0, expiry = Frivol::NEVER_EXPIRE)
|
142
|
+
backend = @other_backends.detect { |be| be.existsc(key) }
|
143
|
+
if backend
|
144
|
+
val = backend.getc(key).to_i
|
145
|
+
ttl = backend.ttl(key)
|
146
|
+
@primary_backend.incrby(key, val) unless val.zero?
|
147
|
+
val = @primary_backend.send(method, key, amt) unless amt.zero? || method == :getc
|
148
|
+
@primary_backend.expire(key, ttl) if ttl
|
149
|
+
@other_backends.each { |be| be.delc key }
|
150
|
+
val
|
151
|
+
elsif method != :getc
|
152
|
+
@primary_backend.send(method, key, amt, expiry)
|
153
|
+
else
|
154
|
+
nil
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|