moneta 0.7.12 → 0.7.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: