moneta 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +17 -51
- data/CHANGES +13 -0
- data/Gemfile +4 -4
- data/README.md +79 -40
- data/Rakefile +40 -25
- data/benchmarks/run.rb +35 -5
- data/lib/moneta.rb +5 -5
- data/lib/moneta/adapters/activerecord.rb +4 -6
- data/lib/moneta/adapters/cassandra.rb +8 -11
- data/lib/moneta/adapters/couch.rb +3 -1
- data/lib/moneta/adapters/daybreak.rb +28 -0
- data/lib/moneta/adapters/fog.rb +3 -3
- data/lib/moneta/adapters/hbase.rb +2 -4
- data/lib/moneta/adapters/memcached/dalli.rb +8 -7
- data/lib/moneta/adapters/memcached/native.rb +8 -9
- data/lib/moneta/adapters/mongo.rb +42 -11
- data/lib/moneta/adapters/pstore.rb +4 -6
- data/lib/moneta/adapters/redis.rb +17 -10
- data/lib/moneta/adapters/restclient.rb +19 -10
- data/lib/moneta/adapters/sequel.rb +4 -6
- data/lib/moneta/adapters/tdb.rb +22 -0
- data/lib/moneta/expires.rb +28 -12
- data/lib/moneta/mixins.rb +64 -3
- data/lib/moneta/pool.rb +37 -0
- data/lib/moneta/proxy.rb +18 -7
- data/lib/moneta/server.rb +1 -1
- data/lib/moneta/shared.rb +2 -2
- data/lib/moneta/transformer/helper.rb +1 -1
- data/lib/moneta/version.rb +1 -1
- data/{spec/generate.rb → script/generate-specs.rb} +195 -91
- data/script/install-bundle.rb +35 -0
- data/spec/helper.rb +6 -0
- data/spec/moneta/adapter_activerecord_spec.rb +1 -1
- data/spec/moneta/adapter_cassandra_spec.rb +1 -12
- data/spec/moneta/adapter_cassandra_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_client_spec.rb +1 -1
- data/spec/moneta/adapter_cookie_spec.rb +1 -1
- data/spec/moneta/adapter_couch_spec.rb +1 -1
- data/spec/moneta/adapter_datamapper_spec.rb +1 -1
- data/spec/moneta/adapter_daybreak_spec.rb +19 -0
- data/spec/moneta/adapter_dbm_spec.rb +1 -1
- data/spec/moneta/adapter_file_spec.rb +1 -1
- data/spec/moneta/adapter_fog_spec.rb +1 -1
- data/spec/moneta/adapter_gdbm_spec.rb +1 -1
- data/spec/moneta/adapter_hbase_spec.rb +1 -1
- data/spec/moneta/adapter_leveldb_spec.rb +1 -1
- data/spec/moneta/adapter_localmemcache_spec.rb +1 -1
- data/spec/moneta/adapter_lruhash_spec.rb +1 -1
- data/spec/moneta/adapter_memcached_dalli_spec.rb +1 -12
- data/spec/moneta/adapter_memcached_dalli_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_memcached_native_spec.rb +1 -13
- data/spec/moneta/adapter_memcached_native_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_memcached_spec.rb +1 -12
- data/spec/moneta/adapter_memcached_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_memory_spec.rb +1 -1
- data/spec/moneta/adapter_mongo_spec.rb +9 -2
- data/spec/moneta/adapter_mongo_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_pstore_spec.rb +1 -1
- data/spec/moneta/adapter_redis_spec.rb +1 -12
- data/spec/moneta/adapter_redis_with_default_expires_spec.rb +21 -0
- data/spec/moneta/adapter_restclient_spec.rb +1 -1
- data/spec/moneta/adapter_riak_spec.rb +1 -1
- data/spec/moneta/adapter_sdbm_spec.rb +1 -1
- data/spec/moneta/adapter_sequel_spec.rb +1 -1
- data/spec/moneta/adapter_sqlite_spec.rb +1 -1
- data/spec/moneta/adapter_tdb_spec.rb +19 -0
- data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +1 -1
- data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +1 -1
- data/spec/moneta/adapter_yaml_spec.rb +1 -1
- data/spec/moneta/cache_file_memory_spec.rb +1 -1
- data/spec/moneta/cache_memory_null_spec.rb +1 -1
- data/spec/moneta/expires_file_spec.rb +1 -1
- data/spec/moneta/expires_memory_spec.rb +1 -12
- data/spec/moneta/expires_memory_with_default_expires_spec.rb +111 -0
- data/spec/moneta/lock_spec.rb +1 -1
- data/spec/moneta/null_adapter_spec.rb +1 -1
- data/spec/moneta/optionmerger_spec.rb +1 -1
- data/spec/moneta/pool_spec.rb +23 -0
- data/spec/moneta/proxy_expires_memory_spec.rb +1 -1
- data/spec/moneta/proxy_redis_spec.rb +1 -1
- data/spec/moneta/shared_spec.rb +1 -1
- data/spec/moneta/simple_activerecord_spec.rb +1 -1
- data/spec/moneta/simple_activerecord_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_cassandra_spec.rb +1 -1
- data/spec/moneta/simple_client_tcp_spec.rb +1 -1
- data/spec/moneta/simple_client_unix_spec.rb +1 -1
- data/spec/moneta/simple_couch_spec.rb +1 -1
- data/spec/moneta/simple_couch_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_datamapper_spec.rb +1 -1
- data/spec/moneta/simple_datamapper_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_datamapper_with_repository_spec.rb +1 -1
- data/spec/moneta/simple_daybreak_spec.rb +144 -0
- data/spec/moneta/simple_daybreak_with_expires_spec.rb +145 -0
- data/spec/moneta/simple_dbm_spec.rb +1 -1
- data/spec/moneta/simple_dbm_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_file_spec.rb +1 -1
- data/spec/moneta/simple_file_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_fog_spec.rb +1 -1
- data/spec/moneta/simple_fog_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_gdbm_spec.rb +1 -1
- data/spec/moneta/simple_gdbm_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_hashfile_spec.rb +1 -1
- data/spec/moneta/simple_hashfile_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_hbase_spec.rb +1 -1
- data/spec/moneta/simple_hbase_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_leveldb_spec.rb +1 -1
- data/spec/moneta/simple_leveldb_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_localmemcache_spec.rb +1 -1
- data/spec/moneta/simple_localmemcache_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_lruhash_spec.rb +1 -1
- data/spec/moneta/simple_lruhash_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_memcached_dalli_spec.rb +1 -1
- data/spec/moneta/simple_memcached_native_spec.rb +1 -1
- data/spec/moneta/simple_memcached_spec.rb +1 -1
- data/spec/moneta/simple_memory_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_compress_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_json_serializer_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_prefix_spec.rb +1 -1
- data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +1 -1
- data/spec/moneta/simple_mongo_spec.rb +3 -2
- data/spec/moneta/simple_null_spec.rb +1 -1
- data/spec/moneta/simple_pstore_spec.rb +1 -1
- data/spec/moneta/simple_pstore_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_redis_spec.rb +1 -1
- data/spec/moneta/simple_restclient_spec.rb +1 -1
- data/spec/moneta/simple_riak_spec.rb +1 -1
- data/spec/moneta/simple_riak_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_sdbm_spec.rb +1 -1
- data/spec/moneta/simple_sdbm_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_sequel_spec.rb +1 -1
- data/spec/moneta/simple_sequel_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_sqlite_spec.rb +1 -1
- data/spec/moneta/simple_sqlite_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_tdb_spec.rb +144 -0
- data/spec/moneta/{simple_mongo_with_expires_spec.rb → simple_tdb_with_expires_spec.rb} +4 -4
- data/spec/moneta/simple_tokyocabinet_spec.rb +1 -1
- data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_yaml_spec.rb +1 -1
- data/spec/moneta/simple_yaml_with_expires_spec.rb +1 -1
- data/spec/moneta/stack_file_memory_spec.rb +1 -1
- data/spec/moneta/stack_memory_file_spec.rb +1 -1
- data/spec/moneta/transformer_bencode_spec.rb +1 -1
- data/spec/moneta/transformer_bert_spec.rb +1 -1
- data/spec/moneta/transformer_bson_spec.rb +1 -1
- data/spec/moneta/transformer_bzip2_spec.rb +1 -1
- data/spec/moneta/transformer_json_spec.rb +1 -1
- data/spec/moneta/transformer_key_marshal_spec.rb +1 -1
- data/spec/moneta/transformer_key_yaml_spec.rb +1 -1
- data/spec/moneta/transformer_lzma_spec.rb +1 -1
- data/spec/moneta/transformer_lzo_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_base64_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_escape_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_hmac_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_md5_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_md5_spread_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_prefix_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_rmd160_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_sha1_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_sha256_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_sha384_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_sha512_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_truncate_spec.rb +1 -1
- data/spec/moneta/transformer_marshal_uuencode_spec.rb +1 -1
- data/spec/moneta/transformer_msgpack_spec.rb +1 -1
- data/spec/moneta/transformer_ox_spec.rb +1 -1
- data/spec/moneta/transformer_quicklz_spec.rb +1 -1
- data/spec/moneta/transformer_snappy_spec.rb +1 -1
- data/spec/moneta/transformer_tnet_spec.rb +1 -1
- data/spec/moneta/transformer_value_marshal_spec.rb +1 -1
- data/spec/moneta/transformer_value_yaml_spec.rb +1 -1
- data/spec/moneta/transformer_yaml_spec.rb +1 -1
- data/spec/moneta/transformer_zlib_spec.rb +1 -1
- data/spec/monetaspecs.rb +105 -3
- metadata +35 -6
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'net/http'
|
2
2
|
|
3
3
|
module Moneta
|
4
4
|
module Adapters
|
@@ -10,38 +10,47 @@ module Moneta
|
|
10
10
|
# @param [Hash] options
|
11
11
|
# @option options [String] :url URL
|
12
12
|
def initialize(options = {})
|
13
|
-
raise ArgumentError, 'Option :url is required' unless
|
13
|
+
raise ArgumentError, 'Option :url is required' unless url = options[:url]
|
14
|
+
url = URI(url)
|
15
|
+
@path = url.path
|
16
|
+
@client = ::Net::HTTP.start(url.host, url.port)
|
14
17
|
end
|
15
18
|
|
16
19
|
# (see Proxy#key?)
|
17
20
|
def key?(key, options = {})
|
18
|
-
response =
|
19
|
-
response.code == 200
|
21
|
+
response = @client.request_head(@path + key)
|
22
|
+
response.code == '200'
|
20
23
|
end
|
21
24
|
|
22
25
|
# (see Proxy#load)
|
23
26
|
def load(key, options = {})
|
24
|
-
response =
|
25
|
-
response.code == 200 ? response.body : nil
|
27
|
+
response = @client.request_get(@path + key)
|
28
|
+
response.code == '200' ? response.body : nil
|
26
29
|
end
|
27
30
|
|
28
31
|
# (see Proxy#store)
|
29
32
|
def store(key, value, options = {})
|
30
|
-
|
33
|
+
response = @client.request_post(@path + key, value)
|
34
|
+
raise "HTTP error #{response.code}" unless response.code == '200'
|
31
35
|
value
|
32
36
|
end
|
33
37
|
|
34
38
|
# (see Proxy#delete)
|
35
39
|
def delete(key, options = {})
|
36
|
-
response =
|
37
|
-
response.code == 200 ? response.body : nil
|
40
|
+
response = @client.request(::Net::HTTP::Delete.new(@path + key))
|
41
|
+
response.code == '200' ? response.body : nil
|
38
42
|
end
|
39
43
|
|
40
44
|
# (see Proxy#clear)
|
41
45
|
def clear(options = {})
|
42
|
-
|
46
|
+
@client.request(::Net::HTTP::Delete.new(@path))
|
43
47
|
self
|
44
48
|
end
|
49
|
+
|
50
|
+
def close
|
51
|
+
@client.finish
|
52
|
+
nil
|
53
|
+
end
|
45
54
|
end
|
46
55
|
end
|
47
56
|
end
|
@@ -6,6 +6,7 @@ module Moneta
|
|
6
6
|
# @api public
|
7
7
|
class Sequel
|
8
8
|
include Defaults
|
9
|
+
include IncrementSupport
|
9
10
|
|
10
11
|
# @param [Hash] options
|
11
12
|
# @option options [String] :db Sequel database
|
@@ -50,12 +51,9 @@ module Moneta
|
|
50
51
|
@db.transaction do
|
51
52
|
locked_table = @table.for_update
|
52
53
|
if record = locked_table[:k => key]
|
53
|
-
value = record[:v]
|
54
|
-
|
55
|
-
|
56
|
-
intvalue += amount
|
57
|
-
locked_table.update(:k => key, :v => intvalue.to_s)
|
58
|
-
intvalue
|
54
|
+
value = convert_for_increment(record[:v]) + amount
|
55
|
+
locked_table.update(:k => key, :v => value.to_s)
|
56
|
+
value
|
59
57
|
else
|
60
58
|
locked_table.insert(:k => key, :v => amount.to_s)
|
61
59
|
amount
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'tdb'
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
module Adapters
|
5
|
+
# TDB backend
|
6
|
+
# @api public
|
7
|
+
class TDB < Memory
|
8
|
+
# @param [Hash] options
|
9
|
+
# @option options [String] :file Database file
|
10
|
+
def initialize(options = {})
|
11
|
+
raise ArgumentError, 'Option :file is required' unless file = options.delete(:file)
|
12
|
+
@hash = ::TDB.new(file, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
# (see Proxy#close)
|
16
|
+
def close
|
17
|
+
@hash.close
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/moneta/expires.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
module Moneta
|
2
2
|
# Adds expiration support to the underlying store
|
3
3
|
#
|
4
|
-
#
|
4
|
+
# `#store`, `#load` and `#key?` support the `:expires` option to set/update
|
5
5
|
# the expiration time.
|
6
6
|
#
|
7
7
|
# @api public
|
8
8
|
class Expires < Proxy
|
9
|
+
include ExpiresSupport
|
10
|
+
|
9
11
|
# @param [Moneta store] adapter The underlying store
|
10
12
|
# @param [Hash] options
|
11
13
|
# @option options [String] :expires Default expiration time
|
12
14
|
def initialize(adapter, options = {})
|
13
15
|
super
|
14
|
-
|
16
|
+
self.default_expires = options[:expires]
|
15
17
|
end
|
16
18
|
|
17
19
|
# (see Proxy#key?)
|
@@ -33,14 +35,12 @@ module Moneta
|
|
33
35
|
# (see Proxy#store)
|
34
36
|
def store(key, value, options = {})
|
35
37
|
return super if options.include?(:raw)
|
36
|
-
expires =
|
37
|
-
if expires
|
38
|
-
|
39
|
-
|
40
|
-
super(key, [value], options)
|
41
|
-
else
|
42
|
-
super(key, value, options)
|
38
|
+
expires = expires_at(options)
|
39
|
+
if options.include?(:expires)
|
40
|
+
options = options.dup
|
41
|
+
options.delete(:expires)
|
43
42
|
end
|
43
|
+
store_entry(key, value, expires, options)
|
44
44
|
value
|
45
45
|
end
|
46
46
|
|
@@ -54,20 +54,36 @@ module Moneta
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def load_entry(key, options)
|
57
|
-
new_expires =
|
57
|
+
new_expires = expires_at(options, nil)
|
58
|
+
if options.include?(:expires)
|
59
|
+
options = options.dup
|
60
|
+
options.delete(:expires)
|
61
|
+
end
|
58
62
|
entry = @adapter.load(key, options)
|
59
63
|
if entry != nil
|
60
64
|
value, expires = entry
|
61
65
|
if expires && Time.now.to_i > expires
|
62
66
|
delete(key)
|
63
67
|
nil
|
64
|
-
elsif new_expires
|
65
|
-
|
68
|
+
elsif new_expires != nil
|
69
|
+
store_entry(key, value, new_expires, options)
|
66
70
|
entry
|
67
71
|
else
|
68
72
|
entry
|
69
73
|
end
|
70
74
|
end
|
71
75
|
end
|
76
|
+
|
77
|
+
def store_entry(key, value, expires, options)
|
78
|
+
entry =
|
79
|
+
if expires
|
80
|
+
[value, expires.to_i]
|
81
|
+
elsif Array === value || value == nil
|
82
|
+
[value]
|
83
|
+
else
|
84
|
+
value
|
85
|
+
end
|
86
|
+
@adapter.store(key, entry, options)
|
87
|
+
end
|
72
88
|
end
|
73
89
|
end
|
data/lib/moneta/mixins.rb
CHANGED
@@ -51,6 +51,9 @@ module Moneta
|
|
51
51
|
#
|
52
52
|
# @param [Object] key
|
53
53
|
# @param [Hash] options
|
54
|
+
# @option options [Integer] :expires Update expiration time (See `Moneta::Expires`)
|
55
|
+
# @option options [String] :prefix Prefix key (See `Moneta::Transformer`)
|
56
|
+
# @option options Other options as defined by the adapters or middleware
|
54
57
|
# @return [Boolean]
|
55
58
|
# @api public
|
56
59
|
def key?(key, options = {})
|
@@ -146,11 +149,16 @@ module Moneta
|
|
146
149
|
# (see Defaults#increment)
|
147
150
|
# @api public
|
148
151
|
def increment(key, amount = 1, options = {})
|
149
|
-
value = load(key, options)
|
152
|
+
value = convert_for_increment(load(key, options)) + amount
|
153
|
+
store(key, value.to_s, options)
|
154
|
+
value
|
155
|
+
end
|
156
|
+
|
157
|
+
protected
|
158
|
+
|
159
|
+
def convert_for_increment(value)
|
150
160
|
intvalue = value.to_i
|
151
161
|
raise 'Tried to increment non integer value' unless value == nil || intvalue.to_s == value.to_s
|
152
|
-
intvalue += amount
|
153
|
-
store(key, intvalue.to_s, options)
|
154
162
|
intvalue
|
155
163
|
end
|
156
164
|
end
|
@@ -204,4 +212,57 @@ module Moneta
|
|
204
212
|
io.write(pack(o))
|
205
213
|
end
|
206
214
|
end
|
215
|
+
|
216
|
+
# This mixin handles the calculation of expiration times.
|
217
|
+
#
|
218
|
+
#
|
219
|
+
module ExpiresSupport
|
220
|
+
attr_accessor :default_expires
|
221
|
+
|
222
|
+
protected
|
223
|
+
|
224
|
+
# Calculates the time when something will expire.
|
225
|
+
#
|
226
|
+
# This method considers false and 0 as "no-expire" and every positive
|
227
|
+
# number as a time to live in seconds.
|
228
|
+
#
|
229
|
+
# @param [Hash] options Options hash
|
230
|
+
# @option options [0,false,nil,Numeric] :expires expires value given by user
|
231
|
+
# @param [0,false,nil,Numeric] default default expiration time
|
232
|
+
#
|
233
|
+
# @return [false] if it should not expire
|
234
|
+
# @return [Time] the time when something should expire
|
235
|
+
# @return [nil] if it is not known
|
236
|
+
def expires_at(options, default = @default_expires)
|
237
|
+
value = expires_value(options, default)
|
238
|
+
Numeric === value ? Time.now + value : value
|
239
|
+
end
|
240
|
+
|
241
|
+
# Calculates the number of seconds something should last.
|
242
|
+
#
|
243
|
+
# This method considers false and 0 as "no-expire" and every positive
|
244
|
+
# number as a time to live in seconds.
|
245
|
+
#
|
246
|
+
# @param [Hash] options Options hash
|
247
|
+
# @option options [0,false,nil,Numeric] :expires expires value given by user
|
248
|
+
# @param [0,false,nil,Numeric] default default expiration time
|
249
|
+
#
|
250
|
+
# @return [false] if it should not expire
|
251
|
+
# @return [Numeric] seconds until expiration
|
252
|
+
# @return [nil] if it is not known
|
253
|
+
def expires_value(options, default = @default_expires)
|
254
|
+
case value = options[:expires]
|
255
|
+
when 0, false
|
256
|
+
false
|
257
|
+
when nil
|
258
|
+
default ? default.to_i : nil
|
259
|
+
when Numeric
|
260
|
+
value = value.to_i
|
261
|
+
raise ArgumentError, ":expires must be a positive value, got #{value}" if value < 0
|
262
|
+
value
|
263
|
+
else
|
264
|
+
raise ArgumentError, ":expires must be Numeric or false, got #{value.inspect}"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
207
268
|
end
|
data/lib/moneta/pool.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Moneta
|
2
|
+
# Creates a pool of stores.
|
3
|
+
# Each thread gets its own store.
|
4
|
+
#
|
5
|
+
# @example Add `Moneta::Pool` to proxy stack
|
6
|
+
# Moneta.build do
|
7
|
+
# use(:Pool) do
|
8
|
+
# # Every thread gets its own instance
|
9
|
+
# adapter :MemcachedNative
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# @api public
|
14
|
+
class Pool < Wrapper
|
15
|
+
# @param [Moneta store] adapter The underlying store
|
16
|
+
# @param [Hash] options
|
17
|
+
def initialize(options = {}, &block)
|
18
|
+
super(nil)
|
19
|
+
@builder = Builder.new(&block)
|
20
|
+
@pool, @active = [], {}
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def adapter
|
26
|
+
@active[Thread.current]
|
27
|
+
end
|
28
|
+
|
29
|
+
def wrap(*args)
|
30
|
+
@pool << @builder.build.last if @pool.empty?
|
31
|
+
@active[Thread.current] = @pool.pop
|
32
|
+
yield
|
33
|
+
ensure
|
34
|
+
@pool << @active.delete(Thread.current)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/moneta/proxy.rb
CHANGED
@@ -14,27 +14,31 @@ module Moneta
|
|
14
14
|
|
15
15
|
# (see Defaults#key?)
|
16
16
|
def key?(key, options = {})
|
17
|
-
|
17
|
+
adapter.key?(key, options)
|
18
18
|
end
|
19
19
|
|
20
20
|
# (see Defaults#increment)
|
21
21
|
def increment(key, amount = 1, options = {})
|
22
|
-
|
22
|
+
adapter.increment(key, amount, options)
|
23
23
|
end
|
24
24
|
|
25
25
|
# (see Defaults#close)
|
26
26
|
def close
|
27
|
-
|
27
|
+
adapter.close
|
28
28
|
end
|
29
29
|
|
30
30
|
# Fetch value with key. Return nil if the key doesn't exist
|
31
31
|
#
|
32
32
|
# @param [Object] key
|
33
33
|
# @param [Hash] options
|
34
|
+
# @option options [Integer] :expires Update expiration time (See `Moneta::Expires`)
|
35
|
+
# @option options [Boolean] :raw Raw access without value transformation (See `Moneta::Transformer`)
|
36
|
+
# @option options [String] :prefix Prefix key (See `Moneta::Transformer`)
|
37
|
+
# @option options Other options as defined by the adapters or middleware
|
34
38
|
# @return [Object] value
|
35
39
|
# @api public
|
36
40
|
def load(key, options = {})
|
37
|
-
|
41
|
+
adapter.load(key, options)
|
38
42
|
end
|
39
43
|
|
40
44
|
# Store value with key
|
@@ -42,10 +46,14 @@ module Moneta
|
|
42
46
|
# @param [Object] key
|
43
47
|
# @param [Object] value
|
44
48
|
# @param [Hash] options
|
49
|
+
# @option options [Integer] :expires Set expiration time (See `Moneta::Expires`)
|
50
|
+
# @option options [Boolean] :raw Raw access without value transformation (See `Moneta::Transformer`)
|
51
|
+
# @option options [String] :prefix Prefix key (See `Moneta::Transformer`)
|
52
|
+
# @option options Other options as defined by the adapters or middleware
|
45
53
|
# @return value
|
46
54
|
# @api public
|
47
55
|
def store(key, value, options = {})
|
48
|
-
|
56
|
+
adapter.store(key, value, options)
|
49
57
|
end
|
50
58
|
|
51
59
|
# Delete the key from the store and return the current value
|
@@ -53,9 +61,12 @@ module Moneta
|
|
53
61
|
# @param [Object] key
|
54
62
|
# @return [Object] current value
|
55
63
|
# @param [Hash] options
|
64
|
+
# @option options [Boolean] :raw Raw access without value transformation (See `Moneta::Transformer`)
|
65
|
+
# @option options [String] :prefix Prefix key (See `Moneta::Transformer`)
|
66
|
+
# @option options Other options as defined by the adapters or middleware
|
56
67
|
# @api public
|
57
68
|
def delete(key, options = {})
|
58
|
-
|
69
|
+
adapter.delete(key, options)
|
59
70
|
end
|
60
71
|
|
61
72
|
# Clear all keys in this store
|
@@ -64,7 +75,7 @@ module Moneta
|
|
64
75
|
# @return [void]
|
65
76
|
# @api public
|
66
77
|
def clear(options = {})
|
67
|
-
|
78
|
+
adapter.clear(options)
|
68
79
|
self
|
69
80
|
end
|
70
81
|
end
|
data/lib/moneta/server.rb
CHANGED
data/lib/moneta/shared.rb
CHANGED
@@ -39,7 +39,7 @@ module Moneta
|
|
39
39
|
@adapter ||= Adapters::Client.new(@options)
|
40
40
|
yield
|
41
41
|
rescue Exception => ex
|
42
|
-
|
42
|
+
warn "Failed to connect: #{ex.message}"
|
43
43
|
begin
|
44
44
|
# TODO: Implement this using forking (MRI) and threading (JRuby)
|
45
45
|
# to get maximal performance
|
@@ -48,7 +48,7 @@ module Moneta
|
|
48
48
|
@thread = Thread.new { @server.run }
|
49
49
|
sleep 0.1 until @server.running?
|
50
50
|
rescue Exception => ex
|
51
|
-
|
51
|
+
warn "Failed to start server: #{ex.message}"
|
52
52
|
@adapter.close if @adapter
|
53
53
|
@adapter = nil
|
54
54
|
end
|
data/lib/moneta/version.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
PATH = File.expand_path(File.join(__FILE__, '..', '..', 'spec'))
|
4
|
+
|
1
5
|
class Specs
|
2
6
|
attr_reader :key, :value, :specs
|
3
7
|
|
@@ -93,13 +97,19 @@ class Specs
|
|
93
97
|
a.delete(:marshallable_value)
|
94
98
|
Specs.new(a, key, value)
|
95
99
|
end
|
100
|
+
|
101
|
+
def with_default_expires
|
102
|
+
a = specs.dup
|
103
|
+
a << :default_expires
|
104
|
+
Specs.new(a, key, value)
|
105
|
+
end
|
96
106
|
end
|
97
107
|
|
98
108
|
ADAPTER_SPECS = Specs.new([:null, :store, :returndifferent, :increment, :persist], %w(string), %w(string))
|
99
109
|
STANDARD_SPECS = Specs.new([:null, :store, :returndifferent, :marshallable_key, :marshallable_value, :transform_value, :increment, :persist])
|
100
110
|
TRANSFORMER_SPECS = Specs.new([:null, :store, :returndifferent, :transform_value, :increment])
|
101
111
|
|
102
|
-
header = "# Generated by #{__FILE__}\n"
|
112
|
+
header = "# Generated by #{File.basename(__FILE__)}\n"
|
103
113
|
|
104
114
|
TESTS = {
|
105
115
|
'simple_client_tcp' => {
|
@@ -232,6 +242,26 @@ end
|
|
232
242
|
:options => ':file => File.join(make_tempdir, "simple_dbm_with_expires"), :expires => true',
|
233
243
|
:specs => STANDARD_SPECS.with_expires
|
234
244
|
},
|
245
|
+
'simple_tdb' => {
|
246
|
+
:store => :TDB,
|
247
|
+
:options => ':file => File.join(make_tempdir, "simple_tdb")',
|
248
|
+
:specs => STANDARD_SPECS
|
249
|
+
},
|
250
|
+
'simple_tdb_with_expires' => {
|
251
|
+
:store => :TDB,
|
252
|
+
:options => ':file => File.join(make_tempdir, "simple_tdb_with_expires"), :expires => true',
|
253
|
+
:specs => STANDARD_SPECS.with_expires
|
254
|
+
},
|
255
|
+
'simple_daybreak' => {
|
256
|
+
:store => :Daybreak,
|
257
|
+
:options => ':file => File.join(make_tempdir, "simple_daybreak")',
|
258
|
+
:specs => STANDARD_SPECS
|
259
|
+
},
|
260
|
+
'simple_daybreak_with_expires' => {
|
261
|
+
:store => :Daybreak,
|
262
|
+
:options => ':file => File.join(make_tempdir, "simple_daybreak_with_expires"), :expires => true',
|
263
|
+
:specs => STANDARD_SPECS.with_expires
|
264
|
+
},
|
235
265
|
'simple_gdbm' => {
|
236
266
|
:store => :GDBM,
|
237
267
|
:options => ':file => File.join(make_tempdir, "simple_gdbm")',
|
@@ -364,12 +394,7 @@ end
|
|
364
394
|
'simple_mongo' => {
|
365
395
|
:store => :Mongo,
|
366
396
|
:options => ":db => 'simple_mongo'",
|
367
|
-
:specs => STANDARD_SPECS.
|
368
|
-
},
|
369
|
-
'simple_mongo_with_expires' => {
|
370
|
-
:store => :Mongo,
|
371
|
-
:options => ":db => 'simple_mongo_with_expires', :expires => true",
|
372
|
-
:specs => STANDARD_SPECS.without_increment.with_expires
|
397
|
+
:specs => STANDARD_SPECS.with_native_expires
|
373
398
|
},
|
374
399
|
'simple_null' => {
|
375
400
|
:store => :Null,
|
@@ -453,19 +478,14 @@ end
|
|
453
478
|
use :Expires
|
454
479
|
adapter :Memory
|
455
480
|
end},
|
456
|
-
:specs => STANDARD_SPECS.without_transform.with_expires.without_persist
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
store.load('key1').should == 'val1'
|
465
|
-
sleep 2
|
466
|
-
store.load('key1').should be_nil
|
467
|
-
store['key2'].should == 'val2'
|
468
|
-
end}
|
481
|
+
:specs => STANDARD_SPECS.without_transform.with_expires.without_persist
|
482
|
+
},
|
483
|
+
'expires_memory_with_default_expires' => {
|
484
|
+
:build => %{Moneta.build do
|
485
|
+
use :Expires, :expires => 1
|
486
|
+
adapter :Memory
|
487
|
+
end},
|
488
|
+
:specs => STANDARD_SPECS.without_transform.with_expires.with_default_expires.without_persist
|
469
489
|
},
|
470
490
|
'expires_file' => {
|
471
491
|
:build => %{Moneta.build do
|
@@ -580,6 +600,14 @@ end},
|
|
580
600
|
end},
|
581
601
|
:specs => STANDARD_SPECS.without_transform.without_returndifferent.without_persist
|
582
602
|
},
|
603
|
+
'pool' => {
|
604
|
+
:build => %{Moneta.build do
|
605
|
+
use :Pool do
|
606
|
+
adapter :File, :dir => File.join(make_tempdir, "pool")
|
607
|
+
end
|
608
|
+
end},
|
609
|
+
:specs => ADAPTER_SPECS
|
610
|
+
},
|
583
611
|
'transformer_zlib' => {
|
584
612
|
:build => %{Moneta.build do
|
585
613
|
use :Transformer, :value => :zlib
|
@@ -857,19 +885,11 @@ end
|
|
857
885
|
},
|
858
886
|
'adapter_cassandra' => {
|
859
887
|
:build => "Moneta::Adapters::Cassandra.new(:keyspace => 'adapter_cassandra')",
|
860
|
-
:specs => ADAPTER_SPECS.without_increment.
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
store.store('key2', 'val2', :expires => 60)
|
866
|
-
store.load('key1').should == 'val1'
|
867
|
-
sleep 1
|
868
|
-
store.load('key1').should == 'val1'
|
869
|
-
sleep 2
|
870
|
-
store.load('key1').should be_nil
|
871
|
-
store['key2'].should == 'val2'
|
872
|
-
end}
|
888
|
+
:specs => ADAPTER_SPECS.without_increment.with_native_expires
|
889
|
+
},
|
890
|
+
'adapter_cassandra_with_default_expires' => {
|
891
|
+
:build => %{Moneta::Adapters::Cassandra.new(:expires => 1)},
|
892
|
+
:specs => ADAPTER_SPECS.without_increment.with_native_expires.with_default_expires
|
873
893
|
},
|
874
894
|
'adapter_hbase' => {
|
875
895
|
:build => "Moneta::Adapters::HBase.new(:table => 'adapter_hbase')",
|
@@ -923,6 +943,14 @@ end
|
|
923
943
|
:build => 'Moneta::Adapters::DBM.new(:file => File.join(make_tempdir, "adapter_dbm"))',
|
924
944
|
:specs => ADAPTER_SPECS
|
925
945
|
},
|
946
|
+
'adapter_tdb' => {
|
947
|
+
:build => 'Moneta::Adapters::TDB.new(:file => File.join(make_tempdir, "adapter_tdb"))',
|
948
|
+
:specs => ADAPTER_SPECS
|
949
|
+
},
|
950
|
+
'adapter_daybreak' => {
|
951
|
+
:build => 'Moneta::Adapters::Daybreak.new(:file => File.join(make_tempdir, "adapter_daybreak"))',
|
952
|
+
:specs => ADAPTER_SPECS
|
953
|
+
},
|
926
954
|
'adapter_file' => {
|
927
955
|
:build => 'Moneta::Adapters::File.new(:dir => File.join(make_tempdir, "adapter_file"))',
|
928
956
|
:specs => ADAPTER_SPECS
|
@@ -946,52 +974,27 @@ end
|
|
946
974
|
},
|
947
975
|
'adapter_memcached_dalli' => {
|
948
976
|
:build => 'Moneta::Adapters::MemcachedDalli.new(:namespace => "adapter_memcached_dalli")',
|
949
|
-
:specs => ADAPTER_SPECS.
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
store.store('key2', 'val2', :expires => 60)
|
955
|
-
store.load('key1').should == 'val1'
|
956
|
-
sleep 1
|
957
|
-
store.load('key1').should == 'val1'
|
958
|
-
sleep 2
|
959
|
-
store.load('key1').should be_nil
|
960
|
-
store['key2'].should == 'val2'
|
961
|
-
end}
|
977
|
+
:specs => ADAPTER_SPECS.with_native_expires
|
978
|
+
},
|
979
|
+
'adapter_memcached_dalli_with_default_expires' => {
|
980
|
+
:build => %{Moneta::Adapters::MemcachedDalli.new(:expires => 1)},
|
981
|
+
:specs => ADAPTER_SPECS.with_native_expires.with_default_expires
|
962
982
|
},
|
963
983
|
'adapter_memcached_native' => {
|
964
984
|
:build => 'Moneta::Adapters::MemcachedNative.new(:namespace => "adapter_memcached_native")',
|
965
|
-
:specs => ADAPTER_SPECS.
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
store.store('key2', 'val2', :expires => 60)
|
971
|
-
store.load('key1').should == 'val1'
|
972
|
-
sleep 1
|
973
|
-
store.load('key1').should == 'val1'
|
974
|
-
sleep 2
|
975
|
-
store.load('key1').should be_nil
|
976
|
-
store['key2'].should == 'val2'
|
977
|
-
end
|
978
|
-
}
|
985
|
+
:specs => ADAPTER_SPECS.with_native_expires
|
986
|
+
},
|
987
|
+
'adapter_memcached_native_with_default_expires' => {
|
988
|
+
:build => %{Moneta::Adapters::MemcachedNative.new(:expires => 1)},
|
989
|
+
:specs => ADAPTER_SPECS.with_native_expires.with_default_expires
|
979
990
|
},
|
980
991
|
'adapter_memcached' => {
|
981
992
|
:build => 'Moneta::Adapters::Memcached.new(:namespace => "adapter_memcached")',
|
982
|
-
:specs => ADAPTER_SPECS.
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
store.store('key2', 'val2', :expires => 60)
|
988
|
-
store.load('key1').should == 'val1'
|
989
|
-
sleep 1
|
990
|
-
store.load('key1').should == 'val1'
|
991
|
-
sleep 2
|
992
|
-
store.load('key1').should be_nil
|
993
|
-
store['key2'].should == 'val2'
|
994
|
-
end}
|
993
|
+
:specs => ADAPTER_SPECS.with_native_expires
|
994
|
+
},
|
995
|
+
'adapter_memcached_with_default_expires' => {
|
996
|
+
:build => %{Moneta::Adapters::Memcached.new(:expires => 1)},
|
997
|
+
:specs => ADAPTER_SPECS.with_native_expires.with_default_expires
|
995
998
|
},
|
996
999
|
'adapter_memory' => {
|
997
1000
|
:build => 'Moneta::Adapters::Memory.new',
|
@@ -1017,7 +1020,18 @@ end}
|
|
1017
1020
|
},
|
1018
1021
|
'adapter_mongo' => {
|
1019
1022
|
:build => 'Moneta::Adapters::Mongo.new(:db => "adapter_mongo")',
|
1020
|
-
:specs => ADAPTER_SPECS.
|
1023
|
+
:specs => ADAPTER_SPECS.with_native_expires,
|
1024
|
+
:tests => %{
|
1025
|
+
it 'automatically deletes expired document' do
|
1026
|
+
store.store('key', 'val', :expires => 30)
|
1027
|
+
store.instance_variable_get(:@collection).find_one('_id' => ::BSON::Binary.new('key')).should_not be_nil
|
1028
|
+
sleep 70 # Mongo needs up to 60 seconds
|
1029
|
+
store.instance_variable_get(:@collection).find_one('_id' => ::BSON::Binary.new('key')).should be_nil
|
1030
|
+
end}
|
1031
|
+
},
|
1032
|
+
'adapter_mongo_with_default_expires' => {
|
1033
|
+
:build => %{Moneta::Adapters::Mongo.new(:expires => 1)},
|
1034
|
+
:specs => ADAPTER_SPECS.with_expires.with_default_expires
|
1021
1035
|
},
|
1022
1036
|
'adapter_pstore' => {
|
1023
1037
|
:build => 'Moneta::Adapters::PStore.new(:file => File.join(make_tempdir, "adapter_pstore"))',
|
@@ -1025,19 +1039,11 @@ end}
|
|
1025
1039
|
},
|
1026
1040
|
'adapter_redis' => {
|
1027
1041
|
:build => 'Moneta::Adapters::Redis.new',
|
1028
|
-
:specs => ADAPTER_SPECS.
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
store.store('key2', 'val2', :expires => 60)
|
1034
|
-
store.load('key1').should == 'val1'
|
1035
|
-
sleep 1
|
1036
|
-
store.load('key1').should == 'val1'
|
1037
|
-
sleep 2
|
1038
|
-
store.load('key1').should be_nil
|
1039
|
-
store['key2'].should == 'val2'
|
1040
|
-
end}
|
1042
|
+
:specs => ADAPTER_SPECS.with_native_expires
|
1043
|
+
},
|
1044
|
+
'adapter_redis_with_default_expires' => {
|
1045
|
+
:build => %{Moneta::Adapters::Redis.new(:expires => 1)},
|
1046
|
+
:specs => ADAPTER_SPECS.with_native_expires.with_default_expires
|
1041
1047
|
},
|
1042
1048
|
'adapter_riak' => {
|
1043
1049
|
:build => 'Moneta::Adapters::Riak.new',
|
@@ -1330,6 +1336,20 @@ SPECS['expires'] = %{it 'supports expires on store and #[]' do
|
|
1330
1336
|
store['key1'].should be_nil
|
1331
1337
|
end
|
1332
1338
|
|
1339
|
+
it 'supports 0 as no-expires on store and #[]' do
|
1340
|
+
store.store('key1', 'val1', :expires => 0)
|
1341
|
+
store['key1'].should == 'val1'
|
1342
|
+
sleep 2
|
1343
|
+
store['key1'].should == 'val1'
|
1344
|
+
end
|
1345
|
+
|
1346
|
+
it 'supports false as no-expires on store and #[]' do
|
1347
|
+
store.store('key1', 'val1', :expires => false)
|
1348
|
+
store['key1'].should == 'val1'
|
1349
|
+
sleep 2
|
1350
|
+
store['key1'].should == 'val1'
|
1351
|
+
end
|
1352
|
+
|
1333
1353
|
it 'supports expires on store and load' do
|
1334
1354
|
store.store('key1', 'val1', :expires => 2)
|
1335
1355
|
store.load('key1').should == 'val1'
|
@@ -1360,6 +1380,20 @@ it 'supports updating the expiration time in load' do
|
|
1360
1380
|
store['key2'].should be_nil
|
1361
1381
|
end
|
1362
1382
|
|
1383
|
+
it 'supports 0 as no-expires in load' do
|
1384
|
+
store.store('key1', 'val1', :expires => 2)
|
1385
|
+
store.load('key1', :expires => 0).should == 'val1'
|
1386
|
+
sleep 2
|
1387
|
+
store.load('key1').should == 'val1'
|
1388
|
+
end
|
1389
|
+
|
1390
|
+
it 'supports false as no-expires in load' do
|
1391
|
+
store.store('key1', 'val1', :expires => 2)
|
1392
|
+
store.load('key1', :expires => false).should == 'val1'
|
1393
|
+
sleep 2
|
1394
|
+
store.load('key1').should == 'val1'
|
1395
|
+
end
|
1396
|
+
|
1363
1397
|
it 'supports updating the expiration time in key?' do
|
1364
1398
|
store.store('key2', 'val2', :expires => 2)
|
1365
1399
|
store['key2'].should == 'val2'
|
@@ -1372,6 +1406,20 @@ it 'supports updating the expiration time in key?' do
|
|
1372
1406
|
store['key2'].should be_nil
|
1373
1407
|
end
|
1374
1408
|
|
1409
|
+
it 'supports 0 as no-expires in key?' do
|
1410
|
+
store.store('key1', 'val1', :expires => 2)
|
1411
|
+
store.key?('key1', :expires => 0).should be_true
|
1412
|
+
sleep 2
|
1413
|
+
store['key1'].should == 'val1'
|
1414
|
+
end
|
1415
|
+
|
1416
|
+
it 'supports false as no-expires in key?' do
|
1417
|
+
store.store('key1', 'val1', :expires => 2)
|
1418
|
+
store.key?('key1', :expires => false ).should be_true
|
1419
|
+
sleep 2
|
1420
|
+
store['key1'].should == 'val1'
|
1421
|
+
end
|
1422
|
+
|
1375
1423
|
it 'supports updating the expiration time in fetch' do
|
1376
1424
|
store.store('key1', 'val1', :expires => 2)
|
1377
1425
|
store['key1'].should == 'val1'
|
@@ -1384,6 +1432,20 @@ it 'supports updating the expiration time in fetch' do
|
|
1384
1432
|
store['key1'].should be_nil
|
1385
1433
|
end
|
1386
1434
|
|
1435
|
+
it 'supports 0 as no-expires in fetch' do
|
1436
|
+
store.store('key1', 'val1', :expires => 2)
|
1437
|
+
store.fetch('key1', nil, :expires => 0).should == 'val1'
|
1438
|
+
sleep 2
|
1439
|
+
store.load('key1').should == 'val1'
|
1440
|
+
end
|
1441
|
+
|
1442
|
+
it 'supports false as no-expires in fetch' do
|
1443
|
+
store.store('key1', 'val1', :expires => 2)
|
1444
|
+
store.fetch('key1', nil, :expires => false).should == 'val1'
|
1445
|
+
sleep 2
|
1446
|
+
store.load('key1').should == 'val1'
|
1447
|
+
end
|
1448
|
+
|
1387
1449
|
it 'respects expires in delete' do
|
1388
1450
|
store.store('key2', 'val2', :expires => 2)
|
1389
1451
|
store['key2'].should == 'val2'
|
@@ -1394,14 +1456,56 @@ it 'respects expires in delete' do
|
|
1394
1456
|
end
|
1395
1457
|
|
1396
1458
|
it 'supports the #expires syntactic sugar' do
|
1397
|
-
store
|
1459
|
+
store.store('persistent_key', 'persistent_value', :expires => 0)
|
1398
1460
|
store.expires(2).store('key2', 'val2')
|
1399
1461
|
store['key2'].should == 'val2'
|
1400
1462
|
sleep 1
|
1401
1463
|
store['key2'].should == 'val2'
|
1402
1464
|
sleep 2
|
1403
1465
|
store.delete('key2').should be_nil
|
1404
|
-
store['
|
1466
|
+
store['persistent_key'].should == 'persistent_value'
|
1467
|
+
end
|
1468
|
+
|
1469
|
+
it 'supports false as no-expires on store and #[]' do
|
1470
|
+
store.store('key1', 'val1', :expires => false)
|
1471
|
+
store['key1'].should == 'val1'
|
1472
|
+
sleep 2
|
1473
|
+
store['key1'].should == 'val1'
|
1474
|
+
end
|
1475
|
+
|
1476
|
+
it 'does not update the expiration time in key? when not asked to do so' do
|
1477
|
+
store.store('key1', 'val1', :expires => 1)
|
1478
|
+
store.key?('key1').should be_true
|
1479
|
+
store.key?('key1', :expires => nil).should be_true
|
1480
|
+
sleep 2
|
1481
|
+
store.key?('key1').should be_false
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
it 'does not update the expiration time in fetch when not asked to do so' do
|
1485
|
+
store.store('key1', 'val1', :expires => 1)
|
1486
|
+
store.fetch('key1').should == 'val1'
|
1487
|
+
store.fetch('key1', :expires => nil).should == 'val1'
|
1488
|
+
sleep 2
|
1489
|
+
store.fetch('key1').should be_nil
|
1490
|
+
end
|
1491
|
+
|
1492
|
+
it 'does not update the expiration time in load when not asked to do so' do
|
1493
|
+
store.store('key1', 'val1', :expires => 1)
|
1494
|
+
store.load('key1').should == 'val1'
|
1495
|
+
store.load('key1', :expires => nil).should == 'val1'
|
1496
|
+
sleep 2
|
1497
|
+
store.load('key1').should be_nil
|
1498
|
+
end}
|
1499
|
+
|
1500
|
+
SPECS['default_expires'] = %{it 'does set default expiration time' do
|
1501
|
+
store['key1'] = 'val1'
|
1502
|
+
store.key?('key1').should be_true
|
1503
|
+
store.fetch('key1').should == 'val1'
|
1504
|
+
store.load('key1').should == 'val1'
|
1505
|
+
sleep 2
|
1506
|
+
store.key?('key1').should be_false
|
1507
|
+
store.fetch('key1').should be_nil
|
1508
|
+
store.load('key1').should be_nil
|
1405
1509
|
end}
|
1406
1510
|
|
1407
1511
|
SPECS['not_increment'] = %{it 'does not support #increment' do
|
@@ -1637,7 +1741,7 @@ SPECS.each do |key, code|
|
|
1637
1741
|
"shared_examples_for '#{key}' do\n " << [code].flatten.join("\n\n").gsub("\n", "\n ") << "\nend\n\n"
|
1638
1742
|
end
|
1639
1743
|
specs_code.gsub!(/\n +\n/, "\n\n")
|
1640
|
-
File.open(File.join(
|
1744
|
+
File.open(File.join(PATH, 'monetaspecs.rb'), 'w') {|out| out << specs_code }
|
1641
1745
|
|
1642
1746
|
TESTS.each do |name, options|
|
1643
1747
|
build = options.delete(:build)
|
@@ -1680,5 +1784,5 @@ end
|
|
1680
1784
|
}
|
1681
1785
|
|
1682
1786
|
code.gsub!(/\n +\n/, "\n\n")
|
1683
|
-
File.open(File.join(
|
1787
|
+
File.open(File.join(PATH, 'moneta', "#{name}_spec.rb"), 'w') {|out| out << code }
|
1684
1788
|
end
|