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
data/.travis.yml
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
rvm:
|
2
2
|
- 1.8.7
|
3
3
|
- 1.9.3
|
4
|
-
# - ruby-head
|
5
4
|
- jruby
|
6
5
|
- rbx-18mode
|
7
6
|
- rbx-19mode
|
@@ -13,60 +12,27 @@ services:
|
|
13
12
|
- memcached
|
14
13
|
- mongodb
|
15
14
|
before_install:
|
16
|
-
- sudo apt-get install -qq libtokyocabinet8 libtokyocabinet-dev liblzo2-dev
|
15
|
+
- sudo apt-get install -qq libtokyocabinet8 libtokyocabinet-dev liblzo2-dev libtdb-dev
|
16
|
+
- script/install-bundle.rb
|
17
17
|
env:
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
18
|
+
global:
|
19
|
+
- secure: "bNtinRuxS/FLP1fKj7KtHweIP/fG94CusdYKH/sBL6P0aqL3mr/dkbC34pSk\nNGkLKs/FAzvLkOo7aIOcCLx1WnL9yaZ12tmHgH8Ztf8ci2S52HSfqYwQw/dE\nq7euNMZVjvWfVu+15+Xpn6+t2XSubSO/TELfymDFGbhivmKAo5M="
|
20
|
+
- secure: "Pv/MUnoaZMbPNB3vx4Hw2ASQBsUO7HIjJsfGHAQa5VbWlX3qEfMdezlYzNbf\nDPdpeabQwEwCUcINT7x10XKH5M4nZn6bBGfpvmNMxvZ8De1Et7mrwvb5/o73\n5EkyvYuUu8FB/LQmjB/4zZcjLQWNCtcfPlYPs7YcADBt0gIwn8M="
|
21
|
+
matrix:
|
22
|
+
- "TASK=test"
|
23
|
+
- "TASK=benchmarks CONFIG=uniform_small"
|
24
|
+
- "TASK=benchmarks CONFIG=uniform_medium"
|
25
|
+
- "TASK=benchmarks CONFIG=uniform_large"
|
26
|
+
- "TASK=benchmarks CONFIG=normal_small"
|
27
|
+
- "TASK=benchmarks CONFIG=normal_medium"
|
28
|
+
- "TASK=benchmarks CONFIG=normal_large"
|
26
29
|
matrix:
|
27
30
|
allow_failures:
|
28
|
-
# - rvm: ruby-head
|
29
31
|
- rvm: jruby
|
30
32
|
- rvm: rbx-18mode
|
31
33
|
- rvm: rbx-19mode
|
32
|
-
# Parallel tests do not work on jruby
|
33
|
-
exclude:
|
34
|
-
- rvm: jruby
|
35
|
-
env: "TASK=test:parallel"
|
36
|
-
- rvm: jruby
|
37
|
-
env: "TASK=benchmarks CONFIG=uniform_small"
|
38
|
-
- rvm: jruby
|
39
|
-
env: "TASK=benchmarks CONFIG=uniform_medium"
|
40
|
-
- rvm: jruby
|
41
|
-
env: "TASK=benchmarks CONFIG=uniform_large"
|
42
|
-
- rvm: jruby
|
43
|
-
env: "TASK=benchmarks CONFIG=normal_small"
|
44
|
-
- rvm: jruby
|
45
|
-
env: "TASK=benchmarks CONFIG=normal_medium"
|
46
|
-
- rvm: jruby
|
47
|
-
env: "TASK=benchmarks CONFIG=normal_large"
|
48
|
-
- rvm: rbx-18mode
|
49
|
-
env: "TASK=benchmarks CONFIG=uniform_small"
|
50
|
-
- rvm: rbx-18mode
|
51
|
-
env: "TASK=benchmarks CONFIG=uniform_medium"
|
52
|
-
- rvm: rbx-18mode
|
53
|
-
env: "TASK=benchmarks CONFIG=uniform_large"
|
54
|
-
- rvm: rbx-18mode
|
55
|
-
env: "TASK=benchmarks CONFIG=normal_small"
|
56
|
-
- rvm: rbx-18mode
|
57
|
-
env: "TASK=benchmarks CONFIG=normal_medium"
|
58
|
-
- rvm: rbx-18mode
|
59
|
-
env: "TASK=benchmarks CONFIG=normal_large"
|
60
|
-
- rvm: rbx-19mode
|
61
|
-
env: "TASK=benchmarks CONFIG=uniform_small"
|
62
|
-
- rvm: rbx-19mode
|
63
|
-
env: "TASK=benchmarks CONFIG=uniform_medium"
|
64
|
-
- rvm: rbx-19mode
|
65
|
-
env: "TASK=benchmarks CONFIG=uniform_large"
|
66
|
-
- rvm: rbx-19mode
|
67
|
-
env: "TASK=benchmarks CONFIG=normal_small"
|
68
|
-
- rvm: rbx-19mode
|
69
|
-
env: "TASK=benchmarks CONFIG=normal_medium"
|
70
|
-
- rvm: rbx-19mode
|
71
|
-
env: "TASK=benchmarks CONFIG=normal_large"
|
72
34
|
script: "bundle exec rake $TASK"
|
35
|
+
branches:
|
36
|
+
only:
|
37
|
+
- master
|
38
|
+
- travis
|
data/CHANGES
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
0.7.4
|
2
|
+
|
3
|
+
* Transformer: fix truncate
|
4
|
+
* Adapters::RestClient: raise error if store fails
|
5
|
+
* Adapters::TDB added
|
6
|
+
* Adapters::Daybreak added
|
7
|
+
* Adapters::Mongo - Expiration and increment support added
|
8
|
+
* Pool proxy added
|
9
|
+
* Mixin ExpiresSupport added
|
10
|
+
* Expiration value handling unified
|
11
|
+
* 0 and false are interpreted as persist value
|
12
|
+
* Adapters::RestClient uses net/http now
|
13
|
+
|
1
14
|
0.7.3
|
2
15
|
|
3
16
|
* Added Adapters::RestClient
|
data/Gemfile
CHANGED
@@ -12,7 +12,6 @@ end
|
|
12
12
|
# Testing
|
13
13
|
gem 'rake'
|
14
14
|
gem 'rspec'
|
15
|
-
gem 'parallel_tests'
|
16
15
|
|
17
16
|
# Serializer used by Transformer
|
18
17
|
gem 'tnetstring'
|
@@ -28,10 +27,11 @@ alternatives :mri => 'bzip2-ruby'
|
|
28
27
|
alternatives :mri => 'ruby-lzma'
|
29
28
|
alternatives :mri => 'lzoruby'
|
30
29
|
alternatives :mri => 'snappy'
|
31
|
-
# QuickLZ segfaults because of an assertion
|
32
|
-
|
30
|
+
# WARNING: QuickLZ segfaults because of an assertion
|
31
|
+
alternatives :mri => 'qlzruby'
|
33
32
|
|
34
33
|
# Backends
|
34
|
+
gem 'daybreak', :github => 'propublica/daybreak'
|
35
35
|
gem 'dm-core'
|
36
36
|
gem 'dm-migrations'
|
37
37
|
gem 'dm-sqlite-adapter'
|
@@ -44,9 +44,9 @@ gem 'sequel'
|
|
44
44
|
gem 'dalli'
|
45
45
|
gem 'riak-client'
|
46
46
|
gem 'cassandra'
|
47
|
-
gem 'httpi'
|
48
47
|
#gem 'hbaserb'
|
49
48
|
#gem 'localmemcache'
|
49
|
+
alternatives :mri => 'tdb'
|
50
50
|
alternatives :mri => 'leveldb-ruby'
|
51
51
|
alternatives :mri => 'tokyocabinet'
|
52
52
|
alternatives :mri => 'memcached', :jruby => 'jruby-memcached'
|
data/README.md
CHANGED
@@ -14,6 +14,16 @@ Moneta provides a standard interface for interacting with various kinds of key/v
|
|
14
14
|
* Includes a very simple key/value server (`Moneta::Server`) and client (`Moneta::Adapters::Client`)
|
15
15
|
* Integration with [Rails](http://rubyonrails.org/), [Rack](http://rack.github.com/), [Sinatra](http://sinatrarb.com/) and [Rack-Cache](https://github.com/rtomayko/rack-cache)
|
16
16
|
|
17
|
+
If you are not yet convinced, you might ask why? What are the goals of the project?
|
18
|
+
|
19
|
+
* Get people started quickly with key/value stores! Therefore all the adapters are included in the gem and you are ready to go. [Tilt](https://github.com/rtomayko/tilt) does the
|
20
|
+
same for template languages.
|
21
|
+
* Make it easy to compare different key/value stores and benchmark them
|
22
|
+
* To hide a lot of different and maybe complex APIs behind one well-designed and simple Moneta API
|
23
|
+
* Give people a starting point or example code to start working with their favourite key/value store. Feel free to copy code, please mention Moneta then :)
|
24
|
+
* Create a reusable piece of code, since similar things are solved over and over again ([Rails](http://rubyonrails.org/ brings its own cache stores, and many frameworks do the same...)
|
25
|
+
* See also http://yehudakatz.com/2009/02/12/whats-the-point/
|
26
|
+
|
17
27
|
Moneta is tested thoroughly using [Travis-CI](http://travis-ci.org/minad/moneta).
|
18
28
|
|
19
29
|
## Links
|
@@ -33,6 +43,7 @@ Out of the box, it supports the following backends:
|
|
33
43
|
* LRU hash - prefer this over :Memory! (`:LRUHash`)
|
34
44
|
* LocalMemCache (`:LocalMemCache`)
|
35
45
|
* Memcached store (`:Memcached`, `:MemcachedNative` and `:MemcachedDalli`)
|
46
|
+
* Daybreak database (`:Daybreak`)
|
36
47
|
* Relational Databases:
|
37
48
|
* DataMapper (`:DataMapper`)
|
38
49
|
* ActiveRecord (`:ActiveRecord`)
|
@@ -46,6 +57,7 @@ Out of the box, it supports the following backends:
|
|
46
57
|
* Key/value databases:
|
47
58
|
* Berkeley DB (`:DBM`)
|
48
59
|
* Cassandra (`:Cassandra`)
|
60
|
+
* Daybreak (`:Daybreak`)
|
49
61
|
* GDBM (`:GDBM`)
|
50
62
|
* HBase (`:HBase`)
|
51
63
|
* LevelDB (`:LevelDB`)
|
@@ -53,6 +65,7 @@ Out of the box, it supports the following backends:
|
|
53
65
|
* Riak (`:Riak`)
|
54
66
|
* SDBM (`:SDBM`)
|
55
67
|
* TokyoCabinet (`:TokyoCabinet`)
|
68
|
+
* Simple Samba database TDB (`:TDB`)
|
56
69
|
* Document databases:
|
57
70
|
* CouchDB (`:Couch`)
|
58
71
|
* MongoDB (`:Mongo`)
|
@@ -68,6 +81,52 @@ are useful if you already use the corresponding backend in your application. You
|
|
68
81
|
store for free then without installing any additional services and you still have the possibility
|
69
82
|
to upgrade to a real key/value store.
|
70
83
|
|
84
|
+
### Backend feature matrix
|
85
|
+
|
86
|
+
<table>
|
87
|
+
<thead style="font-weight:bold"><tr><th>Adapter</th><th>Required gems</th><th>Multi-thread safe<sup>[1]</sup></th><th>Multi-process safe<sup>[2]</sup></th><th>Atomic increment</th><th>Native expires<sup>[3]</sup></th><th>Persistent</th><th>Description</th></tr></thead>
|
88
|
+
<tbody>
|
89
|
+
<tr><td>ActiveRecord</td><td>activerecord</td><td style="color:blue">?</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>ActiveRecord ORM</td></tr>
|
90
|
+
<tr><td>Cassandra</td><td>cassandra</td><td style="color:blue">?</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:green">✓</td><td>Cassandra distributed database</td></tr>
|
91
|
+
<tr><td>Client</td><td>-</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:blue">?<sup>[5]</sup></td><td style="color:blue">?<sup>[5]</sup></td><td style="color:blue">?<sup>[5]</sup></td><td>Moneta client adapter</td></tr>
|
92
|
+
<tr><td>Cookie</td><td>-</td><td style="color:red">✗</td><td style="color:blue">(✓)<sup>[6]</sup></td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td>Cookie in memory store</td></tr>
|
93
|
+
<tr><td>Couch</td><td>couchrest</td><td style="color:blue">?</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td>CouchDB database</td></tr>
|
94
|
+
<tr><td>DataMapper</td><td>dm-core, dm-migrations</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td>DataMapper ORM</td></tr>
|
95
|
+
<tr><td>Daybreak</td><td>daybreak</td><td style="color:blue">?</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>Daybreak ruby key/value store</td></tr>
|
96
|
+
<tr><td>DBM</td><td>-</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>Berkeley DB</td></tr>
|
97
|
+
<tr><td>File</td><td>-</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>File store</td></tr>
|
98
|
+
<tr><td>Fog</td><td>fog</td><td style="color:blue">?</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td>Fog cloud store</td></tr>
|
99
|
+
<tr><td>GDBM</td><td>-</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>GDBM database</td></tr>
|
100
|
+
<tr><td>HBase</td><td>hbase</td><td style="color:blue">?</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td>HBase database</td></tr>
|
101
|
+
<tr><td>LevelDB</td><td>leveldb</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>LevelDB database</td></tr>
|
102
|
+
<tr><td>LocalMemCache</td><td>localmemcache</td><td style="color:blue">?</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td>LocalMemCache database</td></tr>
|
103
|
+
<tr><td>LRUHash</td><td>-</td><td style="color:red">✗</td><td style="color:blue">(✓)<sup>[6]</sup></td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td>LRU memory store</td></tr>
|
104
|
+
<tr><td>Memcached</td><td>dalli or memcached</td><td style="color:blue">?</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗<sup>[4]</sup></td><td>Memcached database</td></tr>
|
105
|
+
<tr><td>MemcachedDalli</td><td>dalli</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗<sup>[4]</sup></td><td>Memcached database</td></tr>
|
106
|
+
<tr><td>MemcachedNative</td><td>memcached</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗<sup>[4]</sup></td><td>Memcached database</td></tr>
|
107
|
+
<tr><td>Memory</td><td>-</td><td style="color:red">✗</td><td style="color:blue">(✓)<sup>[6]</sup></td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td>Memory store</td></tr>
|
108
|
+
<tr><td>Mongo</td><td>mongo</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td>MongoDB database</td></tr>
|
109
|
+
<tr><td>Null</td><td>-</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:red">✗</td><td>No database</td></tr>
|
110
|
+
<tr><td>PStore</td><td>-</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>PStore store</td></tr>
|
111
|
+
<tr><td>Redis</td><td>redis</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td>Redis database</td></tr>
|
112
|
+
<tr><td>RestClient</td><td>-</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:blue">?<sup>[5]</sup></td><td>Moneta REST client adapter</td></tr>
|
113
|
+
<tr><td>Riak</td><td>riak-client</td><td style="color:blue">?</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td>Riak database</td></tr>
|
114
|
+
<tr><td>SDBM</td><td>-</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>SDBM database</td></tr>
|
115
|
+
<tr><td>Sequel</td><td>sequel</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>Sequel ORM</td></tr>
|
116
|
+
<tr><td>Sqlite</td><td>sqlite3</td><td style="color:blue">?</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>Sqlite3 database</td></tr>
|
117
|
+
<tr><td>TDB</td><td>tdb</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>TDB database</td></tr>
|
118
|
+
<tr><td>TokyoCabinet</td><td>tokoycabinet</td><td style="color:red">✗</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>TokyoCabinet database</td></tr>
|
119
|
+
<tr><td>YAML</td><td>-</td><td style="color:red">✗</td><td style="color:green">✓</td><td style="color:green">✓</td><td style="color:red">✗</td><td style="color:green">✓</td><td>YAML store</td></tr>
|
120
|
+
</tbody>
|
121
|
+
</table>
|
122
|
+
|
123
|
+
* [1]: Make adapters thread-safe by using `Moneta::Lock`, `Moneta::Pool` or by passing the option `:threadsafe => true` to `Moneta#new`.
|
124
|
+
* [2]: Share a Moneta store between multiple processes using `Moneta::Shared` (See below).
|
125
|
+
* [3]: Add expiration support by using `Moneta::Expires` or by passing the option `:expires => true` to `Moneta#new`.
|
126
|
+
* [4]: There are some servers which use the memcached protocol but which are persistent (e.g. MemcacheDB, Kai, IronCache, ...)
|
127
|
+
* [5]: Depends on server
|
128
|
+
* [6]: Store is multi-process safe because it is an in-memory store, values are not shared between multiple processes
|
129
|
+
|
71
130
|
## Proxies
|
72
131
|
|
73
132
|
In addition it supports proxies (Similar to [Rack middlewares](http://rack.github.com/)) which
|
@@ -75,14 +134,15 @@ add additional features to storage backends:
|
|
75
134
|
|
76
135
|
* `Moneta::Proxy` and `Moneta::Wrapper` proxy base classes
|
77
136
|
* `Moneta::Expires` to add expiration support to stores which don't support it natively. Add it in the builder using `use :Expires`.
|
78
|
-
* `Moneta::Stack` to stack multiple stores (Read returns result from first where the key is found, writes go to all stores). Add it in the builder using `use
|
137
|
+
* `Moneta::Stack` to stack multiple stores (Read returns result from first where the key is found, writes go to all stores). Add it in the builder using `use(:Stack) {}`.
|
79
138
|
* `Moneta::Transformer` transforms keys and values (Marshal, YAML, JSON, Base64, MD5, ...). Add it in the builder using `use :Transformer`.
|
80
|
-
* `Moneta::Cache` combine two stores, one as backend and one as cache (e.g. `Moneta::Adapters::File` + `Moneta::Adapters::Memory`). Add it in the builder using `use
|
139
|
+
* `Moneta::Cache` combine two stores, one as backend and one as cache (e.g. `Moneta::Adapters::File` + `Moneta::Adapters::Memory`). Add it in the builder using `use(:Cache) {}`.
|
81
140
|
* `Moneta::Lock` to make store thread safe. Add it in the builder using `use :Lock`.
|
141
|
+
* `Moneta::Pool` to create a pool of stores as a means of making the store thread safe. Add it in the builder using `use(:Pool) {}`.
|
82
142
|
* `Moneta::Logger` to log database accesses. Add it in the builder using `use :Logger`.
|
83
|
-
* `Moneta::Shared` to share a store between multiple processes. Add it in the builder using `use
|
143
|
+
* `Moneta::Shared` to share a store between multiple processes. Add it in the builder using `use(:Shared) {}`.
|
84
144
|
|
85
|
-
|
145
|
+
### Serializers and compressors (`Moneta::Transformer`)
|
86
146
|
|
87
147
|
Supported serializers:
|
88
148
|
|
@@ -172,7 +232,7 @@ end
|
|
172
232
|
|
173
233
|
### Expiration
|
174
234
|
|
175
|
-
The Cassandra, Memcached and
|
235
|
+
The Cassandra, Memcached, Redis and Mongo backends supports expires values natively.
|
176
236
|
|
177
237
|
~~~ ruby
|
178
238
|
cache = Moneta::Adapters::Memcached.new
|
@@ -185,12 +245,21 @@ end
|
|
185
245
|
# Expires in 60 seconds
|
186
246
|
cache.store(key, value, :expires => 60)
|
187
247
|
|
248
|
+
# Never expire
|
249
|
+
cache.store(key, value, :expires => 0)
|
250
|
+
cache.store(key, value, :expires => false)
|
251
|
+
|
188
252
|
# Update expires time if value is found
|
189
253
|
cache.load(key, :expires => 30)
|
190
254
|
cache.key?(key, :expires => 30)
|
255
|
+
|
256
|
+
# Or remove the expiration if found
|
257
|
+
cache.load(key, :expires => false)
|
258
|
+
cache.key?(key, :expires => 0)
|
191
259
|
~~~
|
192
260
|
|
193
|
-
You can add the expires feature to other backends using the Expires proxy
|
261
|
+
You can add the expires feature to other backends using the `Moneta::Expires` proxy. But be aware
|
262
|
+
that expired values are not deleted automatically if they are not looked up.
|
194
263
|
|
195
264
|
~~~ ruby
|
196
265
|
# Using the :expires option
|
@@ -257,32 +326,6 @@ counters['counter'] = '10'
|
|
257
326
|
counters.increment('counter') # returns 11
|
258
327
|
~~~
|
259
328
|
|
260
|
-
Stores which support incrementation (you have to use `Moneta::Lock` if you want to use the store in a multithreading environment.)
|
261
|
-
|
262
|
-
* ActiveRecord
|
263
|
-
* File
|
264
|
-
* HBase
|
265
|
-
* LRUHash
|
266
|
-
* LevelDB
|
267
|
-
* Memcached
|
268
|
-
* Memory
|
269
|
-
* Redis
|
270
|
-
* SDBM/DBM/GDBM
|
271
|
-
* Sequel
|
272
|
-
* Sqlite
|
273
|
-
* TokyoCabinet
|
274
|
-
* YAML/PStore
|
275
|
-
|
276
|
-
Stores which don't support incrementation:
|
277
|
-
|
278
|
-
* Cassandra
|
279
|
-
* Couch
|
280
|
-
* DataMapper
|
281
|
-
* Fog
|
282
|
-
* LocalMemCache
|
283
|
-
* Mongo
|
284
|
-
* Riak
|
285
|
-
|
286
329
|
### Syntactic sugar and option merger
|
287
330
|
|
288
331
|
For raw data access as described before the class `Moneta::OptionMerger` is used. It works like this:
|
@@ -524,19 +567,15 @@ to compare the speed of the different key value stores for different key/value s
|
|
524
567
|
Feel free to add your own configurations! The impact of Moneta should be minimal since it is only a thin layer
|
525
568
|
on top of the different stores.
|
526
569
|
|
527
|
-
## More information
|
528
|
-
|
529
|
-
* http://yehudakatz.com/2009/02/12/whats-the-point/
|
530
|
-
* http://yehudakatz.com/2009/02/12/initial-release-of-moneta-unified-keyvalue-store-api/
|
531
|
-
|
532
570
|
## Alternatives
|
533
571
|
|
534
572
|
* [Horcrux](https://github.com/technoweenie/horcrux): Used at github, supports batch operations but only Memcached backend
|
573
|
+
* [ActiveSupport::Cache::Store](http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html): The Rails cache store abstraction
|
535
574
|
* [ToyStore](https://github.com/jnunemaker/toystore): ORM mapper for key/value stores
|
536
575
|
* [ToyStore Adapter](https://github.com/jnunemaker/adapter): Adapter to key/value stores used by ToyStore, Moneta can be used directly with the ToyStore Memory adapter
|
537
576
|
|
538
577
|
## Authors
|
539
578
|
|
540
|
-
* Daniel Mendler
|
541
|
-
* Hannes Georg
|
542
|
-
* Originally by Yehuda Katz and contributors
|
579
|
+
* Daniel Mendler (@minad)
|
580
|
+
* Hannes Georg (@hannesg)
|
581
|
+
* Originally by Yehuda Katz (@wycats) and contributors
|
data/Rakefile
CHANGED
@@ -1,32 +1,47 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
rescue Exception
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
namespace :test do
|
13
|
-
task :parallel do
|
14
|
-
if defined?(JRUBY_VERSION)
|
15
|
-
puts 'No tests executed in parallel in JRuby'
|
16
|
-
else
|
17
|
-
specs = Dir['spec/*/*_spec.rb'].reject {|s| s =~ /memcached|redis|client|shared|riak/ }
|
18
|
-
sh("parallel_rspec -m 5 #{specs.join(' ')}")
|
1
|
+
def rspec(spec)
|
2
|
+
sh("rspec #{spec}")
|
3
|
+
true
|
4
|
+
rescue Exception => ex
|
5
|
+
if $?.termsig
|
6
|
+
sig = nil
|
7
|
+
Signal.list.each do |name, id|
|
8
|
+
if id == $?.termsig
|
9
|
+
sig = name
|
10
|
+
break
|
11
|
+
end
|
19
12
|
end
|
13
|
+
puts "\e[31m########## SIG#{sig} rspec #{spec} ##########\e[0m"
|
20
14
|
end
|
15
|
+
false
|
16
|
+
end
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
18
|
+
task :test do
|
19
|
+
# memcached and redis specs cannot be used in parallel
|
20
|
+
# because of flushing and namespace lacking in redis
|
21
|
+
specs = Dir['spec/*/*_spec.rb']
|
22
|
+
parallel = specs.reject {|s| s =~ /memcached|redis|client|shared|riak/ }
|
23
|
+
serial = specs - parallel
|
24
|
+
threads = []
|
25
|
+
failed = false
|
26
|
+
parallel.each do |spec|
|
27
|
+
threads << Thread.new do
|
28
|
+
begin
|
29
|
+
failed = true unless rspec(spec)
|
30
|
+
ensure
|
31
|
+
threads.delete Thread.current
|
32
|
+
end
|
29
33
|
end
|
34
|
+
sleep 0.1
|
35
|
+
sleep 0.1 while threads.size >= 20
|
36
|
+
end
|
37
|
+
sleep 0.1 until threads.empty?
|
38
|
+
serial.each do |spec|
|
39
|
+
failed = true unless rspec(spec)
|
40
|
+
end
|
41
|
+
if failed
|
42
|
+
fail "\e[31m########## MONETA TESTSUITE FAILED ##########\e[0m"
|
43
|
+
else
|
44
|
+
puts "\e[32m########## MONETA TESTSUITE SUCCEDED ##########\e[0m"
|
30
45
|
end
|
31
46
|
end
|
32
47
|
|
data/benchmarks/run.rb
CHANGED
@@ -5,12 +5,17 @@ require 'benchmark'
|
|
5
5
|
require 'moneta'
|
6
6
|
|
7
7
|
STORES = {
|
8
|
+
# SDBM is unstable
|
9
|
+
# :SDBM => { :file => 'bench.sdbm' },
|
10
|
+
# YAML is so fucking slow
|
11
|
+
# :YAML => { :file => 'bench.yaml' },
|
8
12
|
:ActiveRecord => { :connection => { :adapter => 'sqlite3', :database => ':memory:' } },
|
9
13
|
:Cassandra => {},
|
10
14
|
:Client => {},
|
11
15
|
:Couch => {},
|
12
16
|
:DBM => { :file => 'bench.dbm' },
|
13
17
|
:DataMapper => { :setup => 'sqlite3:bench.datamapper' },
|
18
|
+
:Daybreak => { :file => 'bench.daybreak' },
|
14
19
|
:File => { :dir => 'bench.file' },
|
15
20
|
:GDBM => { :file => 'bench.gdbm' },
|
16
21
|
:HBase => {},
|
@@ -24,13 +29,11 @@ STORES = {
|
|
24
29
|
:Mongo => {},
|
25
30
|
:PStore => { :file => 'bench.pstore' },
|
26
31
|
:Redis => {},
|
32
|
+
:RestClient => { :url => 'http://localhost:8808/' },
|
27
33
|
:Riak => {},
|
28
|
-
# SDBM is unstable
|
29
|
-
# :SDBM => { :file => 'bench.sdbm' },
|
30
34
|
:Sequel => { :db => 'sqlite:/' },
|
31
35
|
:Sqlite => { :file => ':memory:' },
|
32
|
-
|
33
|
-
# :YAML => { :file => 'bench.yaml' },
|
36
|
+
:TDB => { :file => 'bench.tdb' },
|
34
37
|
}
|
35
38
|
|
36
39
|
CONFIGS = {
|
@@ -129,7 +132,31 @@ Process.fork do
|
|
129
132
|
puts "\e[31mFailed to start Moneta server - #{ex.message}\e[0m"
|
130
133
|
end
|
131
134
|
end
|
132
|
-
|
135
|
+
|
136
|
+
Process.fork do
|
137
|
+
require 'rack'
|
138
|
+
require 'webrick'
|
139
|
+
require 'httpi'
|
140
|
+
require 'rack/moneta_rest'
|
141
|
+
|
142
|
+
# Keep webrick quiet
|
143
|
+
::WEBrick::HTTPServer.class_eval do
|
144
|
+
def access_log(config, req, res); end
|
145
|
+
end
|
146
|
+
::WEBrick::BasicLog.class_eval do
|
147
|
+
def log(level, data); end
|
148
|
+
end
|
149
|
+
|
150
|
+
Rack::Server.start(:app => Rack::Builder.app do
|
151
|
+
use Rack::Lint
|
152
|
+
run Rack::MonetaRest.new(:store => :Memory)
|
153
|
+
end,
|
154
|
+
:environment => :none,
|
155
|
+
:server => :webrick,
|
156
|
+
:Port => 8808)
|
157
|
+
end
|
158
|
+
|
159
|
+
sleep 1 # Wait for servers
|
133
160
|
|
134
161
|
STORES.each do |name, options|
|
135
162
|
begin
|
@@ -143,6 +170,9 @@ STORES.each do |name, options|
|
|
143
170
|
elsif name == :Riak
|
144
171
|
require 'riak'
|
145
172
|
Riak.disable_list_keys_warnings = true
|
173
|
+
elsif name == :RestClient
|
174
|
+
require 'httpi'
|
175
|
+
HTTPI.log = false
|
146
176
|
end
|
147
177
|
|
148
178
|
cache = Moneta.new(name, options.dup)
|