moneta 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. data/.travis.yml +17 -51
  2. data/CHANGES +13 -0
  3. data/Gemfile +4 -4
  4. data/README.md +79 -40
  5. data/Rakefile +40 -25
  6. data/benchmarks/run.rb +35 -5
  7. data/lib/moneta.rb +5 -5
  8. data/lib/moneta/adapters/activerecord.rb +4 -6
  9. data/lib/moneta/adapters/cassandra.rb +8 -11
  10. data/lib/moneta/adapters/couch.rb +3 -1
  11. data/lib/moneta/adapters/daybreak.rb +28 -0
  12. data/lib/moneta/adapters/fog.rb +3 -3
  13. data/lib/moneta/adapters/hbase.rb +2 -4
  14. data/lib/moneta/adapters/memcached/dalli.rb +8 -7
  15. data/lib/moneta/adapters/memcached/native.rb +8 -9
  16. data/lib/moneta/adapters/mongo.rb +42 -11
  17. data/lib/moneta/adapters/pstore.rb +4 -6
  18. data/lib/moneta/adapters/redis.rb +17 -10
  19. data/lib/moneta/adapters/restclient.rb +19 -10
  20. data/lib/moneta/adapters/sequel.rb +4 -6
  21. data/lib/moneta/adapters/tdb.rb +22 -0
  22. data/lib/moneta/expires.rb +28 -12
  23. data/lib/moneta/mixins.rb +64 -3
  24. data/lib/moneta/pool.rb +37 -0
  25. data/lib/moneta/proxy.rb +18 -7
  26. data/lib/moneta/server.rb +1 -1
  27. data/lib/moneta/shared.rb +2 -2
  28. data/lib/moneta/transformer/helper.rb +1 -1
  29. data/lib/moneta/version.rb +1 -1
  30. data/{spec/generate.rb → script/generate-specs.rb} +195 -91
  31. data/script/install-bundle.rb +35 -0
  32. data/spec/helper.rb +6 -0
  33. data/spec/moneta/adapter_activerecord_spec.rb +1 -1
  34. data/spec/moneta/adapter_cassandra_spec.rb +1 -12
  35. data/spec/moneta/adapter_cassandra_with_default_expires_spec.rb +21 -0
  36. data/spec/moneta/adapter_client_spec.rb +1 -1
  37. data/spec/moneta/adapter_cookie_spec.rb +1 -1
  38. data/spec/moneta/adapter_couch_spec.rb +1 -1
  39. data/spec/moneta/adapter_datamapper_spec.rb +1 -1
  40. data/spec/moneta/adapter_daybreak_spec.rb +19 -0
  41. data/spec/moneta/adapter_dbm_spec.rb +1 -1
  42. data/spec/moneta/adapter_file_spec.rb +1 -1
  43. data/spec/moneta/adapter_fog_spec.rb +1 -1
  44. data/spec/moneta/adapter_gdbm_spec.rb +1 -1
  45. data/spec/moneta/adapter_hbase_spec.rb +1 -1
  46. data/spec/moneta/adapter_leveldb_spec.rb +1 -1
  47. data/spec/moneta/adapter_localmemcache_spec.rb +1 -1
  48. data/spec/moneta/adapter_lruhash_spec.rb +1 -1
  49. data/spec/moneta/adapter_memcached_dalli_spec.rb +1 -12
  50. data/spec/moneta/adapter_memcached_dalli_with_default_expires_spec.rb +21 -0
  51. data/spec/moneta/adapter_memcached_native_spec.rb +1 -13
  52. data/spec/moneta/adapter_memcached_native_with_default_expires_spec.rb +21 -0
  53. data/spec/moneta/adapter_memcached_spec.rb +1 -12
  54. data/spec/moneta/adapter_memcached_with_default_expires_spec.rb +21 -0
  55. data/spec/moneta/adapter_memory_spec.rb +1 -1
  56. data/spec/moneta/adapter_mongo_spec.rb +9 -2
  57. data/spec/moneta/adapter_mongo_with_default_expires_spec.rb +21 -0
  58. data/spec/moneta/adapter_pstore_spec.rb +1 -1
  59. data/spec/moneta/adapter_redis_spec.rb +1 -12
  60. data/spec/moneta/adapter_redis_with_default_expires_spec.rb +21 -0
  61. data/spec/moneta/adapter_restclient_spec.rb +1 -1
  62. data/spec/moneta/adapter_riak_spec.rb +1 -1
  63. data/spec/moneta/adapter_sdbm_spec.rb +1 -1
  64. data/spec/moneta/adapter_sequel_spec.rb +1 -1
  65. data/spec/moneta/adapter_sqlite_spec.rb +1 -1
  66. data/spec/moneta/adapter_tdb_spec.rb +19 -0
  67. data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +1 -1
  68. data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +1 -1
  69. data/spec/moneta/adapter_yaml_spec.rb +1 -1
  70. data/spec/moneta/cache_file_memory_spec.rb +1 -1
  71. data/spec/moneta/cache_memory_null_spec.rb +1 -1
  72. data/spec/moneta/expires_file_spec.rb +1 -1
  73. data/spec/moneta/expires_memory_spec.rb +1 -12
  74. data/spec/moneta/expires_memory_with_default_expires_spec.rb +111 -0
  75. data/spec/moneta/lock_spec.rb +1 -1
  76. data/spec/moneta/null_adapter_spec.rb +1 -1
  77. data/spec/moneta/optionmerger_spec.rb +1 -1
  78. data/spec/moneta/pool_spec.rb +23 -0
  79. data/spec/moneta/proxy_expires_memory_spec.rb +1 -1
  80. data/spec/moneta/proxy_redis_spec.rb +1 -1
  81. data/spec/moneta/shared_spec.rb +1 -1
  82. data/spec/moneta/simple_activerecord_spec.rb +1 -1
  83. data/spec/moneta/simple_activerecord_with_expires_spec.rb +1 -1
  84. data/spec/moneta/simple_cassandra_spec.rb +1 -1
  85. data/spec/moneta/simple_client_tcp_spec.rb +1 -1
  86. data/spec/moneta/simple_client_unix_spec.rb +1 -1
  87. data/spec/moneta/simple_couch_spec.rb +1 -1
  88. data/spec/moneta/simple_couch_with_expires_spec.rb +1 -1
  89. data/spec/moneta/simple_datamapper_spec.rb +1 -1
  90. data/spec/moneta/simple_datamapper_with_expires_spec.rb +1 -1
  91. data/spec/moneta/simple_datamapper_with_repository_spec.rb +1 -1
  92. data/spec/moneta/simple_daybreak_spec.rb +144 -0
  93. data/spec/moneta/simple_daybreak_with_expires_spec.rb +145 -0
  94. data/spec/moneta/simple_dbm_spec.rb +1 -1
  95. data/spec/moneta/simple_dbm_with_expires_spec.rb +1 -1
  96. data/spec/moneta/simple_file_spec.rb +1 -1
  97. data/spec/moneta/simple_file_with_expires_spec.rb +1 -1
  98. data/spec/moneta/simple_fog_spec.rb +1 -1
  99. data/spec/moneta/simple_fog_with_expires_spec.rb +1 -1
  100. data/spec/moneta/simple_gdbm_spec.rb +1 -1
  101. data/spec/moneta/simple_gdbm_with_expires_spec.rb +1 -1
  102. data/spec/moneta/simple_hashfile_spec.rb +1 -1
  103. data/spec/moneta/simple_hashfile_with_expires_spec.rb +1 -1
  104. data/spec/moneta/simple_hbase_spec.rb +1 -1
  105. data/spec/moneta/simple_hbase_with_expires_spec.rb +1 -1
  106. data/spec/moneta/simple_leveldb_spec.rb +1 -1
  107. data/spec/moneta/simple_leveldb_with_expires_spec.rb +1 -1
  108. data/spec/moneta/simple_localmemcache_spec.rb +1 -1
  109. data/spec/moneta/simple_localmemcache_with_expires_spec.rb +1 -1
  110. data/spec/moneta/simple_lruhash_spec.rb +1 -1
  111. data/spec/moneta/simple_lruhash_with_expires_spec.rb +1 -1
  112. data/spec/moneta/simple_memcached_dalli_spec.rb +1 -1
  113. data/spec/moneta/simple_memcached_native_spec.rb +1 -1
  114. data/spec/moneta/simple_memcached_spec.rb +1 -1
  115. data/spec/moneta/simple_memory_spec.rb +1 -1
  116. data/spec/moneta/simple_memory_with_compress_spec.rb +1 -1
  117. data/spec/moneta/simple_memory_with_expires_spec.rb +1 -1
  118. data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +1 -1
  119. data/spec/moneta/simple_memory_with_json_serializer_spec.rb +1 -1
  120. data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +1 -1
  121. data/spec/moneta/simple_memory_with_prefix_spec.rb +1 -1
  122. data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +1 -1
  123. data/spec/moneta/simple_mongo_spec.rb +3 -2
  124. data/spec/moneta/simple_null_spec.rb +1 -1
  125. data/spec/moneta/simple_pstore_spec.rb +1 -1
  126. data/spec/moneta/simple_pstore_with_expires_spec.rb +1 -1
  127. data/spec/moneta/simple_redis_spec.rb +1 -1
  128. data/spec/moneta/simple_restclient_spec.rb +1 -1
  129. data/spec/moneta/simple_riak_spec.rb +1 -1
  130. data/spec/moneta/simple_riak_with_expires_spec.rb +1 -1
  131. data/spec/moneta/simple_sdbm_spec.rb +1 -1
  132. data/spec/moneta/simple_sdbm_with_expires_spec.rb +1 -1
  133. data/spec/moneta/simple_sequel_spec.rb +1 -1
  134. data/spec/moneta/simple_sequel_with_expires_spec.rb +1 -1
  135. data/spec/moneta/simple_sqlite_spec.rb +1 -1
  136. data/spec/moneta/simple_sqlite_with_expires_spec.rb +1 -1
  137. data/spec/moneta/simple_tdb_spec.rb +144 -0
  138. data/spec/moneta/{simple_mongo_with_expires_spec.rb → simple_tdb_with_expires_spec.rb} +4 -4
  139. data/spec/moneta/simple_tokyocabinet_spec.rb +1 -1
  140. data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +1 -1
  141. data/spec/moneta/simple_yaml_spec.rb +1 -1
  142. data/spec/moneta/simple_yaml_with_expires_spec.rb +1 -1
  143. data/spec/moneta/stack_file_memory_spec.rb +1 -1
  144. data/spec/moneta/stack_memory_file_spec.rb +1 -1
  145. data/spec/moneta/transformer_bencode_spec.rb +1 -1
  146. data/spec/moneta/transformer_bert_spec.rb +1 -1
  147. data/spec/moneta/transformer_bson_spec.rb +1 -1
  148. data/spec/moneta/transformer_bzip2_spec.rb +1 -1
  149. data/spec/moneta/transformer_json_spec.rb +1 -1
  150. data/spec/moneta/transformer_key_marshal_spec.rb +1 -1
  151. data/spec/moneta/transformer_key_yaml_spec.rb +1 -1
  152. data/spec/moneta/transformer_lzma_spec.rb +1 -1
  153. data/spec/moneta/transformer_lzo_spec.rb +1 -1
  154. data/spec/moneta/transformer_marshal_base64_spec.rb +1 -1
  155. data/spec/moneta/transformer_marshal_escape_spec.rb +1 -1
  156. data/spec/moneta/transformer_marshal_hmac_spec.rb +1 -1
  157. data/spec/moneta/transformer_marshal_md5_spec.rb +1 -1
  158. data/spec/moneta/transformer_marshal_md5_spread_spec.rb +1 -1
  159. data/spec/moneta/transformer_marshal_prefix_spec.rb +1 -1
  160. data/spec/moneta/transformer_marshal_rmd160_spec.rb +1 -1
  161. data/spec/moneta/transformer_marshal_sha1_spec.rb +1 -1
  162. data/spec/moneta/transformer_marshal_sha256_spec.rb +1 -1
  163. data/spec/moneta/transformer_marshal_sha384_spec.rb +1 -1
  164. data/spec/moneta/transformer_marshal_sha512_spec.rb +1 -1
  165. data/spec/moneta/transformer_marshal_spec.rb +1 -1
  166. data/spec/moneta/transformer_marshal_truncate_spec.rb +1 -1
  167. data/spec/moneta/transformer_marshal_uuencode_spec.rb +1 -1
  168. data/spec/moneta/transformer_msgpack_spec.rb +1 -1
  169. data/spec/moneta/transformer_ox_spec.rb +1 -1
  170. data/spec/moneta/transformer_quicklz_spec.rb +1 -1
  171. data/spec/moneta/transformer_snappy_spec.rb +1 -1
  172. data/spec/moneta/transformer_tnet_spec.rb +1 -1
  173. data/spec/moneta/transformer_value_marshal_spec.rb +1 -1
  174. data/spec/moneta/transformer_value_yaml_spec.rb +1 -1
  175. data/spec/moneta/transformer_yaml_spec.rb +1 -1
  176. data/spec/moneta/transformer_zlib_spec.rb +1 -1
  177. data/spec/monetaspecs.rb +105 -3
  178. 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
- - "TASK=test:parallel"
19
- - "TASK=test:non_parallel"
20
- - "TASK=benchmarks CONFIG=uniform_small"
21
- - "TASK=benchmarks CONFIG=uniform_medium"
22
- - "TASK=benchmarks CONFIG=uniform_large"
23
- - "TASK=benchmarks CONFIG=normal_small"
24
- - "TASK=benchmarks CONFIG=normal_medium"
25
- - "TASK=benchmarks CONFIG=normal_large"
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, fix this before activating it again
32
- # alternatives :mri => 'qlzruby'
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 :Stack`.
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 :Cache`.
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 :Shared`.
143
+ * `Moneta::Shared` to share a store between multiple processes. Add it in the builder using `use(:Shared) {}`.
84
144
 
85
- ## Supported serializers and compressors (`Moneta::Transformer`)
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 Redis backends supports expires values directly:
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
- begin
2
- require 'bundler'
3
- Bundler::GemHelper.install_tasks
4
- rescue Exception
5
- end
6
-
7
- task :test => %w(test:parallel test:non_parallel)
8
-
9
- # memcached and redis specs cannot be used in parallel
10
- # because of flushing and namespace lacking in redis
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
- task :non_parallel do
23
- if defined?(JRUBY_VERSION)
24
- # Run all tests in jruby non-parallel
25
- sh('rspec spec/*/*_spec.rb')
26
- else
27
- specs = Dir['spec/*/*_spec.rb'].select {|s| s =~ /memcached|redis|client|shared|riak/ }
28
- sh("rspec #{specs.join(' ')}")
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
- # YAML is so fucking slow
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
- sleep 1 # Wait for server
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)