moneta 0.7.12 → 0.7.13
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +3 -3
- data/CHANGES +5 -0
- data/Gemfile +2 -1
- data/README.md +7 -6
- data/Rakefile +5 -3
- data/lib/moneta/adapters/activerecord.rb +48 -32
- data/lib/moneta/adapters/file.rb +6 -15
- data/lib/moneta/adapters/memcached/dalli.rb +6 -1
- data/lib/moneta/adapters/redis.rb +3 -1
- data/lib/moneta/mixins.rb +1 -1
- data/lib/moneta/version.rb +1 -1
- data/script/benchmarks +12 -5
- data/script/generate-specs +12 -12
- data/script/start-services +3 -3
- data/spec/moneta/adapter_activerecord_spec.rb +2 -2
- data/spec/moneta/adapter_sequel_spec.rb +1 -1
- data/spec/moneta/adapter_yaml_spec.rb +0 -2
- data/spec/moneta/optionmerger_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_sequel_spec.rb +1 -1
- data/spec/moneta/simple_sequel_with_expires_spec.rb +1 -1
- data/spec/moneta/simple_yaml_spec.rb +0 -2
- data/spec/moneta/simple_yaml_with_expires_spec.rb +0 -2
- data/spec/monetaspecs.rb +1 -1
- data/spec/rack/session_moneta_spec.rb +5 -6
- metadata +3 -2
data/.travis.yml
CHANGED
data/CHANGES
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -144,13 +144,13 @@ __NOTE:__ <a name="backend-matrix">The backend matrix</a> is much more readable
|
|
144
144
|
|
145
145
|
<tr><td>Sequel</td><td>sequel</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5">✓</td><td><a href="http://sequel.rubyforge.org/">Sequel</a> ORM</td></tr>
|
146
146
|
|
147
|
-
<tr><td>
|
147
|
+
<tr><td>TokyoTyrant</td><td>tokyotyrant or ruby-tokyotyrant</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5">✓</td><td><a href="http://fallabs.com/tokyotyrant/">TokyoTyrant</a> database</td></tr>
|
148
148
|
|
149
|
-
<tr><td>PStore</td><td>-</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5"
|
149
|
+
<tr><td>PStore</td><td>-</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5">✓<sup>[10]</sup></td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5">✓</td><td><a href="http://ruby-doc.org/stdlib/libdoc/pstore/rdoc/PStore.html">PStore</a> store</td></tr>
|
150
150
|
|
151
|
-
<tr><td>
|
151
|
+
<tr><td>YAML</td><td>-</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5">✓<sup>[10]</sup></td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5">✓</td><td><a href="http://www.ruby-doc.org/stdlib/libdoc/yaml/rdoc/YAML/Store.html">YAML</a> store</td></tr>
|
152
152
|
|
153
|
-
<tr><td>
|
153
|
+
<tr><td>Sqlite</td><td>sqlite3</td><td style="text-align:center;background:#55F">?</td><td style="text-align:center;background:#5F5">✓<sup>[10]</sup></td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5">✓</td><td><a href="http://sqlite.org/">Sqlite3</a> database</td></tr>
|
154
154
|
|
155
155
|
<tr><td>Daybreak</td><td>daybreak</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#55F">(✓)<sup>[7]</sup></td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#5F5">✓</td><td style="text-align:center;background:#F44">✗</td><td style="text-align:center;background:#5F5">✓</td><td>Incredibly fast pure-ruby key/value store <a href="http://propublica.github.com/daybreak/">Daybreak</a></td></tr>
|
156
156
|
|
@@ -211,8 +211,9 @@ __NOTE:__ <a name="backend-matrix">The backend matrix</a> is much more readable
|
|
211
211
|
* [5]: Depends on server
|
212
212
|
* [6]: Store is multi-process safe because it is an in-memory store, values are not shared between multiple processes
|
213
213
|
* [7]: Store is multi-process safe, but not synchronized automatically between multiple processes
|
214
|
-
* [8]: If a store provides atomic increment it can be used with `Moneta::Semaphore`. You can add weak `#increment` using the `Moneta::WeakIncrement` proxy.
|
215
|
-
* [
|
214
|
+
* [8]: If a store provides atomic increment it can be used with `Moneta::Semaphore`. You can add weak `#increment` support using the `Moneta::WeakIncrement` proxy.
|
215
|
+
* [9]: If a store provides atomic creation it can be used with `Moneta::Mutex`. You can add weak `#create` support using the `Moneta::WeakCreate` proxy.
|
216
|
+
* [10]: Sqlite/YAML/PStore are multiprocess safe, but the performance suffers badly since the whole database file must be locked for writing. Use a key/value server if you want multiprocess concurrency!
|
216
217
|
|
217
218
|
------
|
218
219
|
|
data/Rakefile
CHANGED
@@ -21,7 +21,7 @@ task :test do
|
|
21
21
|
# Shuffle specs to ensure equal distribution over the test groups
|
22
22
|
# We have to shuffle with the same seed every time because rake is started
|
23
23
|
# multiple times!
|
24
|
-
old_seed = srand(
|
24
|
+
old_seed = srand(43)
|
25
25
|
specs.shuffle!
|
26
26
|
srand(old_seed)
|
27
27
|
|
@@ -33,8 +33,10 @@ task :test do
|
|
33
33
|
# QuickLZ is also not maintained on Github, but on Bitbucket
|
34
34
|
# and I don't know where the issue tracker is.
|
35
35
|
#
|
36
|
-
# * Cassandra
|
37
|
-
|
36
|
+
# * Cassandra and Riak fail spuriously (An expert has to check the adapters!)
|
37
|
+
#
|
38
|
+
# * ActiveRecord has some connection problems (An expert has to check the adapter!)
|
39
|
+
unstable = specs.select {|s| s =~ /quicklz|cassandra|riak|activerecord/ }
|
38
40
|
specs -= unstable
|
39
41
|
|
40
42
|
if group =~ /^(\d+)\/(\d+)$/
|
@@ -36,33 +36,41 @@ module Moneta
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
@table.
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
@table.connection_pool.with_connection do |conn|
|
40
|
+
unless @table.table_exists?
|
41
|
+
conn.create_table(table, :id => false) do |t|
|
42
|
+
# Do not use binary columns (Issue #17)
|
43
|
+
t.string :k, :null => false
|
44
|
+
t.string :v
|
45
|
+
end
|
46
|
+
conn.add_index(table, :k, :unique => true)
|
44
47
|
end
|
45
|
-
@table.connection.add_index(@table.table_name, :k, :unique => true)
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
51
|
# (see Proxy#key?)
|
50
52
|
def key?(key, options = {})
|
51
|
-
|
53
|
+
@table.connection_pool.with_connection do
|
54
|
+
!@table.where(:k => key).empty?
|
55
|
+
end
|
52
56
|
end
|
53
57
|
|
54
58
|
# (see Proxy#load)
|
55
59
|
def load(key, options = {})
|
56
|
-
|
57
|
-
|
60
|
+
@table.connection_pool.with_connection do
|
61
|
+
record = @table.select(:v).where(:k => key).first
|
62
|
+
record && record.v
|
63
|
+
end
|
58
64
|
end
|
59
65
|
|
60
66
|
# (see Proxy#store)
|
61
67
|
def store(key, value, options = {})
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
68
|
+
@table.connection_pool.with_connection do
|
69
|
+
record = @table.select(:k).where(:k => key).first_or_initialize
|
70
|
+
record.v = value
|
71
|
+
record.save
|
72
|
+
value
|
73
|
+
end
|
66
74
|
rescue
|
67
75
|
tries ||= 0
|
68
76
|
(tries += 1) < 10 ? retry : raise
|
@@ -70,24 +78,28 @@ module Moneta
|
|
70
78
|
|
71
79
|
# (see Proxy#delete)
|
72
80
|
def delete(key, options = {})
|
73
|
-
|
74
|
-
record.
|
75
|
-
|
81
|
+
@table.connection_pool.with_connection do
|
82
|
+
if record = @table.where(:k => key).first
|
83
|
+
record.destroy
|
84
|
+
record.v
|
85
|
+
end
|
76
86
|
end
|
77
87
|
end
|
78
88
|
|
79
89
|
# (see Proxy#increment)
|
80
90
|
def increment(key, amount = 1, options = {})
|
81
|
-
@table.
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
amount
|
89
|
-
|
90
|
-
|
91
|
+
@table.connection_pool.with_connection do
|
92
|
+
@table.transaction do
|
93
|
+
if record = @table.where(:k => key).lock.first
|
94
|
+
value = Utils.to_int(record.v) + amount
|
95
|
+
record.v = value.to_s
|
96
|
+
record.save
|
97
|
+
value
|
98
|
+
elsif create(key, amount.to_s, options)
|
99
|
+
amount
|
100
|
+
else
|
101
|
+
raise 'Concurrent modification'
|
102
|
+
end
|
91
103
|
end
|
92
104
|
end
|
93
105
|
rescue
|
@@ -97,11 +109,13 @@ module Moneta
|
|
97
109
|
|
98
110
|
# (see Proxy#create)
|
99
111
|
def create(key, value, options = {})
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
112
|
+
@table.connection_pool.with_connection do
|
113
|
+
record = @table.new
|
114
|
+
record.k = key
|
115
|
+
record.v = value
|
116
|
+
record.save
|
117
|
+
true
|
118
|
+
end
|
105
119
|
rescue
|
106
120
|
# FIXME: This catches too many errors
|
107
121
|
# it should only catch a not-unique-exception
|
@@ -110,7 +124,9 @@ module Moneta
|
|
110
124
|
|
111
125
|
# (see Proxy#clear)
|
112
126
|
def clear(options = {})
|
113
|
-
@table.
|
127
|
+
@table.connection_pool.with_connection do
|
128
|
+
@table.delete_all
|
129
|
+
end
|
114
130
|
self
|
115
131
|
end
|
116
132
|
end
|
data/lib/moneta/adapters/file.rb
CHANGED
@@ -33,12 +33,8 @@ module Moneta
|
|
33
33
|
temp_file = ::File.join(@dir, "value-#{$$}-#{Thread.current.object_id}")
|
34
34
|
FileUtils.mkpath(::File.dirname(path))
|
35
35
|
::File.open(temp_file, 'wb') {|file| file.write(value) }
|
36
|
-
::File.unlink(path) if ::File.exist?(path)
|
37
36
|
::File.rename(temp_file, path)
|
38
37
|
value
|
39
|
-
rescue Errno::ENOENT
|
40
|
-
::File.unlink(temp_file) rescue nil
|
41
|
-
value
|
42
38
|
end
|
43
39
|
|
44
40
|
# (see Proxy#delete)
|
@@ -63,20 +59,15 @@ module Moneta
|
|
63
59
|
# (see Proxy#increment)
|
64
60
|
def increment(key, amount = 1, options = {})
|
65
61
|
path = store_path(key)
|
66
|
-
::File.
|
62
|
+
FileUtils.mkpath(::File.dirname(path))
|
63
|
+
existed = ::File.exists?(path)
|
64
|
+
::File.open(path, 'ab+') do |f|
|
67
65
|
Thread.pass until f.flock(::File::LOCK_EX)
|
68
|
-
|
66
|
+
content = f.read
|
69
67
|
f.truncate(0)
|
70
|
-
|
71
|
-
f.write(
|
72
|
-
value
|
73
|
-
end
|
74
|
-
rescue Errno::ENOENT
|
75
|
-
if create(key, amount.to_s, options)
|
68
|
+
amount += Utils.to_int(content) if existed || !content.empty?
|
69
|
+
f.write(amount.to_s)
|
76
70
|
amount
|
77
|
-
else
|
78
|
-
# Concurrent modification
|
79
|
-
retry
|
80
71
|
end
|
81
72
|
end
|
82
73
|
|
@@ -53,7 +53,12 @@ module Moneta
|
|
53
53
|
# FIXME: There is a Dalli bug, load(key) returns a wrong value after increment
|
54
54
|
# therefore we set default = nil and create the counter manually
|
55
55
|
# See https://github.com/mperham/dalli/issues/309
|
56
|
-
result =
|
56
|
+
result =
|
57
|
+
if amount >= 0
|
58
|
+
@backend.incr(key, amount, expires_value(options) || nil, nil)
|
59
|
+
else
|
60
|
+
@backend.decr(key, -amount, expires_value(options) || nil, nil)
|
61
|
+
end
|
57
62
|
if result
|
58
63
|
result
|
59
64
|
elsif create(key, amount.to_s, options)
|
data/lib/moneta/mixins.rb
CHANGED
data/lib/moneta/version.rb
CHANGED
data/script/benchmarks
CHANGED
@@ -34,7 +34,7 @@ class MonetaBenchmarks
|
|
34
34
|
# SDBM is unstable, YAML is too slow
|
35
35
|
# :SDBM => { :file => "#{DIR}/sdbm" },
|
36
36
|
# :YAML => { :file => "#{DIR}/yaml" },
|
37
|
-
:ActiveRecord => { :table => 'activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta' } },
|
37
|
+
:ActiveRecord => { :table => 'activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :username => 'root', :database => 'moneta' } },
|
38
38
|
:Cassandra => {},
|
39
39
|
:Client => {},
|
40
40
|
:Couch => {},
|
@@ -57,7 +57,10 @@ class MonetaBenchmarks
|
|
57
57
|
:Redis => {},
|
58
58
|
:RestClient => { :url => 'http://localhost:8808/' },
|
59
59
|
:Riak => {},
|
60
|
-
:Sequel => { :
|
60
|
+
:Sequel => { :table => 'sequel',
|
61
|
+
:db => (defined?(JRUBY_VERSION) ?
|
62
|
+
'jdbc:mysql://localhost/moneta?user=root' :
|
63
|
+
'mysql2://root:@localhost/moneta') },
|
61
64
|
:Sqlite => { :file => ':memory:' },
|
62
65
|
:TDB => { :file => "#{DIR}/tdb" },
|
63
66
|
:TokyoCabinet => { :file => "#{DIR}/tokyocabinet" },
|
@@ -306,14 +309,13 @@ class MonetaBenchmarks
|
|
306
309
|
|
307
310
|
@config[:runs].times do |run|
|
308
311
|
store.clear
|
309
|
-
print "%s[%-#{2 * @config[:runs]}s] " % ["\b" * (2 * @config[:runs] + 3), state << 'W']
|
310
312
|
|
311
313
|
@data.shuffle!
|
312
314
|
m1 = Benchmark.measure do
|
313
315
|
@data.each {|k,v| store[k] = v }
|
314
316
|
end
|
315
317
|
|
316
|
-
print "%s[%-#{2 * @config[:runs]}s] " % ["\b" * (2 * @config[:runs] + 3), state << '
|
318
|
+
print "%s[%-#{2 * @config[:runs]}s] " % ["\b" * (2 * @config[:runs] + 3), state << 'W']
|
317
319
|
|
318
320
|
@data.shuffle!
|
319
321
|
error = 0
|
@@ -323,6 +325,8 @@ class MonetaBenchmarks
|
|
323
325
|
end
|
324
326
|
end
|
325
327
|
|
328
|
+
print "%s[%-#{2 * @config[:runs]}s] " % ["\b" * (2 * @config[:runs] + 3), state << 'R']
|
329
|
+
|
326
330
|
if type == 'Measure'
|
327
331
|
@stats[name][:write] << m1.real * 1000
|
328
332
|
@stats[name][:error] << error
|
@@ -340,7 +344,10 @@ class MonetaBenchmarks
|
|
340
344
|
end
|
341
345
|
|
342
346
|
def run_benchmarks
|
343
|
-
STORES.each
|
347
|
+
STORES.each do |name, options|
|
348
|
+
benchmark_store(name, options)
|
349
|
+
sleep 1
|
350
|
+
end
|
344
351
|
end
|
345
352
|
|
346
353
|
def print_summary
|
data/script/generate-specs
CHANGED
@@ -305,13 +305,13 @@ end
|
|
305
305
|
'simple_yaml' => {
|
306
306
|
:store => :YAML,
|
307
307
|
:options => ':file => File.join(make_tempdir, "simple_yaml")',
|
308
|
-
:specs => STANDARD_SPECS.without_marshallable_value,
|
308
|
+
:specs => STANDARD_SPECS.without_marshallable_value.without_concurrent,
|
309
309
|
:load_value => 'value'
|
310
310
|
},
|
311
311
|
'simple_yaml_with_expires' => {
|
312
312
|
:store => :YAML,
|
313
313
|
:options => ':file => File.join(make_tempdir, "simple_yaml_with_expires"), :expires => true',
|
314
|
-
:specs => STANDARD_SPECS.without_marshallable_value.with_expires,
|
314
|
+
:specs => STANDARD_SPECS.without_marshallable_value.with_expires.without_concurrent,
|
315
315
|
:load_value => 'value'
|
316
316
|
},
|
317
317
|
'simple_localmemcache' => {
|
@@ -423,13 +423,13 @@ end
|
|
423
423
|
},
|
424
424
|
'simple_sequel' => {
|
425
425
|
:store => :Sequel,
|
426
|
-
:options => ':db => (defined?(JRUBY_VERSION) ? "jdbc:mysql" : "mysql2
|
426
|
+
:options => ':db => (defined?(JRUBY_VERSION) ? "jdbc:mysql://localhost/moneta?user=root" : "mysql2://root:@localhost/moneta"), :table => "simple_sequel"',
|
427
427
|
:load_value => '::Marshal.load(value.unpack(\'m\').first)',
|
428
428
|
:specs => STANDARD_SPECS
|
429
429
|
},
|
430
430
|
'simple_sequel_with_expires' => {
|
431
431
|
:store => :Sequel,
|
432
|
-
:options => ':db => (defined?(JRUBY_VERSION) ? "jdbc:mysql" : "mysql2
|
432
|
+
:options => ':db => (defined?(JRUBY_VERSION) ? "jdbc:mysql://localhost/moneta?user=root" : "mysql2://root:@localhost/moneta"), :table => "simple_sequel_with_expires", :expires => true',
|
433
433
|
:specs => STANDARD_SPECS.with_expires,
|
434
434
|
:load_value => '::Marshal.load(value.unpack(\'m\').first)'
|
435
435
|
},
|
@@ -460,12 +460,12 @@ end
|
|
460
460
|
'simple_activerecord' => {
|
461
461
|
:store => :ActiveRecord,
|
462
462
|
:specs => STANDARD_SPECS,
|
463
|
-
:options => ":table => 'simple_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta' }",
|
463
|
+
:options => ":table => 'simple_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' }",
|
464
464
|
:load_value => '::Marshal.load(value.unpack(\'m\').first)'
|
465
465
|
},
|
466
466
|
'simple_activerecord_with_expires' => {
|
467
467
|
:store => :ActiveRecord,
|
468
|
-
:options => ":table => 'simple_activerecord_with_expires', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta' }, :expires => true",
|
468
|
+
:options => ":table => 'simple_activerecord_with_expires', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' }, :expires => true",
|
469
469
|
:specs => STANDARD_SPECS.with_expires,
|
470
470
|
:load_value => '::Marshal.load(value.unpack(\'m\').first)'
|
471
471
|
},
|
@@ -1101,7 +1101,7 @@ it 'compile transformer class' do
|
|
1101
1101
|
end}
|
1102
1102
|
},
|
1103
1103
|
'adapter_activerecord' => {
|
1104
|
-
:build => "Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta' })",
|
1104
|
+
:build => "Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' })",
|
1105
1105
|
:specs => ADAPTER_SPECS,
|
1106
1106
|
:tests => %{
|
1107
1107
|
it 'updates an existing key/value' do
|
@@ -1112,7 +1112,7 @@ it 'updates an existing key/value' do
|
|
1112
1112
|
end
|
1113
1113
|
|
1114
1114
|
it 'uses an existing connection' do
|
1115
|
-
ActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta'
|
1115
|
+
ActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root'
|
1116
1116
|
|
1117
1117
|
store = Moneta::Adapters::ActiveRecord.new(:table => 'activerecord_existing')
|
1118
1118
|
store.table.should be_table_exists
|
@@ -1308,7 +1308,7 @@ end}
|
|
1308
1308
|
:specs => ADAPTER_SPECS.without_multiprocess
|
1309
1309
|
},
|
1310
1310
|
'adapter_sequel' => {
|
1311
|
-
:build => 'Moneta::Adapters::Sequel.new(:db => (defined?(JRUBY_VERSION) ? "jdbc:mysql" : "mysql2
|
1311
|
+
:build => 'Moneta::Adapters::Sequel.new(:db => (defined?(JRUBY_VERSION) ? "jdbc:mysql://localhost/moneta?user=root" : "mysql2://root:@localhost/moneta"), :table => "adapter_sequel")',
|
1312
1312
|
:specs => ADAPTER_SPECS
|
1313
1313
|
},
|
1314
1314
|
'adapter_sqlite' => {
|
@@ -1333,7 +1333,7 @@ end}
|
|
1333
1333
|
},
|
1334
1334
|
'adapter_yaml' => {
|
1335
1335
|
:build => 'Moneta::Adapters::YAML.new(:file => File.join(make_tempdir, "adapter_yaml"))',
|
1336
|
-
:specs => STANDARD_SPECS.simplevalues_only.simplekeys_only.without_transform
|
1336
|
+
:specs => STANDARD_SPECS.simplevalues_only.simplekeys_only.without_transform.without_concurrent
|
1337
1337
|
},
|
1338
1338
|
'mutex' => {
|
1339
1339
|
:store => :Memory,
|
@@ -1531,7 +1531,7 @@ it 'has method #raw' do
|
|
1531
1531
|
end
|
1532
1532
|
|
1533
1533
|
it 'has method #expires' do
|
1534
|
-
store.expires(10).default_options.should == {:store=>{:expires=>10},:create=>{:expires=>10}}
|
1534
|
+
store.expires(10).default_options.should == {:store=>{:expires=>10},:create=>{:expires=>10},:increment=>{:expires=>10}}
|
1535
1535
|
end
|
1536
1536
|
|
1537
1537
|
it 'has method #prefix' do
|
@@ -1974,7 +1974,7 @@ SPECS['concurrent_increment'] = %{def increment_thread(name)
|
|
1974
1974
|
Thread.new do
|
1975
1975
|
s = new_store
|
1976
1976
|
1000.times do |i|
|
1977
|
-
s.increment('counter')
|
1977
|
+
s.increment('counter', 1, :expires => false)
|
1978
1978
|
s.store("\#{name}\#{i}", i.to_s, :expires => false)
|
1979
1979
|
sleep 0.01 if i % 100 == 0
|
1980
1980
|
end
|
data/script/start-services
CHANGED
@@ -7,7 +7,7 @@ describe_moneta "adapter_activerecord" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def new_store
|
10
|
-
Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta' })
|
10
|
+
Moneta::Adapters::ActiveRecord.new(:table => 'adapter_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' })
|
11
11
|
end
|
12
12
|
|
13
13
|
def load_value(value)
|
@@ -33,7 +33,7 @@ describe_moneta "adapter_activerecord" do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'uses an existing connection' do
|
36
|
-
ActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta'
|
36
|
+
ActiveRecord::Base.establish_connection :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root'
|
37
37
|
|
38
38
|
store = Moneta::Adapters::ActiveRecord.new(:table => 'activerecord_existing')
|
39
39
|
store.table.should be_table_exists
|
@@ -7,7 +7,7 @@ describe_moneta "adapter_sequel" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def new_store
|
10
|
-
Moneta::Adapters::Sequel.new(:db => (defined?(JRUBY_VERSION) ? "jdbc:mysql" : "mysql2
|
10
|
+
Moneta::Adapters::Sequel.new(:db => (defined?(JRUBY_VERSION) ? "jdbc:mysql://localhost/moneta?user=root" : "mysql2://root:@localhost/moneta"), :table => "adapter_sequel")
|
11
11
|
end
|
12
12
|
|
13
13
|
def load_value(value)
|
@@ -15,8 +15,6 @@ describe_moneta "adapter_yaml" do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
include_context 'setup_store'
|
18
|
-
it_should_behave_like 'concurrent_create'
|
19
|
-
it_should_behave_like 'concurrent_increment'
|
20
18
|
it_should_behave_like 'create'
|
21
19
|
it_should_behave_like 'features'
|
22
20
|
it_should_behave_like 'increment'
|
@@ -81,7 +81,7 @@ describe_moneta "optionmerger" do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'has method #expires' do
|
84
|
-
store.expires(10).default_options.should == {:store=>{:expires=>10},:create=>{:expires=>10}}
|
84
|
+
store.expires(10).default_options.should == {:store=>{:expires=>10},:create=>{:expires=>10},:increment=>{:expires=>10}}
|
85
85
|
end
|
86
86
|
|
87
87
|
it 'has method #prefix' do
|
@@ -7,7 +7,7 @@ describe_moneta "simple_activerecord" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def new_store
|
10
|
-
Moneta.new(:ActiveRecord, :table => 'simple_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta' }, :logger => {:file => File.join(make_tempdir, 'simple_activerecord.log')})
|
10
|
+
Moneta.new(:ActiveRecord, :table => 'simple_activerecord', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' }, :logger => {:file => File.join(make_tempdir, 'simple_activerecord.log')})
|
11
11
|
end
|
12
12
|
|
13
13
|
def load_value(value)
|
@@ -7,7 +7,7 @@ describe_moneta "simple_activerecord_with_expires" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def new_store
|
10
|
-
Moneta.new(:ActiveRecord, :table => 'simple_activerecord_with_expires', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta' }, :expires => true, :logger => {:file => File.join(make_tempdir, 'simple_activerecord_with_expires.log')})
|
10
|
+
Moneta.new(:ActiveRecord, :table => 'simple_activerecord_with_expires', :connection => { :adapter => (defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'), :database => 'moneta', :username => 'root' }, :expires => true, :logger => {:file => File.join(make_tempdir, 'simple_activerecord_with_expires.log')})
|
11
11
|
end
|
12
12
|
|
13
13
|
def load_value(value)
|
@@ -7,7 +7,7 @@ describe_moneta "simple_sequel" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def new_store
|
10
|
-
Moneta.new(:Sequel, :db => (defined?(JRUBY_VERSION) ? "jdbc:mysql" : "mysql2
|
10
|
+
Moneta.new(:Sequel, :db => (defined?(JRUBY_VERSION) ? "jdbc:mysql://localhost/moneta?user=root" : "mysql2://root:@localhost/moneta"), :table => "simple_sequel", :logger => {:file => File.join(make_tempdir, 'simple_sequel.log')})
|
11
11
|
end
|
12
12
|
|
13
13
|
def load_value(value)
|
@@ -7,7 +7,7 @@ describe_moneta "simple_sequel_with_expires" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def new_store
|
10
|
-
Moneta.new(:Sequel, :db => (defined?(JRUBY_VERSION) ? "jdbc:mysql" : "mysql2
|
10
|
+
Moneta.new(:Sequel, :db => (defined?(JRUBY_VERSION) ? "jdbc:mysql://localhost/moneta?user=root" : "mysql2://root:@localhost/moneta"), :table => "simple_sequel_with_expires", :expires => true, :logger => {:file => File.join(make_tempdir, 'simple_sequel_with_expires.log')})
|
11
11
|
end
|
12
12
|
|
13
13
|
def load_value(value)
|
@@ -15,8 +15,6 @@ describe_moneta "simple_yaml" do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
include_context 'setup_store'
|
18
|
-
it_should_behave_like 'concurrent_create'
|
19
|
-
it_should_behave_like 'concurrent_increment'
|
20
18
|
it_should_behave_like 'create'
|
21
19
|
it_should_behave_like 'features'
|
22
20
|
it_should_behave_like 'increment'
|
@@ -15,8 +15,6 @@ describe_moneta "simple_yaml_with_expires" do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
include_context 'setup_store'
|
18
|
-
it_should_behave_like 'concurrent_create'
|
19
|
-
it_should_behave_like 'concurrent_increment'
|
20
18
|
it_should_behave_like 'create'
|
21
19
|
it_should_behave_like 'create_expires'
|
22
20
|
it_should_behave_like 'expires'
|
data/spec/monetaspecs.rb
CHANGED
@@ -17149,7 +17149,7 @@ shared_examples_for 'concurrent_increment' do
|
|
17149
17149
|
Thread.new do
|
17150
17150
|
s = new_store
|
17151
17151
|
1000.times do |i|
|
17152
|
-
s.increment('counter')
|
17152
|
+
s.increment('counter', 1, :expires => false)
|
17153
17153
|
s.store("#{name}#{i}", i.to_s, :expires => false)
|
17154
17154
|
sleep 0.01 if i % 100 == 0
|
17155
17155
|
end
|
@@ -304,7 +304,7 @@ describe Rack::Session::Moneta do
|
|
304
304
|
end
|
305
305
|
|
306
306
|
it "does not suffer a race-condition in get_session" do
|
307
|
-
# By lying about existence of a key this proxy tricks the session
|
307
|
+
# By lying about existence of a key this proxy tricks the session
|
308
308
|
# to overwrite values when it wouldn't normally.
|
309
309
|
broken_key = Class.new(::Moneta::Proxy) do
|
310
310
|
def key?(key, *args)
|
@@ -318,15 +318,14 @@ describe Rack::Session::Moneta do
|
|
318
318
|
end
|
319
319
|
|
320
320
|
# Override the SID generator with one that returns predefined values.
|
321
|
-
|
322
|
-
|
323
|
-
shift || raise(
|
321
|
+
def pool.generate_sid(*)
|
322
|
+
@fake_sid ||= %w(deadbeef deadbeef caffee)
|
323
|
+
@fake_sid.shift || raise('Empty!')
|
324
324
|
end
|
325
|
-
|
325
|
+
|
326
326
|
req = Rack::MockRequest.new(pool)
|
327
327
|
req.get('/')
|
328
328
|
res = req.get('/')
|
329
329
|
res['Set-Cookie'].should =~ /\Arack.session=caffee; /
|
330
330
|
end
|
331
|
-
|
332
331
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moneta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.13
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-02-
|
14
|
+
date: 2013-02-06 00:00:00.000000000 Z
|
15
15
|
dependencies: []
|
16
16
|
description: A unified interface to key/value stores
|
17
17
|
email:
|
@@ -464,3 +464,4 @@ test_files:
|
|
464
464
|
- spec/rack/moneta_cookies_spec.rb
|
465
465
|
- spec/rack/moneta_store_spec.rb
|
466
466
|
- spec/rack/session_moneta_spec.rb
|
467
|
+
has_rdoc:
|