moneta 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.travis.yml +39 -0
- data/Gemfile +61 -0
- data/LICENSE +2 -2
- data/README.md +450 -0
- data/Rakefile +29 -51
- data/SPEC.md +75 -0
- data/benchmarks/run.rb +195 -0
- data/lib/action_dispatch/middleware/session/moneta_store.rb +11 -0
- data/lib/active_support/cache/moneta_store.rb +55 -0
- data/lib/moneta.rb +121 -67
- data/lib/moneta/adapters/activerecord.rb +87 -0
- data/lib/moneta/adapters/cassandra.rb +91 -0
- data/lib/moneta/adapters/client.rb +69 -0
- data/lib/moneta/adapters/cookie.rb +35 -0
- data/lib/moneta/adapters/couch.rb +57 -0
- data/lib/moneta/adapters/datamapper.rb +75 -0
- data/lib/moneta/adapters/dbm.rb +25 -0
- data/lib/moneta/adapters/file.rb +79 -0
- data/lib/moneta/adapters/fog.rb +51 -0
- data/lib/moneta/adapters/gdbm.rb +25 -0
- data/lib/moneta/adapters/hbase.rb +101 -0
- data/lib/moneta/adapters/leveldb.rb +35 -0
- data/lib/moneta/adapters/localmemcache.rb +28 -0
- data/lib/moneta/adapters/lruhash.rb +85 -0
- data/lib/moneta/adapters/memcached.rb +11 -0
- data/lib/moneta/adapters/memcached_dalli.rb +69 -0
- data/lib/moneta/adapters/memcached_native.rb +70 -0
- data/lib/moneta/adapters/memory.rb +10 -0
- data/lib/moneta/adapters/mongo.rb +50 -0
- data/lib/moneta/adapters/null.rb +30 -0
- data/lib/moneta/adapters/pstore.rb +69 -0
- data/lib/moneta/adapters/redis.rb +68 -0
- data/lib/moneta/adapters/riak.rb +57 -0
- data/lib/moneta/adapters/sdbm.rb +35 -0
- data/lib/moneta/adapters/sequel.rb +79 -0
- data/lib/moneta/adapters/sqlite.rb +65 -0
- data/lib/moneta/adapters/tokyocabinet.rb +41 -0
- data/lib/moneta/adapters/yaml.rb +15 -0
- data/lib/moneta/base.rb +78 -0
- data/lib/moneta/builder.rb +39 -0
- data/lib/moneta/cache.rb +84 -0
- data/lib/moneta/expires.rb +71 -0
- data/lib/moneta/lock.rb +25 -0
- data/lib/moneta/logger.rb +61 -0
- data/lib/moneta/mixins.rb +65 -0
- data/lib/moneta/net.rb +18 -0
- data/lib/moneta/optionmerger.rb +39 -0
- data/lib/moneta/proxy.rb +86 -0
- data/lib/moneta/server.rb +81 -0
- data/lib/moneta/shared.rb +60 -0
- data/lib/moneta/stack.rb +78 -0
- data/lib/moneta/transformer.rb +159 -0
- data/lib/moneta/transformer/config.rb +42 -0
- data/lib/moneta/transformer/helper.rb +37 -0
- data/lib/moneta/version.rb +5 -0
- data/lib/moneta/wrapper.rb +33 -0
- data/lib/rack/cache/moneta.rb +93 -0
- data/lib/rack/moneta_cookies.rb +64 -0
- data/lib/rack/session/moneta.rb +63 -0
- data/moneta.gemspec +19 -0
- data/spec/action_dispatch/fixtures/session_autoload_test/foo.rb +10 -0
- data/spec/action_dispatch/session_moneta_store_spec.rb +196 -0
- data/spec/active_support/cache_moneta_store_spec.rb +197 -0
- data/spec/generate.rb +1489 -0
- data/spec/helper.rb +91 -0
- data/spec/moneta/adapter_activerecord_spec.rb +32 -0
- data/spec/moneta/adapter_cassandra_spec.rb +30 -0
- data/spec/moneta/adapter_client_spec.rb +19 -0
- data/spec/moneta/adapter_cookie_spec.rb +18 -0
- data/spec/moneta/adapter_couch_spec.rb +18 -0
- data/spec/moneta/adapter_datamapper_spec.rb +49 -0
- data/spec/moneta/adapter_dbm_spec.rb +18 -0
- data/spec/moneta/adapter_file_spec.rb +18 -0
- data/spec/moneta/adapter_fog_spec.rb +23 -0
- data/spec/moneta/adapter_gdbm_spec.rb +18 -0
- data/spec/moneta/adapter_hbase_spec.rb +18 -0
- data/spec/moneta/adapter_leveldb_spec.rb +18 -0
- data/spec/moneta/adapter_localmemcache_spec.rb +18 -0
- data/spec/moneta/adapter_lruhash_spec.rb +31 -0
- data/spec/moneta/adapter_memcached_dalli_spec.rb +30 -0
- data/spec/moneta/adapter_memcached_native_spec.rb +31 -0
- data/spec/moneta/adapter_memcached_spec.rb +30 -0
- data/spec/moneta/adapter_memory_spec.rb +39 -0
- data/spec/moneta/adapter_mongo_spec.rb +18 -0
- data/spec/moneta/adapter_pstore_spec.rb +21 -0
- data/spec/moneta/adapter_redis_spec.rb +30 -0
- data/spec/moneta/adapter_riak_spec.rb +22 -0
- data/spec/moneta/adapter_sdbm_spec.rb +18 -0
- data/spec/moneta/adapter_sequel_spec.rb +18 -0
- data/spec/moneta/adapter_sqlite_spec.rb +18 -0
- data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +18 -0
- data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +18 -0
- data/spec/moneta/adapter_yaml_spec.rb +21 -0
- data/spec/moneta/cache_file_memory_spec.rb +34 -0
- data/spec/moneta/cache_memory_null_spec.rb +23 -0
- data/spec/moneta/expires_file_spec.rb +76 -0
- data/spec/moneta/expires_memory_spec.rb +65 -0
- data/spec/moneta/lock_spec.rb +42 -0
- data/spec/moneta/null_adapter_spec.rb +26 -0
- data/spec/moneta/optionmerger_spec.rb +92 -0
- data/spec/moneta/proxy_expires_memory_spec.rb +55 -0
- data/spec/moneta/proxy_redis_spec.rb +23 -0
- data/spec/moneta/shared_spec.rb +30 -0
- data/spec/moneta/simple_activerecord_spec.rb +51 -0
- data/spec/moneta/simple_activerecord_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_cassandra_spec.rb +52 -0
- data/spec/moneta/simple_client_tcp_spec.rb +67 -0
- data/spec/moneta/simple_client_unix_spec.rb +53 -0
- data/spec/moneta/simple_couch_spec.rb +51 -0
- data/spec/moneta/simple_couch_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_datamapper_spec.rb +53 -0
- data/spec/moneta/simple_datamapper_with_expires_spec.rb +54 -0
- data/spec/moneta/simple_datamapper_with_repository_spec.rb +53 -0
- data/spec/moneta/simple_dbm_spec.rb +51 -0
- data/spec/moneta/simple_dbm_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_file_spec.rb +51 -0
- data/spec/moneta/simple_file_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_fog_spec.rb +56 -0
- data/spec/moneta/simple_fog_with_expires_spec.rb +58 -0
- data/spec/moneta/simple_gdbm_spec.rb +51 -0
- data/spec/moneta/simple_gdbm_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_hashfile_spec.rb +51 -0
- data/spec/moneta/simple_hashfile_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_hbase_spec.rb +51 -0
- data/spec/moneta/simple_hbase_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_leveldb_spec.rb +51 -0
- data/spec/moneta/simple_leveldb_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_localmemcache_spec.rb +51 -0
- data/spec/moneta/simple_localmemcache_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_lruhash_spec.rb +51 -0
- data/spec/moneta/simple_lruhash_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_memcached_dalli_spec.rb +52 -0
- data/spec/moneta/simple_memcached_native_spec.rb +52 -0
- data/spec/moneta/simple_memcached_spec.rb +52 -0
- data/spec/moneta/simple_memory_spec.rb +51 -0
- data/spec/moneta/simple_memory_with_compress_spec.rb +51 -0
- data/spec/moneta/simple_memory_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +37 -0
- data/spec/moneta/simple_memory_with_json_serializer_spec.rb +28 -0
- data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +35 -0
- data/spec/moneta/simple_memory_with_prefix_spec.rb +51 -0
- data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +51 -0
- data/spec/moneta/simple_mongo_spec.rb +51 -0
- data/spec/moneta/simple_mongo_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_null_spec.rb +36 -0
- data/spec/moneta/simple_pstore_spec.rb +51 -0
- data/spec/moneta/simple_pstore_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_redis_spec.rb +52 -0
- data/spec/moneta/simple_riak_spec.rb +55 -0
- data/spec/moneta/simple_riak_with_expires_spec.rb +56 -0
- data/spec/moneta/simple_sdbm_spec.rb +51 -0
- data/spec/moneta/simple_sdbm_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_sequel_spec.rb +51 -0
- data/spec/moneta/simple_sequel_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_sqlite_spec.rb +51 -0
- data/spec/moneta/simple_sqlite_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_tokyocabinet_spec.rb +51 -0
- data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +52 -0
- data/spec/moneta/simple_yaml_spec.rb +50 -0
- data/spec/moneta/simple_yaml_with_expires_spec.rb +51 -0
- data/spec/moneta/stack_file_memory_spec.rb +25 -0
- data/spec/moneta/stack_memory_file_spec.rb +24 -0
- data/spec/moneta/transformer_bencode_spec.rb +30 -0
- data/spec/moneta/transformer_bert_spec.rb +30 -0
- data/spec/moneta/transformer_bson_spec.rb +30 -0
- data/spec/moneta/transformer_bzip2_spec.rb +27 -0
- data/spec/moneta/transformer_json_spec.rb +30 -0
- data/spec/moneta/transformer_lzma_spec.rb +27 -0
- data/spec/moneta/transformer_lzo_spec.rb +27 -0
- data/spec/moneta/transformer_marshal_base64_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_escape_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_hmac_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_md5_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_md5_spread_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_prefix_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_rmd160_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_sha1_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_sha256_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_sha384_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_sha512_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_truncate_spec.rb +54 -0
- data/spec/moneta/transformer_marshal_uuencode_spec.rb +54 -0
- data/spec/moneta/transformer_msgpack_spec.rb +30 -0
- data/spec/moneta/transformer_ox_spec.rb +51 -0
- data/spec/moneta/transformer_quicklz_spec.rb +27 -0
- data/spec/moneta/transformer_snappy_spec.rb +27 -0
- data/spec/moneta/transformer_tnet_spec.rb +30 -0
- data/spec/moneta/transformer_yaml_spec.rb +51 -0
- data/spec/moneta/transformer_zlib_spec.rb +27 -0
- data/spec/monetaspecs.rb +2663 -0
- data/spec/rack/cache_moneta_spec.rb +355 -0
- data/spec/rack/moneta_cookies_spec.rb +81 -0
- data/spec/rack/session_moneta_spec.rb +305 -0
- metadata +359 -56
- data/README +0 -51
- data/TODO +0 -4
- data/lib/moneta/basic_file.rb +0 -111
- data/lib/moneta/berkeley.rb +0 -53
- data/lib/moneta/couch.rb +0 -63
- data/lib/moneta/datamapper.rb +0 -117
- data/lib/moneta/file.rb +0 -91
- data/lib/moneta/lmc.rb +0 -52
- data/lib/moneta/memcache.rb +0 -52
- data/lib/moneta/memory.rb +0 -11
- data/lib/moneta/mongodb.rb +0 -58
- data/lib/moneta/redis.rb +0 -49
- data/lib/moneta/rufus.rb +0 -41
- data/lib/moneta/s3.rb +0 -162
- data/lib/moneta/sdbm.rb +0 -33
- data/lib/moneta/tyrant.rb +0 -58
- data/lib/moneta/xattr.rb +0 -58
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'tokyocabinet'
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
module Adapters
|
5
|
+
# TokyoCabinet backend
|
6
|
+
# @api public
|
7
|
+
class TokyoCabinet < Memory
|
8
|
+
# Constructor
|
9
|
+
#
|
10
|
+
# @param [Hash] options
|
11
|
+
#
|
12
|
+
# Options:
|
13
|
+
# * :file - Database file
|
14
|
+
# * :type - Database type (default :hdb, :bdb and :hdb possible)
|
15
|
+
def initialize(options = {})
|
16
|
+
file = options[:file]
|
17
|
+
raise ArgumentError, 'Option :file is required' unless options[:file]
|
18
|
+
if options[:type] == :bdb
|
19
|
+
@hash = ::TokyoCabinet::BDB.new
|
20
|
+
@hash.open(file, ::TokyoCabinet::BDB::OWRITER | ::TokyoCabinet::BDB::OCREAT)
|
21
|
+
else
|
22
|
+
@hash = ::TokyoCabinet::HDB.new
|
23
|
+
@hash.open(file, ::TokyoCabinet::HDB::OWRITER | ::TokyoCabinet::HDB::OCREAT)
|
24
|
+
end or raise @hash.errmsg(@hash.ecode)
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(key, options = {})
|
28
|
+
value = load(key, options)
|
29
|
+
if value
|
30
|
+
@hash.delete(key)
|
31
|
+
value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def close
|
36
|
+
@hash.close
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/moneta/base.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
module Moneta
|
2
|
+
# Simple interface to key/value stores with Hash-like interface.
|
3
|
+
# @api public
|
4
|
+
class Base
|
5
|
+
include Mixins::WithOptions
|
6
|
+
|
7
|
+
# Exists the value with key
|
8
|
+
#
|
9
|
+
# @param [Object] key
|
10
|
+
# @return [Boolean]
|
11
|
+
# @param [Hash] options
|
12
|
+
# @api public
|
13
|
+
def key?(key, options = {})
|
14
|
+
load(key, options) != nil
|
15
|
+
end
|
16
|
+
|
17
|
+
# Atomically increment integer value with key
|
18
|
+
#
|
19
|
+
# Not every Moneta store implements this method,
|
20
|
+
# a NotImplementedError if it is not supported.
|
21
|
+
#
|
22
|
+
# @param [Object] key
|
23
|
+
# @param [Integer] amount
|
24
|
+
# @param [Hash] options
|
25
|
+
# @return [Object] value from store
|
26
|
+
# @api public
|
27
|
+
def increment(key, amount = 1, options = {})
|
28
|
+
raise NotImplementedError, 'increment is not supported'
|
29
|
+
end
|
30
|
+
|
31
|
+
# Explicitly close the store
|
32
|
+
# @api public
|
33
|
+
def close
|
34
|
+
end
|
35
|
+
|
36
|
+
# Fetch value with key
|
37
|
+
#
|
38
|
+
# This is a overloaded method:
|
39
|
+
#
|
40
|
+
# * fetch(key, options = {}, &block) retrieve a key. if the key is not available, execute the
|
41
|
+
# block and return its return value.
|
42
|
+
#
|
43
|
+
# * fetch(key, value, options = {}) retrieve a key. if the key is not available, return the value.
|
44
|
+
#
|
45
|
+
# @param [Object] key
|
46
|
+
# @param [Object] default Default value
|
47
|
+
# @param [Hash] options
|
48
|
+
# @return [Object] value from store
|
49
|
+
# @api public
|
50
|
+
def fetch(key, default = nil, options = nil)
|
51
|
+
if block_given?
|
52
|
+
raise ArgumentError, 'Only one argument accepted if block is given' if options
|
53
|
+
load(key, default || {}) || yield(key)
|
54
|
+
else
|
55
|
+
load(key, options || {}) || default
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Fetch value with key. Return nil if the key doesn't exist
|
60
|
+
#
|
61
|
+
# @param [Object] key
|
62
|
+
# @return [Object] value
|
63
|
+
# @api public
|
64
|
+
def [](key)
|
65
|
+
load(key)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Store value with key
|
69
|
+
#
|
70
|
+
# @param [Object] key
|
71
|
+
# @param [Object] value
|
72
|
+
# @return value
|
73
|
+
# @api public
|
74
|
+
def []=(key, value)
|
75
|
+
store(key, value)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Moneta
|
2
|
+
# Builder implements the DSL to build a chain of store proxies
|
3
|
+
# @api private
|
4
|
+
class Builder
|
5
|
+
# @api private
|
6
|
+
def build
|
7
|
+
klass, options, block = @proxies.first
|
8
|
+
@proxies[1..-1].inject([klass.new(options, &block)]) do |stores, proxy|
|
9
|
+
klass, options, block = proxy
|
10
|
+
stores << klass.new(stores.last, options, &block)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(&block)
|
15
|
+
raise ArgumentError, 'No block given' unless block_given?
|
16
|
+
@proxies = []
|
17
|
+
instance_eval(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Add proxy to chain
|
21
|
+
#
|
22
|
+
# @param [Symbol or Class] proxy Name of proxy class or proxy class
|
23
|
+
# @param [Hash] options Options hash
|
24
|
+
def use(proxy, options = {}, &block)
|
25
|
+
proxy = Moneta.const_get(proxy) if Symbol === proxy
|
26
|
+
raise ArgumentError, 'You must give a Class or a Symbol' unless Class === proxy
|
27
|
+
@proxies.unshift [proxy, options, block]
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add adapter to chain
|
32
|
+
#
|
33
|
+
# @param [Symbol] name Name of adapter class
|
34
|
+
# @param [Hash] options Options hash
|
35
|
+
def adapter(name, options = {}, &block)
|
36
|
+
use(Adapters.const_get(name), options, &block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/moneta/cache.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
module Moneta
|
2
|
+
# Combines two stores. One is used as cache, the other as backend.
|
3
|
+
#
|
4
|
+
# @example Add cache to chain
|
5
|
+
# Moneta.build do
|
6
|
+
# use(:Cache) do
|
7
|
+
# backend { adapter :File, :dir => 'data' }
|
8
|
+
# cache { adapter :Memory }
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
class Cache < Base
|
14
|
+
# @api private
|
15
|
+
class DSL
|
16
|
+
def initialize(options, &block)
|
17
|
+
@cache, @backend = options[:cache], options[:backend]
|
18
|
+
instance_eval(&block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def backend(store = nil, &block)
|
22
|
+
raise 'Backend already set' if @backend
|
23
|
+
raise ArgumentError, 'Only argument or block allowed' if store && block
|
24
|
+
@backend = store || Moneta.build(&block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def cache(store = nil, &block)
|
28
|
+
raise 'Cache already set' if @cache
|
29
|
+
raise ArgumentError, 'Only argument or block allowed' if store && block
|
30
|
+
@cache = store || Moneta.build(&block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def result
|
34
|
+
[@cache, @backend]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_reader :cache, :backend
|
39
|
+
|
40
|
+
def initialize(options = {}, &block)
|
41
|
+
@cache, @backend = DSL.new(options, &block).result
|
42
|
+
end
|
43
|
+
|
44
|
+
def key?(key, options = {})
|
45
|
+
@cache.key?(key, options) || @backend.key?(key, options)
|
46
|
+
end
|
47
|
+
|
48
|
+
def load(key, options = {})
|
49
|
+
value = @cache.load(key, options)
|
50
|
+
unless value
|
51
|
+
value = @backend.load(key, options)
|
52
|
+
@cache.store(key, value, options) if value
|
53
|
+
end
|
54
|
+
value
|
55
|
+
end
|
56
|
+
|
57
|
+
def store(key, value, options = {})
|
58
|
+
@cache.store(key, value, options)
|
59
|
+
@backend.store(key, value, options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def increment(key, amount = 1, options = {})
|
63
|
+
value = @backend.increment(key, amount, options)
|
64
|
+
@cache.store(key, value.to_s, options)
|
65
|
+
value
|
66
|
+
end
|
67
|
+
|
68
|
+
def delete(key, options = {})
|
69
|
+
@cache.delete(key, options)
|
70
|
+
@backend.delete(key, options)
|
71
|
+
end
|
72
|
+
|
73
|
+
def clear(options = {})
|
74
|
+
@cache.clear(options)
|
75
|
+
@backend.clear(options)
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
def close
|
80
|
+
@cache.close
|
81
|
+
@backend.close
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Moneta
|
2
|
+
# Adds expiration support to the underlying store
|
3
|
+
#
|
4
|
+
# #store and #load support the :expires option to set/update
|
5
|
+
# the expiration time.
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
class Expires < Proxy
|
9
|
+
# Constructor
|
10
|
+
#
|
11
|
+
# @param [Moneta store] adapter The underlying store
|
12
|
+
# @param [Hash] options
|
13
|
+
#
|
14
|
+
# Options:
|
15
|
+
# * :expires - Default expiration time (default none)
|
16
|
+
def initialize(adapter, options = {})
|
17
|
+
super
|
18
|
+
@expires = options[:expires]
|
19
|
+
end
|
20
|
+
|
21
|
+
def key?(key, options = {})
|
22
|
+
load(key, options) != nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def load(key, options = {})
|
26
|
+
if options.include?(:raw)
|
27
|
+
super
|
28
|
+
else
|
29
|
+
value = check_expired(key, super)
|
30
|
+
if value && options.include?(:expires)
|
31
|
+
store(key, value, options)
|
32
|
+
else
|
33
|
+
value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def store(key, value, options = {})
|
39
|
+
if options.include?(:raw)
|
40
|
+
super
|
41
|
+
else
|
42
|
+
if expires = (options.delete(:expires) || @expires)
|
43
|
+
super(key, [value, Time.now.to_i + expires], options)
|
44
|
+
else
|
45
|
+
super(key, [value], options)
|
46
|
+
end
|
47
|
+
value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def delete(key, options = {})
|
52
|
+
if options.include?(:raw)
|
53
|
+
super
|
54
|
+
else
|
55
|
+
check_expired(key, super, false)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
def check_expired(key, value, delete_expired = true)
|
62
|
+
value, expires = value
|
63
|
+
if expires && Time.now.to_i > expires
|
64
|
+
delete(key) if delete_expired
|
65
|
+
nil
|
66
|
+
else
|
67
|
+
value
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/moneta/lock.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Moneta
|
4
|
+
# Locks the underlying stores with a Mutex
|
5
|
+
# @api public
|
6
|
+
class Lock < Wrapper
|
7
|
+
# Constructor
|
8
|
+
#
|
9
|
+
# @param [Moneta store] adapter The underlying store
|
10
|
+
# @param [Hash] options
|
11
|
+
#
|
12
|
+
# Options:
|
13
|
+
# * :mutex - Mutex object (default Mutex.new)
|
14
|
+
def initialize(adapter, options = {})
|
15
|
+
super
|
16
|
+
@lock = options[:mutex] || Mutex.new
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def wrap(*args, &block)
|
22
|
+
@lock.synchronize(&block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Moneta
|
2
|
+
# Logger proxy
|
3
|
+
# @api public
|
4
|
+
class Logger < Wrapper
|
5
|
+
# Standard formatter used by the logger
|
6
|
+
# @api public
|
7
|
+
class Format
|
8
|
+
def initialize(options)
|
9
|
+
@prefix = options[:prefix] || 'Moneta '
|
10
|
+
@out = options[:out] || STDOUT
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(entry)
|
14
|
+
@out.write(format(entry))
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def format(entry)
|
20
|
+
args = entry[:args]
|
21
|
+
args.pop if Hash === args.last && args.last.empty?
|
22
|
+
args = args.map {|a| dump(a) }.join(', ')
|
23
|
+
if entry[:error]
|
24
|
+
"#{@prefix}#{entry[:method]}(#{args}) raised error: #{entry[:error].message}\n"
|
25
|
+
else
|
26
|
+
"#{@prefix}#{entry[:method]}(#{args}) -> #{dump entry[:return]}\n"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def dump(value)
|
31
|
+
value = value.inspect
|
32
|
+
value.size > 30 ? value[0..30] + '...' : value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Constructor
|
37
|
+
#
|
38
|
+
# @param [Moneta store] adapter The underlying store
|
39
|
+
# @param [Hash] options
|
40
|
+
#
|
41
|
+
# Options:
|
42
|
+
# * :logger - Callable logger object (default Moneta::Logger::Format)
|
43
|
+
# * :logprefix - Prefix string (default 'Moneta ')
|
44
|
+
# * :logout - Output (default STDOUT)
|
45
|
+
def initialize(adapter, options = {})
|
46
|
+
super
|
47
|
+
@logger = options[:logger] || Format.new(options)
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def wrap(method, *args)
|
53
|
+
ret = yield
|
54
|
+
@logger.call(:method => method, :args => args, :return => (method == :clear ? 'self' : ret))
|
55
|
+
ret
|
56
|
+
rescue Exception => error
|
57
|
+
@logger.call(:method => method, :args => args, :error => error)
|
58
|
+
raise
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Moneta
|
2
|
+
# @api private
|
3
|
+
module Mixins
|
4
|
+
module WithOptions
|
5
|
+
def with(options)
|
6
|
+
OptionMerger.new(self, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def raw
|
10
|
+
@raw_store ||=
|
11
|
+
begin
|
12
|
+
store = with(:raw => true, :only => [:load, :store, :delete])
|
13
|
+
store.instance_variable_set(:@raw_store, store)
|
14
|
+
store
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def prefix(prefix)
|
19
|
+
with(:prefix => prefix, :except => :clear)
|
20
|
+
end
|
21
|
+
|
22
|
+
def expires(expires)
|
23
|
+
with(:expires => expires, :only => [:store, :increment])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module IncrementSupport
|
28
|
+
def increment(key, amount = 1, options = {})
|
29
|
+
value = load(key, options)
|
30
|
+
intvalue = value.to_i
|
31
|
+
raise 'Tried to increment non integer value' unless value == nil || intvalue.to_s == value.to_s
|
32
|
+
intvalue += amount
|
33
|
+
store(key, intvalue.to_s, options)
|
34
|
+
intvalue
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module HashAdapter
|
39
|
+
def initialize(options = {})
|
40
|
+
@hash = {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def key?(key, options = {})
|
44
|
+
@hash.has_key?(key)
|
45
|
+
end
|
46
|
+
|
47
|
+
def load(key, options = {})
|
48
|
+
@hash[key]
|
49
|
+
end
|
50
|
+
|
51
|
+
def store(key, value, options = {})
|
52
|
+
@hash[key] = value
|
53
|
+
end
|
54
|
+
|
55
|
+
def delete(key, options = {})
|
56
|
+
@hash.delete(key)
|
57
|
+
end
|
58
|
+
|
59
|
+
def clear(options = {})
|
60
|
+
@hash.clear
|
61
|
+
self
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|