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 CHANGED
@@ -1,11 +1,11 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.8.7
4
3
  - 1.9.3
5
- - jruby-18mode
4
+ - 1.8.7
6
5
  - jruby-19mode
7
- # - rbx-18mode
6
+ - jruby-18mode
8
7
  # - rbx-19mode
8
+ # - rbx-18mode
9
9
  before_install:
10
10
  - script/kill-travis
11
11
  - script/install-kyotocabinet
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ 0.7.13
2
+
3
+ * Adapters::ActiveRecord: Use connection_pool
4
+ * Adapters::File: Race condition in #increment fixed
5
+
1
6
  0.7.12
2
7
 
3
8
  * Concurrency tests added
data/Gemfile CHANGED
@@ -34,7 +34,8 @@ gem 'fog'
34
34
  gem 'activerecord', '>= 3.2.11'
35
35
  gem 'redis'
36
36
  gem 'mongo'
37
- gem 'sequel'
37
+ # Use sequel master because of deprecation warnings
38
+ gem 'sequel', :github => 'jeremyevans/sequel'
38
39
  gem 'dalli'
39
40
  gem 'riak-client'
40
41
  gem 'cassandra'
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>Sqlite</td><td>sqlite3</td><td style="text-align:center;background:#55F">?</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://sqlite.org/">Sqlite3</a> database</td></tr>
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">✓</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>
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>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>
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>YAML</td><td>-</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://www.ruby-doc.org/stdlib/libdoc/yaml/rdoc/YAML/Store.html">YAML</a> store</td></tr>
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
- * [8]: If a store provides atomic creation it can be used with `Moneta::Mutex`. You can add weak `#create` using the `Moneta::WeakCreate` proxy.
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(42)
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 fails spuriously (An expert has to check the adapter!)
37
- unstable = specs.select {|s| s =~ /quicklz|cassandra/ }
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
- unless @table.table_exists?
40
- @table.connection.create_table(@table.table_name, :id => false) do |t|
41
- # Do not use binary columns (Issue #17)
42
- t.string :k, :null => false
43
- t.string :v
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
- !@table.where(:k => key).empty?
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
- record = @table.select(:v).where(:k => key).first
57
- record && record.v
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
- record = @table.select(:k).where(:k => key).first_or_initialize
63
- record.v = value
64
- record.save
65
- value
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
- if record = @table.where(:k => key).first
74
- record.destroy
75
- record.v
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.transaction do
82
- if record = @table.where(:k => key).lock.first
83
- value = Utils.to_int(record.v) + amount
84
- record.v = value.to_s
85
- record.save
86
- value
87
- elsif create(key, amount.to_s, options)
88
- amount
89
- else
90
- raise 'Concurrent modification'
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
- record = @table.new
101
- record.k = key
102
- record.v = value
103
- record.save
104
- true
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.delete_all
127
+ @table.connection_pool.with_connection do
128
+ @table.delete_all
129
+ end
114
130
  self
115
131
  end
116
132
  end
@@ -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.open(path, 'rb+') do |f|
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
- value = Utils.to_int(f.read) + amount
66
+ content = f.read
69
67
  f.truncate(0)
70
- f.pos = 0
71
- f.write(value.to_s)
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 = amount >= 0 ? @backend.incr(key, amount, nil, nil) : @backend.decr(key, -amount, nil, nil)
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)
@@ -60,7 +60,9 @@ module Moneta
60
60
 
61
61
  # (see Proxy#increment)
62
62
  def increment(key, amount = 1, options = {})
63
- @backend.incrby(key, amount)
63
+ value = @backend.incrby(key, amount)
64
+ update_expires(key, options)
65
+ value
64
66
  end
65
67
 
66
68
  # (see Proxy#clear)
data/lib/moneta/mixins.rb CHANGED
@@ -45,7 +45,7 @@ module Moneta
45
45
  # @return [OptionMerger]
46
46
  # @api public
47
47
  def expires(expires)
48
- with(:expires => expires, :only => [:store, :create])
48
+ with(:expires => expires, :only => [:store, :create, :increment])
49
49
  end
50
50
  end
51
51
 
@@ -1,5 +1,5 @@
1
1
  module Moneta
2
2
  # Moneta version number
3
3
  # @api public
4
- VERSION = '0.7.12'
4
+ VERSION = '0.7.13'
5
5
  end
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 => { :db => (defined?(JRUBY_VERSION) ? 'jdbc:mysql' : 'mysql2') + '://root:@localhost/moneta', :table => '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 << 'R']
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 {|name, options| benchmark_store(name, options) }
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
@@ -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") + "://root:@localhost/moneta", :table => "simple_sequel"',
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") + "://root:@localhost/moneta", :table => "simple_sequel_with_expires", :expires => true',
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") + "://root:@localhost/moneta", :table => "adapter_sequel")',
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
@@ -12,6 +12,6 @@ echo 'Starting TokyoTyrant'
12
12
  # Waiting for servers to start
13
13
  sleep 3
14
14
 
15
- echo 'TokyoTyrant status'
16
- ps aux | grep ttserver
17
- cat /tmp/ttserver.log
15
+ #echo 'TokyoTyrant status'
16
+ #ps aux | grep ttserver
17
+ #cat /tmp/ttserver.log
@@ -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") + "://root:@localhost/moneta", :table => "adapter_sequel")
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") + "://root:@localhost/moneta", :table => "simple_sequel", :logger => {:file => File.join(make_tempdir, 'simple_sequel.log')})
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") + "://root:@localhost/moneta", :table => "simple_sequel_with_expires", :expires => true, :logger => {:file => File.join(make_tempdir, 'simple_sequel_with_expires.log')})
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
- gen = ["deadbeef", "deadbeef", "caffee"]
322
- def gen.hex(_)
323
- shift || raise("Empty!")
321
+ def pool.generate_sid(*)
322
+ @fake_sid ||= %w(deadbeef deadbeef caffee)
323
+ @fake_sid.shift || raise('Empty!')
324
324
  end
325
- pool.instance_variable_set(:@sid_secure, gen)
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.12
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-04 00:00:00.000000000 Z
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: