moneta 0.7.18 → 0.7.19

Sign up to get free protection for your applications and to get access to all the features.
data/lib/moneta/shared.rb CHANGED
@@ -36,24 +36,32 @@ module Moneta
36
36
  protected
37
37
 
38
38
  def wrap(*args)
39
- @adapter ||= Adapters::Client.new(@options)
39
+ connect
40
40
  yield
41
+ end
42
+
43
+ def connect
44
+ @adapter ||= Adapters::Client.new(@options)
41
45
  rescue Errno::ECONNREFUSED, Errno::ENOENT => ex
46
+ start_server
42
47
  tries ||= 0
43
48
  warn "Moneta::Shared - Failed to connect: #{ex.message}" if tries > 0
44
- begin
45
- # TODO: Implement this using forking (MRI) and threading (JRuby)
46
- # to get maximal performance
47
- @adapter = Lock.new(@builder.build.last)
48
- @server = Server.new(@adapter, @options)
49
- @thread = Thread.new { @server.run }
50
- sleep 0.1 until @server.running?
51
- rescue Exception => ex
52
- warn "Moneta::Shared - Failed to start server: #{ex.message}"
53
- @adapter.close if @adapter
54
- @adapter = nil
55
- end
56
49
  (tries += 1) < 3 ? retry : raise
57
50
  end
51
+
52
+ # TODO: Implement this using forking (MRI) and threading (JRuby)
53
+ # to get maximal performance
54
+ def start_server
55
+ @adapter = Lock.new(@builder.build.last)
56
+ @server = Server.new(@adapter, @options)
57
+ @thread = Thread.new { @server.run }
58
+ sleep 0.1 until @server.running?
59
+ rescue Exception => ex
60
+ @adapter.close if @adapter
61
+ @adapter = nil
62
+ @server = nil
63
+ @thread = nil
64
+ warn "Moneta::Shared - Failed to start server: #{ex.message}"
65
+ end
58
66
  end
59
67
  end
@@ -1,5 +1,5 @@
1
1
  module Moneta
2
2
  # Moneta version number
3
3
  # @api public
4
- VERSION = '0.7.18'
4
+ VERSION = '0.7.19'
5
5
  end
@@ -18,7 +18,7 @@ module Rack
18
18
  @pool = ::Moneta.new(@pool, :expires => true) if Symbol === @pool
19
19
  end
20
20
  @pool = ::Moneta::WeakCreate.new(@pool) unless @pool.supports?(:create)
21
- @mutex = Mutex.new
21
+ @mutex = ::Mutex.new
22
22
  end
23
23
 
24
24
  def generate_sid
data/script/benchmarks CHANGED
@@ -28,7 +28,6 @@ end
28
28
 
29
29
  class MonetaBenchmarks
30
30
  DIR = __FILE__ + '.tmp'
31
- FileUtils.mkpath(DIR)
32
31
 
33
32
  STORES = {
34
33
  # SDBM accepts only very short key/value pairs (1k for both)
@@ -378,12 +377,15 @@ class MonetaBenchmarks
378
377
  end
379
378
 
380
379
  def run
380
+ FileUtils.rm_rf(DIR)
381
+ FileUtils.mkpath(DIR)
381
382
  start_servers
382
383
  test_stores
383
384
  print_config
384
385
  generate_data
385
386
  run_benchmarks
386
387
  print_summary
388
+ FileUtils.rm_rf(DIR)
387
389
  end
388
390
  end
389
391
 
@@ -479,7 +479,7 @@ end
479
479
  :options => ":aws_access_key_id => 'fake_access_key_id',
480
480
  :aws_secret_access_key => 'fake_secret_access_key',
481
481
  :provider => 'AWS',
482
- :dir => 'moneta'",
482
+ :dir => 'simple_fog'",
483
483
  # Put Fog into testing mode
484
484
  :preamble => "require 'fog'\nFog.mock!\n"
485
485
  },
@@ -488,27 +488,37 @@ end
488
488
  :options => ":aws_access_key_id => 'fake_access_key_id',
489
489
  :aws_secret_access_key => 'fake_secret_access_key',
490
490
  :provider => 'AWS',
491
- :dir => 'moneta',
491
+ :dir => 'simple_fog_with_expires',
492
492
  :expires => true",
493
493
  # Put Fog into testing mode
494
494
  :preamble => "require 'fog'\nFog.mock!\n",
495
495
  :specs => STANDARD_SPECS.without_increment.without_create.with_expires
496
496
  },
497
497
  'weak_create' => {
498
- :preamble => "start_restserver\n",
498
+ # Put Fog into testing mode
499
+ :preamble => "require 'fog'\nFog.mock!\n",
499
500
  :build => %{Moneta.build do
500
501
  use :WeakCreate
501
- adapter :RestClient, :url => 'http://localhost:8808/moneta/'
502
+ adapter :Fog,
503
+ :aws_access_key_id => 'fake_access_key_id',
504
+ :aws_secret_access_key => 'fake_secret_access_key',
505
+ :provider => 'AWS',
506
+ :dir => 'weak_create'
502
507
  end},
503
- :specs => ADAPTER_SPECS.without_increment.without_concurrent
508
+ :specs => ADAPTER_SPECS.without_increment.without_concurrent.returnsame
504
509
  },
505
510
  'weak_increment' => {
506
- :preamble => "start_restserver\n",
511
+ # Put Fog into testing mode
512
+ :preamble => "require 'fog'\nFog.mock!\n",
507
513
  :build => %{Moneta.build do
508
514
  use :WeakIncrement
509
- adapter :RestClient, :url => 'http://localhost:8808/moneta/'
515
+ adapter :Fog,
516
+ :aws_access_key_id => 'fake_access_key_id',
517
+ :aws_secret_access_key => 'fake_secret_access_key',
518
+ :provider => 'AWS',
519
+ :dir => 'weak_increment'
510
520
  end},
511
- :specs => ADAPTER_SPECS.without_create.without_concurrent
521
+ :specs => ADAPTER_SPECS.without_create.without_concurrent.returnsame
512
522
  },
513
523
  'expires_memory' => {
514
524
  :build => %{Moneta.build do
@@ -1162,8 +1172,7 @@ end}
1162
1172
  it 'updates an existing key/value' do
1163
1173
  store['foo/bar'] = '1'
1164
1174
  store['foo/bar'] = '2'
1165
- records = store.table.find :all, :conditions => { :k => 'foo/bar' }
1166
- records.count.should == 1
1175
+ store.table.where(:k => 'foo/bar').count.should == 1
1167
1176
  end
1168
1177
 
1169
1178
  it 'supports different tables same database' do
@@ -1283,7 +1292,7 @@ end
1283
1292
  :build => "Moneta::Adapters::Fog.new(:aws_access_key_id => 'fake_access_key_id',
1284
1293
  :aws_secret_access_key => 'fake_secret_access_key',
1285
1294
  :provider => 'AWS',
1286
- :dir => 'moneta')",
1295
+ :dir => 'adapter_fog')",
1287
1296
  # Put Fog into testing mode
1288
1297
  :preamble => "require 'fog'\nFog.mock!\n",
1289
1298
  # Fog returns same object in mocking mode (in-memory store)
@@ -1682,7 +1691,7 @@ it 'guarantees that the same value is returned when setting a key' do
1682
1691
  (store[#{key1}] = value).should equal(value)
1683
1692
  end
1684
1693
 
1685
- it 'returns false from key? if a key is not available' do
1694
+ it 'returns false from #key? if a key is not available' do
1686
1695
  store.key?(#{key1}).should be_false
1687
1696
  end
1688
1697
 
@@ -1730,7 +1739,7 @@ end}
1730
1739
  store.load(#{key1}).should == #{val1}
1731
1740
  end
1732
1741
 
1733
- it 'returns true from key? if a key is available' do
1742
+ it 'returns true from #key? if a key is available' do
1734
1743
  store[#{key1}] = #{val1}
1735
1744
  store.key?(#{key1}).should be_true
1736
1745
  end
@@ -1908,7 +1917,7 @@ it 'supports strict expires on store and load' do
1908
1917
  store.load('key1').should be_nil
1909
1918
  end
1910
1919
 
1911
- it 'supports expires on store and key?', :retry => 3 do
1920
+ it 'supports expires on store and #key?', :retry => 3 do
1912
1921
  store.store('key1', 'val1', :expires => 3)
1913
1922
  store.key?('key1').should be_true
1914
1923
  sleep 1
@@ -1917,7 +1926,7 @@ it 'supports expires on store and key?', :retry => 3 do
1917
1926
  store.key?('key1').should be_false
1918
1927
  end
1919
1928
 
1920
- it 'supports strict expires on store and key?' do
1929
+ it 'supports strict expires on store and #key?' do
1921
1930
  store.store('key1', 'val1', :expires => 2)
1922
1931
  store.key?('key1').should be_true
1923
1932
  sleep 3 # Sleep 3 seconds because after 2 seconds the value can still exist!
@@ -1950,7 +1959,7 @@ it 'supports false as no-expires in load' do
1950
1959
  store.load('key1').should == 'val1'
1951
1960
  end
1952
1961
 
1953
- it 'supports updating the expiration time in key?', :retry => 3 do
1962
+ it 'supports updating the expiration time in #key?', :retry => 3 do
1954
1963
  store.store('key2', 'val2', :expires => 3)
1955
1964
  store['key2'].should == 'val2'
1956
1965
  sleep 1
@@ -1962,14 +1971,14 @@ it 'supports updating the expiration time in key?', :retry => 3 do
1962
1971
  store['key2'].should be_nil
1963
1972
  end
1964
1973
 
1965
- it 'supports 0 as no-expires in key?' do
1974
+ it 'supports 0 as no-expires in #key?' do
1966
1975
  store.store('key1', 'val1', :expires => 2)
1967
1976
  store.key?('key1', :expires => 0).should be_true
1968
1977
  sleep 3
1969
1978
  store['key1'].should == 'val1'
1970
1979
  end
1971
1980
 
1972
- it 'supports false as no-expires in key?' do
1981
+ it 'supports false as no-expires in #key?' do
1973
1982
  store.store('key1', 'val1', :expires => 2)
1974
1983
  store.key?('key1', :expires => false ).should be_true
1975
1984
  sleep 3
@@ -2034,7 +2043,7 @@ it 'supports false as no-expires on store and []' do
2034
2043
  store['key1'].should == 'val1'
2035
2044
  end
2036
2045
 
2037
- it 'does not update the expiration time in key? when not asked to do so', :retry => 3 do
2046
+ it 'does not update the expiration time in #key? when not asked to do so', :retry => 3 do
2038
2047
  store.store('key1', 'val1', :expires => 1)
2039
2048
  store.key?('key1').should be_true
2040
2049
  store.key?('key1', :expires => nil).should be_true
@@ -2307,7 +2316,7 @@ it 'refuses to store to keys that cannot be marshalled' do
2307
2316
  end.to raise_error(marshal_error)
2308
2317
  end
2309
2318
 
2310
- it 'refuses to check for key? if the key cannot be marshalled' do
2319
+ it 'refuses to check for #key? if the key cannot be marshalled' do
2311
2320
  expect do
2312
2321
  store.key? Struct.new(:foo).new(:bar)
2313
2322
  end.to raise_error(marshal_error)
@@ -16,10 +16,20 @@ end
16
16
 
17
17
  BUNDLE_FILE = "moneta-bundle-#{RUBY_VERSION}-#{ruby}.tar.gz"
18
18
 
19
- if system("curl -u moneta:#{ENV['DAV_PW']} -k -o #{BUNDLE_FILE} https://mendler.net/dav/#{BUNDLE_FILE}")
19
+ if system("curl -f -u moneta:#{ENV['DAV_PW']} -k -o #{BUNDLE_FILE} https://mendler.net/dav/#{BUNDLE_FILE}")
20
20
  cmd 'rm -rf .bundle'
21
21
  cmd "tar -xpf #{BUNDLE_FILE}"
22
22
  cmd "rm -f #{BUNDLE_FILE}"
23
+
24
+ # Write newest moneta version in Gemfile.lock
25
+ require './lib/moneta/version'
26
+ File.open('Gemfile.lock', 'r+') do |fp|
27
+ content = fp.read
28
+ content.gsub!(/moneta\s*\(.*?\)/, "moneta (#{Moneta::VERSION})")
29
+ fp.truncate(0)
30
+ fp.pos = 0
31
+ fp.write(content)
32
+ end
23
33
  else
24
34
  cmd 'bundle install --path .bundle'
25
35
  cmd 'bundle update'
data/script/kill-travis CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/bin/bash
2
- # Allow Travis-CI builds to be canceled
2
+ # Allow Travis-CI builds to be cancelled
3
3
 
4
4
  if [[ $TRAVIS ]]; then
5
5
  echo 'Started Travis-CI killer!'
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ def rspec(spec)
4
+ if system("rspec #{spec}")
5
+ true
6
+ elsif sig = $?.termsig
7
+ found = Signal.list.to_a.select {|name, id| id == sig }.first
8
+ puts "\e[31m########## SIG#{found ? found.first : sig} rspec #{spec} ##########\e[0m"
9
+ false
10
+ else
11
+ puts "rspec terminated with #{$?.exitstatus}"
12
+ false
13
+ end
14
+ end
15
+
16
+ ENV['PARALLEL_TESTS'] = 'yes'
17
+
18
+ specs = Dir['spec/*/*_spec.rb'].sort
19
+
20
+ # Shuffle specs to ensure equal distribution over the test groups
21
+ # We have to shuffle with the same seed every time because rake is started
22
+ # multiple times!
23
+ old_seed = srand(43)
24
+ specs.shuffle!
25
+ srand(old_seed)
26
+
27
+ # FIXME:
28
+ #
29
+ # * QuickLZ segfaults because of an assertion
30
+ # QuickLZ is also not maintained on Github, but on Bitbucket
31
+ # and I don't know where the issue tracker is.
32
+ #
33
+ # * PStore increment/locking doesn't work correctly on JRuby
34
+ #
35
+ unstable = %w(quicklz riak cassandra)
36
+ unstable += %w(pstore) if defined?(JRUBY_VERSION)
37
+
38
+ unstable_re = /#{unstable.join('|')}/
39
+ unstable = specs.select {|s| s =~ unstable_re }
40
+ specs -= unstable
41
+
42
+ group = ARGV.first || '1/1'
43
+ case group
44
+ when /^(\d+)\/(\d+)$/
45
+ n = $1.to_i
46
+ max = $2.to_i
47
+ if n == max
48
+ specs = specs[(n-1)*(specs.size/max)..-1]
49
+ else
50
+ specs = specs[(n-1)*(specs.size/max), specs.size/max]
51
+ end
52
+ when 'unstable'
53
+ specs = unstable
54
+ else
55
+ puts "Invalid test group #{group}"
56
+ exit 1
57
+ end
58
+
59
+ puts "The following specs will be executed:\n\t#{specs.join "\n\t"}\n\n"
60
+
61
+ # Memcached and Redis specs cannot be used in parallel
62
+ # because of flushing and lacking namespaces
63
+ parallel = []
64
+ %w(memcached redis client shared riak tokyotyrant couch cassandra).each do |name|
65
+ serial = specs.select { |s| s.include?(name) }
66
+ unless serial.empty?
67
+ specs -= serial
68
+ parallel << serial
69
+ end
70
+ end
71
+ parallel += specs.map {|s| [s] }
72
+
73
+ threads = []
74
+ failed = false
75
+ parallel.each do |serial|
76
+ threads << Thread.new do
77
+ begin
78
+ serial.each do |spec|
79
+ failed = true unless rspec(spec)
80
+ end
81
+ ensure
82
+ threads.delete Thread.current
83
+ end
84
+ end
85
+ sleep 0.1
86
+ sleep 0.1 while threads.size >= 5
87
+ end
88
+ sleep 0.1 until threads.empty?
89
+
90
+ if failed
91
+ puts "\e[31m########## MONETA TESTSUITE FAILED ##########\e[0m"
92
+ exit 1
93
+ end
94
+
95
+ puts "\e[32m########## MONETA TESTSUITE SUCCEDED ##########\e[0m"
data/script/upload-bundle CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/bin/bash
2
- curl -u moneta:$DAV_PW -k -T moneta-bundle-*.tar.gz https://mendler.net/dav/ || echo 'Nothing uploaded'
2
+ curl -f -u moneta:$DAV_PW -k -T moneta-bundle-*.tar.gz https://mendler.net/dav/ || echo 'Nothing uploaded'
data/spec/helper.rb CHANGED
@@ -1,23 +1,57 @@
1
1
  require 'rspec'
2
- require 'rspec/core/formatters/progress_formatter'
2
+ require 'rspec/core/formatters/base_text_formatter'
3
3
  require 'rspec/retry'
4
4
  require 'moneta'
5
5
  require 'fileutils'
6
6
  require 'monetaspecs'
7
7
 
8
- if ENV['TRAVIS']
9
- RSpec::Core::Formatters::ProgressFormatter.class_eval do
10
- def example_passed(example)
11
- # do nothing
8
+ class MonetaParallelFormatter < RSpec::Core::Formatters::BaseTextFormatter
9
+ def start(*args)
10
+
11
+ output.puts colorise_summary("STARTING #{ARGV.join(' ')}")
12
+ @stopped = false
13
+ @passed_count = 0
14
+ @heartbeat = Thread.new do
15
+ count = 0
16
+ until @stopped
17
+ if (count += 1) % 60 == 0
18
+ output.puts(color("RUNNING #{ARGV.join(' ')} - #{@passed_count} passed, #{failed_examples.size} failures",
19
+ failed_examples.empty? ? RSpec.configuration.success_color : RSpec.configuration.failure_color))
20
+ end
21
+ sleep 0.5
22
+ end
12
23
  end
13
24
  end
25
+
26
+ def example_passed(example)
27
+ super
28
+ @passed_count += 1
29
+ end
30
+
31
+ def stop
32
+ @stopped = true
33
+ @heartbeat.join
34
+ end
35
+
36
+ def dump_summary(duration, example_count, failure_count, pending_count)
37
+ @duration = duration
38
+ @example_count = example_count
39
+ @failure_count = failure_count
40
+ @pending_count = pending_count
41
+ output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
42
+ dump_commands_to_rerun_failed_examples
43
+ end
44
+
45
+ def summary_line(example_count, failure_count, pending_count)
46
+ "FINISHED #{ARGV.join(' ')} in #{format_duration(duration)} - #{super}"
47
+ end
14
48
  end
15
49
 
16
50
  RSpec.configure do |config|
17
51
  config.verbose_retry = true
18
52
  config.color_enabled = true
19
53
  config.tty = true
20
- config.formatter = :progress
54
+ config.formatter = ENV['PARALLEL_TESTS'] ? MonetaParallelFormatter : :progress
21
55
  end
22
56
 
23
57
  # Disable jruby stdout pollution by memcached
@@ -135,10 +169,9 @@ shared_context 'setup_store' do
135
169
  end
136
170
 
137
171
  after do
138
- store.close.should == nil if store
139
- if @log
140
- @log.close
141
- @log = nil
172
+ if store
173
+ store.close.should == nil
174
+ @store = nil
142
175
  end
143
176
  end
144
177
  end