frivol 0.3.1 → 0.4.0
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.
- 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
@@ -0,0 +1,93 @@
|
|
1
|
+
require "redis"
|
2
|
+
|
3
|
+
module Frivol
|
4
|
+
module Backend
|
5
|
+
# == Configuration
|
6
|
+
# This is a connection to a single Redis server and the simplest backend.
|
7
|
+
# REDIS_CONFIG = {
|
8
|
+
# :host => "localhost",
|
9
|
+
# :port => 6379
|
10
|
+
# }
|
11
|
+
# Frivol::Config.backend = Frivol::Backend::Redis.new(REDIS_CONFIG)
|
12
|
+
class Redis
|
13
|
+
# :nodoc:
|
14
|
+
def initialize(config)
|
15
|
+
@config = config
|
16
|
+
end
|
17
|
+
|
18
|
+
# Hashes
|
19
|
+
def get(key, expiry = Frivol::NEVER_EXPIRE)
|
20
|
+
connection.get(key)
|
21
|
+
end
|
22
|
+
alias_method :getc, :get # Counter method alias
|
23
|
+
|
24
|
+
def set(key, val, expiry = Frivol::NEVER_EXPIRE)
|
25
|
+
set_with_expiry(key, val, expiry)
|
26
|
+
end
|
27
|
+
alias_method :setc, :set # Counter method alias
|
28
|
+
|
29
|
+
def del(key)
|
30
|
+
connection.del(key)
|
31
|
+
end
|
32
|
+
alias_method :delc, :del # Counter method alias
|
33
|
+
|
34
|
+
def exists(key)
|
35
|
+
connection.exists(key)
|
36
|
+
end
|
37
|
+
alias_method :existsc, :exists # Counter method alias
|
38
|
+
|
39
|
+
# Counters
|
40
|
+
def incr(key, expiry = Frivol::NEVER_EXPIRE)
|
41
|
+
set_with_expiry(key, 1, expiry, :incrby)
|
42
|
+
end
|
43
|
+
|
44
|
+
def decr(key, expiry = Frivol::NEVER_EXPIRE)
|
45
|
+
set_with_expiry(key, 1, expiry, :decrby)
|
46
|
+
end
|
47
|
+
|
48
|
+
def incrby(key, amt, expiry = Frivol::NEVER_EXPIRE)
|
49
|
+
set_with_expiry(key, amt, expiry, :incrby)
|
50
|
+
end
|
51
|
+
|
52
|
+
def decrby(key, amt, expiry = Frivol::NEVER_EXPIRE)
|
53
|
+
set_with_expiry(key, amt, expiry, :decrby)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Expiry/TTL
|
57
|
+
def expire(key, ttl)
|
58
|
+
connection.expire(key, ttl)
|
59
|
+
end
|
60
|
+
|
61
|
+
def ttl(key)
|
62
|
+
time = connection.ttl(key)
|
63
|
+
time < 0 ? nil : time
|
64
|
+
end
|
65
|
+
|
66
|
+
# Connection
|
67
|
+
def flushdb
|
68
|
+
connection.flushdb
|
69
|
+
end
|
70
|
+
|
71
|
+
def connection
|
72
|
+
Thread.current[thread_key] ||= ::Redis.new(@config)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
def thread_key
|
77
|
+
@thread_key ||= @config.hash.to_s.to_sym
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_with_expiry(key, val, expiry, method = :set)
|
81
|
+
if expiry == Frivol::NEVER_EXPIRE
|
82
|
+
connection.send(method, key, val)
|
83
|
+
else
|
84
|
+
result = connection.multi do |redis|
|
85
|
+
redis.send(method, key, val)
|
86
|
+
redis.expire(key, expiry)
|
87
|
+
end
|
88
|
+
result[0]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "redis"
|
2
|
+
require "redis/distributed"
|
3
|
+
require File.join(File.dirname(__FILE__), "redis")
|
4
|
+
|
5
|
+
module Frivol
|
6
|
+
module Backend
|
7
|
+
# == Configuration
|
8
|
+
# While it's not well known or documented, the Redis gem includes a sharding implementation in
|
9
|
+
# Redis::Distributed[http://www.rubydoc.info/gems/redis/3.2.1/Redis/Distributed]. This backend
|
10
|
+
# makes that available for Frivol.
|
11
|
+
# REDIS_CONFIG = [{
|
12
|
+
# :host => "localhost",
|
13
|
+
# :port => 6379
|
14
|
+
# }, {
|
15
|
+
# :host => "localhost",
|
16
|
+
# :port => 6380
|
17
|
+
# }]
|
18
|
+
# Frivol::Config.backend = Frivol::Backend::RedisDistributed.new(REDIS_CONFIG)
|
19
|
+
class RedisDistributed < Frivol::Backend::Redis
|
20
|
+
# :nodoc:
|
21
|
+
def set(key, val, expiry = Frivol::NEVER_EXPIRE)
|
22
|
+
if expiry == Frivol::NEVER_EXPIRE
|
23
|
+
connection.set(key, val)
|
24
|
+
else
|
25
|
+
connection.node_for(key).multi do |redis|
|
26
|
+
redis.set(key, val)
|
27
|
+
redis.expire(key, expiry)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
alias_method :setc, :set # Counter method alias
|
32
|
+
|
33
|
+
def connection
|
34
|
+
Thread.current[thread_key] ||= ::Redis::Distributed.new(@config)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def set_with_expiry(key, val, expiry, method = :set)
|
39
|
+
if expiry == Frivol::NEVER_EXPIRE
|
40
|
+
connection.send(method, key, val)
|
41
|
+
else
|
42
|
+
results = connection.node_for(key).multi do |redis|
|
43
|
+
redis.send(method, key, val)
|
44
|
+
redis.expire(key, expiry)
|
45
|
+
end
|
46
|
+
results[0]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require "riak"
|
2
|
+
|
3
|
+
module Frivol #:nodoc:
|
4
|
+
module Backend
|
5
|
+
# == Configuration
|
6
|
+
# This backend is experimental. I have not used this in production. YMMV.
|
7
|
+
# RIAK_CONFIG = {
|
8
|
+
# :protocol => 'http',
|
9
|
+
# :nodes => [ { :host => '127.0.0.1' } ]
|
10
|
+
# }
|
11
|
+
# Frivol::Config.backend = Frivol::Backend::Riak.new(RIAK_CONFIG)
|
12
|
+
class Riak
|
13
|
+
# :nodoc:
|
14
|
+
def initialize(config)
|
15
|
+
@prefix = config.delete(:prefix) || ''
|
16
|
+
@config = config
|
17
|
+
end
|
18
|
+
|
19
|
+
# Hashes
|
20
|
+
def get(key, expiry = Frivol::NEVER_EXPIRE)
|
21
|
+
obj = objects_bucket.get_or_new(key)
|
22
|
+
expires_in = ttl(key)
|
23
|
+
if expires_in.nil? || expires_in > 0
|
24
|
+
obj.raw_data
|
25
|
+
else
|
26
|
+
obj.delete
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def set(key, val, expiry = Frivol::NEVER_EXPIRE)
|
32
|
+
obj = objects_bucket.get_or_new(key)
|
33
|
+
obj.raw_data = val
|
34
|
+
obj.content_type = 'text/plain'
|
35
|
+
obj.store
|
36
|
+
expire(key, expiry) unless expiry == Frivol::NEVER_EXPIRE
|
37
|
+
end
|
38
|
+
|
39
|
+
def del(key)
|
40
|
+
objects_bucket.delete(key)
|
41
|
+
expires_bucket.delete(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def exists(key)
|
45
|
+
exists = objects_bucket.exist?(key)
|
46
|
+
if exists
|
47
|
+
expires_in = ttl(key)
|
48
|
+
if expires_in.nil? || expires_in > 0
|
49
|
+
true
|
50
|
+
else
|
51
|
+
objects_bucket.delete(key)
|
52
|
+
false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Counters
|
58
|
+
def getc(key, expiry = Frivol::NEVER_EXPIRE)
|
59
|
+
cnt = counters_bucket.counter(key) if existsc(key)
|
60
|
+
expires_in = ttl(key)
|
61
|
+
if expires_in.nil? || expires_in > 0
|
62
|
+
cnt ? cnt.value : nil
|
63
|
+
else
|
64
|
+
delc(key)
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def setc(key, val, expiry = Frivol::NEVER_EXPIRE)
|
70
|
+
delc(key)
|
71
|
+
cnt = counters_bucket.counter(key)
|
72
|
+
cnt.increment(val)
|
73
|
+
expire(key, expiry) unless expiry == Frivol::NEVER_EXPIRE
|
74
|
+
end
|
75
|
+
|
76
|
+
def delc(key)
|
77
|
+
counters_bucket.delete(key)
|
78
|
+
expires_bucket.delete(key)
|
79
|
+
end
|
80
|
+
|
81
|
+
def existsc(key)
|
82
|
+
exists = counters_bucket.exist?(key)
|
83
|
+
if exists
|
84
|
+
expires_in = ttl(key)
|
85
|
+
if expires_in.nil? || expires_in > 0
|
86
|
+
true
|
87
|
+
else
|
88
|
+
counters_bucket.delete(key)
|
89
|
+
false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def incr(key, expiry = Frivol::NEVER_EXPIRE)
|
95
|
+
cnt = counters_bucket.counter(key)
|
96
|
+
cnt.increment
|
97
|
+
expire(key, expiry) unless expiry == Frivol::NEVER_EXPIRE
|
98
|
+
cnt.value
|
99
|
+
end
|
100
|
+
|
101
|
+
def decr(key, expiry = Frivol::NEVER_EXPIRE)
|
102
|
+
cnt = counters_bucket.counter(key)
|
103
|
+
cnt.decrement
|
104
|
+
expire(key, expiry) unless expiry == Frivol::NEVER_EXPIRE
|
105
|
+
cnt.value
|
106
|
+
end
|
107
|
+
|
108
|
+
def incrby(key, amt, expiry = Frivol::NEVER_EXPIRE)
|
109
|
+
cnt = counters_bucket.counter(key)
|
110
|
+
cnt.increment(amt)
|
111
|
+
expire(key, expiry) unless expiry == Frivol::NEVER_EXPIRE
|
112
|
+
cnt.value
|
113
|
+
end
|
114
|
+
|
115
|
+
def decrby(key, amt, expiry = Frivol::NEVER_EXPIRE)
|
116
|
+
cnt = counters_bucket.counter(key)
|
117
|
+
cnt.decrement(amt)
|
118
|
+
expire(key, expiry) unless expiry == Frivol::NEVER_EXPIRE
|
119
|
+
cnt.value
|
120
|
+
end
|
121
|
+
|
122
|
+
# Expiry/TTL
|
123
|
+
def expire(key, ttl)
|
124
|
+
obj = expires_bucket.get_or_new(key)
|
125
|
+
obj.raw_data = (Time.now.to_i + ttl).to_s
|
126
|
+
obj.content_type = 'text/plain'
|
127
|
+
obj.store
|
128
|
+
end
|
129
|
+
|
130
|
+
def ttl(key)
|
131
|
+
obj = expires_bucket.get_or_new(key)
|
132
|
+
expiry = obj.raw_data.to_i
|
133
|
+
if expiry == 0
|
134
|
+
nil
|
135
|
+
else
|
136
|
+
expiry - Time.now.to_i
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Connection
|
141
|
+
def flushdb
|
142
|
+
objects_bucket.keys.each { |k| objects_bucket.delete(k) }
|
143
|
+
counters_bucket.keys.each { |k| counters_bucket.delete(k) }
|
144
|
+
expires_bucket.keys.each { |k| expires_bucket.delete(k) }
|
145
|
+
end
|
146
|
+
|
147
|
+
def connection
|
148
|
+
Thread.current[thread_key] ||= begin
|
149
|
+
@objects_bucket = nil
|
150
|
+
@counters_bucket = nil
|
151
|
+
@expires_bucket = nil
|
152
|
+
::Riak::Client.new(@config)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
def objects_bucket
|
158
|
+
@objects_bucket ||= begin
|
159
|
+
bkt = connection.bucket("#{@prefix}frivol_objects")
|
160
|
+
bkt.props = { :last_write_wins => true }
|
161
|
+
bkt
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def counters_bucket
|
166
|
+
@counters_bucket ||= begin
|
167
|
+
bkt = connection.bucket("#{@prefix}frivol_counters")
|
168
|
+
bkt.allow_mult = true
|
169
|
+
bkt
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def expires_bucket
|
174
|
+
@expires_bucket ||= begin
|
175
|
+
bkt = connection.bucket("#{@prefix}frivol_expires")
|
176
|
+
bkt.props = { :last_write_wins => true }
|
177
|
+
bkt
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def thread_key
|
182
|
+
@thread_key ||= @config.hash.to_s.to_sym
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
data/lib/frivol/class_methods.rb
CHANGED
@@ -92,6 +92,12 @@ module Frivol
|
|
92
92
|
define_method "decrement_#{bucket}_by" do |amount|
|
93
93
|
Frivol::Helpers.decrement_counter_by(self, bucket, amount, seed_callback)
|
94
94
|
end
|
95
|
+
|
96
|
+
define_method "delete_#{bucket}" do
|
97
|
+
condition_evaluation("delete_#{bucket}") do
|
98
|
+
Frivol::Helpers.delete_counter(self, bucket)
|
99
|
+
end
|
100
|
+
end
|
95
101
|
else
|
96
102
|
define_method "store_#{bucket}" do |keys_and_values|
|
97
103
|
condition_evaluation("store_#{bucket}", keys_and_values) do
|
@@ -115,11 +121,11 @@ module Frivol
|
|
115
121
|
return result.first if result.size == 1
|
116
122
|
result
|
117
123
|
end
|
118
|
-
end
|
119
124
|
|
120
|
-
|
121
|
-
|
122
|
-
|
125
|
+
define_method "delete_#{bucket}" do
|
126
|
+
condition_evaluation("delete_#{bucket}") do
|
127
|
+
Frivol::Helpers.delete_hash(self, bucket)
|
128
|
+
end
|
123
129
|
end
|
124
130
|
end
|
125
131
|
|
data/lib/frivol/config.rb
CHANGED
@@ -3,31 +3,17 @@ module Frivol
|
|
3
3
|
# Sets the Frivol configuration (currently only the Redis config), allows access to the configured Redis instance,
|
4
4
|
# and has a helper method to include Frivol in a class with an optional storage expiry parameter
|
5
5
|
module Config
|
6
|
-
# Set the
|
6
|
+
# Set the Backend.
|
7
7
|
#
|
8
|
-
# Expects
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
# }
|
13
|
-
# Frivol::Config.redis_config = REDIS_CONFIG
|
14
|
-
def self.redis_config=(config)
|
15
|
-
@@redis_config = config
|
16
|
-
@@redis_version = nil
|
17
|
-
Thread.current[:frivol_redis] = nil
|
18
|
-
end
|
19
|
-
|
20
|
-
# Returns the configured Redis instance
|
21
|
-
def self.redis
|
22
|
-
Thread.current[:frivol_redis] ||= Redis.new(@@redis_config)
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.redis_version
|
26
|
-
redis.info('server')['redis_version'].to_f
|
8
|
+
# Expects one of Frivol::Backend::Redis, Frivol::Backend::RedisDistributed,
|
9
|
+
# Frivol::Backend::Riak or Frivol::Backend::Multi
|
10
|
+
def self.backend=(new_backend)
|
11
|
+
@@backend = new_backend
|
27
12
|
end
|
28
13
|
|
29
|
-
|
30
|
-
|
14
|
+
# Get the Backend.
|
15
|
+
def self.backend
|
16
|
+
@@backend
|
31
17
|
end
|
32
18
|
|
33
19
|
def self.allow_json_create
|
data/lib/frivol/helpers.rb
CHANGED
@@ -29,41 +29,23 @@ module Frivol
|
|
29
29
|
data, is_new = get_data_and_is_new instance
|
30
30
|
data[bucket.to_s] = hash
|
31
31
|
|
32
|
-
store_value instance, is_new[bucket.to_s], dump_json(hash), bucket
|
33
|
-
|
34
|
-
self.set_data_and_is_new instance, data, is_new
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.store_value(instance, is_new, value, bucket = nil)
|
38
32
|
key = instance.send(:storage_key, bucket)
|
39
33
|
time = instance.class.storage_expiry(bucket)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
time = redis.ttl(key).to_i unless is_new
|
44
|
-
Frivol::Config.redis.multi do |redis|
|
45
|
-
redis[key] = value
|
46
|
-
redis.expire(key, time)
|
47
|
-
end
|
48
|
-
elsif is_new
|
49
|
-
Frivol::Config.redis.multi do |redis|
|
50
|
-
redis[key] = value
|
51
|
-
redis.expire(key, time)
|
52
|
-
end
|
53
|
-
else
|
54
|
-
Frivol::Config.redis[key] = value
|
55
|
-
end
|
34
|
+
Frivol::Config.backend.set(key, dump_json(hash), is_new ? time : nil)
|
35
|
+
|
36
|
+
self.set_data_and_is_new instance, data, is_new
|
56
37
|
end
|
57
38
|
|
58
39
|
def self.retrieve_hash(instance, bucket = nil)
|
59
40
|
data, is_new = get_data_and_is_new instance
|
60
41
|
return data[bucket.to_s] if data.key?(bucket.to_s)
|
61
42
|
key = instance.send(:storage_key, bucket)
|
62
|
-
|
43
|
+
time = instance.class.storage_expiry(bucket)
|
44
|
+
json = Frivol::Config.backend.get(key, time).to_s
|
63
45
|
|
64
|
-
is_new[bucket.to_s] = json.
|
46
|
+
is_new[bucket.to_s] = json.empty?
|
65
47
|
|
66
|
-
hash = json.
|
48
|
+
hash = json.empty? ? {} : load_json(json)
|
67
49
|
data[bucket.to_s] = hash
|
68
50
|
|
69
51
|
self.set_data_and_is_new instance, data, is_new
|
@@ -72,7 +54,7 @@ module Frivol
|
|
72
54
|
|
73
55
|
def self.delete_hash(instance, bucket = nil)
|
74
56
|
key = instance.send(:storage_key, bucket)
|
75
|
-
Frivol::Config.
|
57
|
+
Frivol::Config.backend.del key
|
76
58
|
clear_hash(instance, bucket)
|
77
59
|
end
|
78
60
|
|
@@ -96,41 +78,57 @@ module Frivol
|
|
96
78
|
|
97
79
|
def self.store_counter(instance, counter, value)
|
98
80
|
key = instance.send(:storage_key, counter)
|
99
|
-
|
100
|
-
|
81
|
+
exists = Frivol::Config.backend.existsc(key)
|
82
|
+
time = instance.class.storage_expiry(counter)
|
83
|
+
Frivol::Config.backend.setc(key, value, exists ? nil : time)
|
101
84
|
end
|
102
85
|
|
103
86
|
def self.retrieve_counter(instance, counter, default)
|
104
87
|
key = instance.send(:storage_key, counter)
|
105
|
-
|
88
|
+
time = instance.class.storage_expiry(counter)
|
89
|
+
(Frivol::Config.backend.getc(key, time) || default).to_i
|
106
90
|
end
|
107
91
|
|
108
92
|
def self.increment_counter(instance, counter, seed_callback=nil)
|
109
93
|
key = instance.send(:storage_key, counter)
|
110
94
|
store_counter_seed_value(key, instance, counter, seed_callback)
|
111
|
-
Frivol::Config.
|
95
|
+
exists = Frivol::Config.backend.existsc(key)
|
96
|
+
time = instance.class.storage_expiry(counter)
|
97
|
+
Frivol::Config.backend.incr(key, exists ? nil : time)
|
112
98
|
end
|
113
99
|
|
114
100
|
def self.increment_counter_by(instance, counter, amount, seed_callback=nil)
|
115
101
|
key = instance.send(:storage_key, counter)
|
116
102
|
store_counter_seed_value(key, instance, counter, seed_callback)
|
117
|
-
Frivol::Config.
|
103
|
+
exists = Frivol::Config.backend.existsc(key)
|
104
|
+
time = instance.class.storage_expiry(counter)
|
105
|
+
Frivol::Config.backend.incrby(key, amount, exists ? nil : time)
|
118
106
|
end
|
119
107
|
|
120
108
|
def self.decrement_counter(instance, counter, seed_callback=nil)
|
121
109
|
key = instance.send(:storage_key, counter)
|
122
110
|
store_counter_seed_value(key, instance, counter, seed_callback)
|
123
|
-
Frivol::Config.
|
111
|
+
exists = Frivol::Config.backend.existsc(key)
|
112
|
+
time = instance.class.storage_expiry(counter)
|
113
|
+
Frivol::Config.backend.decr(key, exists ? nil : time)
|
124
114
|
end
|
125
115
|
|
126
116
|
def self.decrement_counter_by(instance, counter, amount, seed_callback=nil)
|
127
117
|
key = instance.send(:storage_key, counter)
|
128
118
|
store_counter_seed_value(key, instance, counter, seed_callback)
|
129
|
-
Frivol::Config.
|
119
|
+
exists = Frivol::Config.backend.existsc(key)
|
120
|
+
time = instance.class.storage_expiry(counter)
|
121
|
+
Frivol::Config.backend.decrby(key, amount, exists ? nil : time)
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.delete_counter(instance, counter = nil)
|
125
|
+
key = instance.send(:storage_key, counter)
|
126
|
+
Frivol::Config.backend.delc key
|
127
|
+
clear_hash(instance, counter)
|
130
128
|
end
|
131
129
|
|
132
130
|
def self.store_counter_seed_value(key, instance, counter, seed_callback)
|
133
|
-
unless Frivol::Config.
|
131
|
+
unless Frivol::Config.backend.existsc(key) || seed_callback.nil?
|
134
132
|
store_counter( instance, counter, seed_callback.call(instance))
|
135
133
|
end
|
136
134
|
end
|