moneta 0.7.18 → 0.7.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +19 -19
- data/CHANGES +6 -0
- data/CONTRIBUTORS +1 -0
- data/Gemfile +9 -3
- data/SPEC.md +1 -1
- data/lib/action_dispatch/middleware/session/moneta_store.rb +1 -0
- data/lib/moneta.rb +0 -1
- data/lib/moneta/adapters/client.rb +26 -21
- data/lib/moneta/adapters/memcached/dalli.rb +1 -1
- data/lib/moneta/adapters/memcached/native.rb +1 -1
- data/lib/moneta/mixins.rb +0 -21
- data/lib/moneta/pool.rb +1 -1
- data/lib/moneta/server.rb +69 -38
- data/lib/moneta/shared.rb +21 -13
- data/lib/moneta/version.rb +1 -1
- data/lib/rack/session/moneta.rb +1 -1
- data/script/benchmarks +3 -1
- data/script/generate-specs +29 -20
- data/script/install-bundle +11 -1
- data/script/kill-travis +1 -1
- data/script/parallel-tests +95 -0
- data/script/upload-bundle +1 -1
- data/spec/helper.rb +43 -10
- data/spec/moneta/adapter_activerecord_spec.rb +1 -2
- data/spec/moneta/adapter_fog_spec.rb +1 -1
- data/spec/moneta/simple_fog_spec.rb +1 -1
- data/spec/moneta/simple_fog_with_expires_spec.rb +1 -1
- data/spec/moneta/weak_create_spec.rb +8 -3
- data/spec/moneta/weak_increment_spec.rb +8 -3
- data/spec/monetaspecs.rb +647 -647
- data/spec/quality_spec.rb +51 -0
- metadata +5 -3
- data/Rakefile +0 -99
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54ab5446cbb72cf10100e2e72680c4624113aaa0
|
4
|
+
data.tar.gz: c3337a129506fdeab6624542b37ada15a9c16c20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc94d4af7c904ad023cee82ee3ec408e9685273362a94a6cf620ba0d108ea69b660ea8a737bd91491faacd10c09d0e5b1942f429b19fb010df806980e9f1f88b
|
7
|
+
data.tar.gz: 50a2df5e71906df99c2954ed1efb8ca2986234db51f21565c53bbbbdf93e2b07f123d041c6c165a0b24e9876852cbc23d2b4877e94261cf0f8b4bda946da53c1
|
data/.travis.yml
CHANGED
@@ -24,31 +24,31 @@ env:
|
|
24
24
|
global:
|
25
25
|
- secure: "dtM4n7FP8P0UI9Iq+nsvQ7/yfDqsxhfCO9i8zMxm/f9Kxj5Z/4C7jsXsLA+e\n/7FZ9+ld2QjPSPU0LUiDpj/z81bxyZHwqocQ7Nb0DVvO3JRHpr4/iBQQQHd3\n0jvou3mRbu5mBlUjf1/ALaZA+b+vcnsF9fd86UnkY+ChriylGnM="
|
26
26
|
matrix:
|
27
|
-
- "
|
28
|
-
- "
|
29
|
-
- "
|
30
|
-
- "
|
31
|
-
- "
|
32
|
-
- "
|
33
|
-
- "
|
34
|
-
- "
|
35
|
-
- "
|
36
|
-
- "
|
37
|
-
- "
|
38
|
-
- "
|
39
|
-
- "
|
40
|
-
- "
|
41
|
-
- "
|
42
|
-
- "
|
43
|
-
- "
|
27
|
+
- "SCRIPT='parallel-tests 1/10'"
|
28
|
+
- "SCRIPT='parallel-tests 2/10'"
|
29
|
+
- "SCRIPT='parallel-tests 3/10'"
|
30
|
+
- "SCRIPT='parallel-tests 4/10'"
|
31
|
+
- "SCRIPT='parallel-tests 5/10'"
|
32
|
+
- "SCRIPT='parallel-tests 6/10'"
|
33
|
+
- "SCRIPT='parallel-tests 7/10'"
|
34
|
+
- "SCRIPT='parallel-tests 8/10'"
|
35
|
+
- "SCRIPT='parallel-tests 9/10'"
|
36
|
+
- "SCRIPT='parallel-tests 10/10'"
|
37
|
+
- "SCRIPT='parallel-tests unstable'"
|
38
|
+
- "SCRIPT='benchmarks uniform_small'"
|
39
|
+
- "SCRIPT='benchmarks uniform_medium'"
|
40
|
+
- "SCRIPT='benchmarks uniform_large'"
|
41
|
+
- "SCRIPT='benchmarks normal_small'"
|
42
|
+
- "SCRIPT='benchmarks normal_medium'"
|
43
|
+
- "SCRIPT='benchmarks normal_large'"
|
44
44
|
matrix:
|
45
45
|
allow_failures:
|
46
46
|
- rvm: jruby-18mode
|
47
47
|
- rvm: jruby-19mode
|
48
48
|
- rvm: rbx-18mode
|
49
49
|
- rvm: rbx-19mode
|
50
|
-
- env: "
|
51
|
-
script: "bundle exec
|
50
|
+
- env: "SCRIPT='parallel-tests unstable'"
|
51
|
+
script: "eval bundle exec ruby script/$SCRIPT"
|
52
52
|
branches:
|
53
53
|
only:
|
54
54
|
- master
|
data/CHANGES
CHANGED
data/CONTRIBUTORS
CHANGED
@@ -16,6 +16,7 @@ lakshan <lakshan@web2media.net>
|
|
16
16
|
Piotr Murach <pmurach@gmail.com>
|
17
17
|
Potapov Sergey <blake131313@gmail.com>
|
18
18
|
Quin Hoxie <quin@aboutus.org>
|
19
|
+
Ryan T. Hosford <tad.hosford@gmail.com>
|
19
20
|
Scott Wadden <scott.wadden@gmail.com>
|
20
21
|
Tom Meier <ozmeier@yahoo.co.uk>
|
21
22
|
Xavier Shay <xavier@rhnh.net>
|
data/Gemfile
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
+
# Rails 4 requires Ruby >= 1.9
|
2
|
+
def rails_version
|
3
|
+
v = ['>= 3.2.11']
|
4
|
+
v << '< 4.0.0' unless RUBY_VERSION >= '1.9'
|
5
|
+
v
|
6
|
+
end
|
7
|
+
|
1
8
|
source 'https://rubygems.org'
|
2
9
|
gemspec
|
3
10
|
|
4
11
|
# Testing
|
5
|
-
gem 'rake'
|
6
12
|
gem 'rspec'
|
7
13
|
gem 'rspec-retry'
|
8
14
|
|
@@ -38,7 +44,7 @@ gem 'dm-migrations'
|
|
38
44
|
gem 'dm-mysql-adapter'
|
39
45
|
# FIXME: Use fog master because of failing tests, fixed after 1.11.1
|
40
46
|
gem 'fog', :github => 'fog/fog'
|
41
|
-
gem 'activerecord',
|
47
|
+
gem 'activerecord', *rails_version
|
42
48
|
gem 'redis'
|
43
49
|
gem 'mongo'
|
44
50
|
gem 'sequel'
|
@@ -74,5 +80,5 @@ gem 'rack'
|
|
74
80
|
gem 'rack-cache'
|
75
81
|
|
76
82
|
# Rails integration testing
|
77
|
-
gem 'actionpack',
|
83
|
+
gem 'actionpack', *rails_version
|
78
84
|
gem 'minitest', '~> 4.7.4'
|
data/SPEC.md
CHANGED
@@ -65,7 +65,7 @@ Closes the store
|
|
65
65
|
|
66
66
|
### <code>features => Array<Symbol></code> and <code>supports?(Symbol) => [TrueClass, FalseClass]</code>
|
67
67
|
|
68
|
-
Feature detection. Adapters MUST return <code>:create</code> and <code>:increment</code> if these methods are supported.
|
68
|
+
Feature detection. Adapters MUST return <code>:create</code> and <code>:increment</code> if these methods are supported.
|
69
69
|
|
70
70
|
## Additional Options Hashes
|
71
71
|
|
data/lib/moneta.rb
CHANGED
@@ -10,7 +10,6 @@ module Moneta
|
|
10
10
|
autoload :Lock, 'moneta/lock'
|
11
11
|
autoload :Logger, 'moneta/logger'
|
12
12
|
autoload :Mutex, 'moneta/synchronize'
|
13
|
-
autoload :Net, 'moneta/mixins'
|
14
13
|
autoload :OptionMerger, 'moneta/optionmerger'
|
15
14
|
autoload :OptionSupport, 'moneta/mixins'
|
16
15
|
autoload :Pool, 'moneta/pool'
|
@@ -5,7 +5,6 @@ module Moneta
|
|
5
5
|
# Moneta client backend
|
6
6
|
# @api public
|
7
7
|
class Client
|
8
|
-
include Net
|
9
8
|
include Defaults
|
10
9
|
|
11
10
|
# @param [Hash] options
|
@@ -14,50 +13,50 @@ module Moneta
|
|
14
13
|
# @option options [String] :socket Unix socket file name as alternative to `:port` and `:host`
|
15
14
|
def initialize(options = {})
|
16
15
|
@socket = options[:socket] ? UNIXSocket.open(options[:socket]) :
|
17
|
-
TCPSocket.open(options[:host] || '127.0.0.1', options[:port] ||
|
16
|
+
TCPSocket.open(options[:host] || '127.0.0.1', options[:port] || 9000)
|
18
17
|
end
|
19
18
|
|
20
19
|
# (see Proxy#key?)
|
21
20
|
def key?(key, options = {})
|
22
|
-
write(
|
23
|
-
|
21
|
+
write(:key?, key, options)
|
22
|
+
read
|
24
23
|
end
|
25
24
|
|
26
25
|
# (see Proxy#load)
|
27
26
|
def load(key, options = {})
|
28
|
-
write(
|
29
|
-
|
27
|
+
write(:load, key, options)
|
28
|
+
read
|
30
29
|
end
|
31
30
|
|
32
31
|
# (see Proxy#store)
|
33
32
|
def store(key, value, options = {})
|
34
|
-
write(
|
35
|
-
|
33
|
+
write(:store, key, value, options)
|
34
|
+
read
|
36
35
|
value
|
37
36
|
end
|
38
37
|
|
39
38
|
# (see Proxy#delete)
|
40
39
|
def delete(key, options = {})
|
41
|
-
write(
|
42
|
-
|
40
|
+
write(:delete, key, options)
|
41
|
+
read
|
43
42
|
end
|
44
43
|
|
45
44
|
# (see Proxy#increment)
|
46
45
|
def increment(key, amount = 1, options = {})
|
47
|
-
write(
|
48
|
-
|
46
|
+
write(:increment, key, amount, options)
|
47
|
+
read
|
49
48
|
end
|
50
49
|
|
51
50
|
# (see Proxy#create)
|
52
51
|
def create(key, value, options = {})
|
53
|
-
write(
|
54
|
-
|
52
|
+
write(:create, key, value, options)
|
53
|
+
read
|
55
54
|
end
|
56
55
|
|
57
56
|
# (see Proxy#clear)
|
58
57
|
def clear(options = {})
|
59
|
-
write(
|
60
|
-
|
58
|
+
write(:clear, options)
|
59
|
+
read
|
61
60
|
self
|
62
61
|
end
|
63
62
|
|
@@ -71,16 +70,22 @@ module Moneta
|
|
71
70
|
def features
|
72
71
|
@features ||=
|
73
72
|
begin
|
74
|
-
write(
|
75
|
-
|
73
|
+
write(:features)
|
74
|
+
read.freeze
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
79
78
|
private
|
80
79
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
80
|
+
def write(*args)
|
81
|
+
s = Marshal.dump(args)
|
82
|
+
@socket.write([s.bytesize].pack('N') << s)
|
83
|
+
end
|
84
|
+
|
85
|
+
def read
|
86
|
+
size = @socket.read(4).unpack('N').first
|
87
|
+
result = Marshal.load(@socket.read(size))
|
88
|
+
raise result if Exception === result
|
84
89
|
result
|
85
90
|
end
|
86
91
|
end
|
@@ -52,7 +52,7 @@ module Moneta
|
|
52
52
|
def increment(key, amount = 1, options = {})
|
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
56
|
result =
|
57
57
|
if amount >= 0
|
58
58
|
@backend.incr(key, amount, expires_value(options) || nil, nil)
|
@@ -64,7 +64,7 @@ module Moneta
|
|
64
64
|
@backend.decrement(key, -amount)
|
65
65
|
end
|
66
66
|
# HACK: Throw error if applied to invalid value
|
67
|
-
|
67
|
+
# see https://github.com/evan/memcached/issues/110
|
68
68
|
Utils.to_int((@backend.get(key, false) rescue nil)) if result == 0
|
69
69
|
result
|
70
70
|
rescue ::Memcached::NotFound => ex
|
data/lib/moneta/mixins.rb
CHANGED
@@ -284,27 +284,6 @@ module Moneta
|
|
284
284
|
end
|
285
285
|
end
|
286
286
|
|
287
|
-
# @api private
|
288
|
-
module Net
|
289
|
-
DEFAULT_PORT = 9000
|
290
|
-
|
291
|
-
class Error < RuntimeError; end
|
292
|
-
|
293
|
-
def pack(o)
|
294
|
-
s = Marshal.dump(o)
|
295
|
-
[s.bytesize].pack('N') << s
|
296
|
-
end
|
297
|
-
|
298
|
-
def read(io)
|
299
|
-
size = io.read(4).unpack('N').first
|
300
|
-
Marshal.load(io.read(size))
|
301
|
-
end
|
302
|
-
|
303
|
-
def write(io, o)
|
304
|
-
io.write(pack(o))
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
287
|
# This mixin handles the calculation of expiration times.
|
309
288
|
#
|
310
289
|
#
|
data/lib/moneta/pool.rb
CHANGED
@@ -27,7 +27,7 @@ module Moneta
|
|
27
27
|
|
28
28
|
def close
|
29
29
|
@mutex.synchronize do
|
30
|
-
raise '#close can only when no thread is using the pool' if @all.size != @pool.size
|
30
|
+
raise '#close can only be called when no thread is using the pool' if @all.size != @pool.size
|
31
31
|
@all.each(&:close)
|
32
32
|
@all = @pool = nil
|
33
33
|
end
|
data/lib/moneta/server.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'socket'
|
2
2
|
|
3
3
|
module Moneta
|
4
|
-
# Moneta server
|
4
|
+
# Moneta server to be used together with Moneta::Adapters::Client
|
5
5
|
# @api public
|
6
6
|
class Server
|
7
7
|
# @param [Hash] options
|
@@ -9,13 +9,9 @@ module Moneta
|
|
9
9
|
# @option options [String] :socket Alternative Unix socket file name
|
10
10
|
def initialize(store, options = {})
|
11
11
|
@store = store
|
12
|
-
@server =
|
13
|
-
|
14
|
-
|
15
|
-
else
|
16
|
-
TCPServer.open(options[:port] || DEFAULT_PORT)
|
17
|
-
end
|
18
|
-
@clients = [@server]
|
12
|
+
@server = start(options)
|
13
|
+
@ios = [@server]
|
14
|
+
@clients = {}
|
19
15
|
@running = false
|
20
16
|
end
|
21
17
|
|
@@ -52,54 +48,89 @@ module Moneta
|
|
52
48
|
|
53
49
|
private
|
54
50
|
|
55
|
-
include Net
|
56
51
|
TIMEOUT = 1
|
52
|
+
MAXSIZE = 0x100000
|
57
53
|
|
58
54
|
def mainloop
|
59
|
-
|
60
|
-
|
55
|
+
if ios = IO.select(@ios, nil, @ios, TIMEOUT)
|
56
|
+
ios[2].each do |io|
|
57
|
+
io.close
|
58
|
+
delete_client(io)
|
59
|
+
end
|
60
|
+
ios[0].each do |io|
|
61
|
+
if io == @server
|
62
|
+
if client = @server.accept
|
63
|
+
@ios << client
|
64
|
+
@clients[client] = ''
|
65
|
+
end
|
66
|
+
elsif io.closed? || io.eof?
|
67
|
+
delete_client(io)
|
68
|
+
else
|
69
|
+
handle(io, @clients[io] << io.readpartial(0xFFFF))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
61
73
|
rescue SignalException => ex
|
62
74
|
warn "Moneta::Server - #{ex.message}"
|
63
|
-
raise if ex.signo == 15 # SIGTERM
|
64
|
-
rescue IOError => ex
|
65
|
-
warn "Moneta::Server - #{ex.message}" unless ex.message =~ /closed/
|
66
|
-
@clients.delete(client) if client
|
67
|
-
@clients.reject!(&:closed?)
|
75
|
+
raise if ex.signo == 15 || ex.signo == 2 # SIGTERM or SIGINT
|
68
76
|
rescue Exception => ex
|
69
77
|
warn "Moneta::Server - #{ex.message}"
|
70
|
-
write(client, Error.new(ex.message)) if client
|
71
78
|
end
|
72
79
|
|
73
|
-
def
|
74
|
-
ios
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
if io == @server
|
82
|
-
client = @server.accept
|
83
|
-
@clients << client if client
|
84
|
-
else
|
85
|
-
return io unless io.eof?
|
86
|
-
@clients.delete(io)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
nil
|
80
|
+
def delete_client(io)
|
81
|
+
@ios.delete(io)
|
82
|
+
@clients.delete(io)
|
83
|
+
end
|
84
|
+
|
85
|
+
def pack(o)
|
86
|
+
s = Marshal.dump(o)
|
87
|
+
[s.bytesize].pack('N') << s
|
90
88
|
end
|
91
89
|
|
92
|
-
def handle(
|
93
|
-
|
90
|
+
def handle(io, buffer)
|
91
|
+
buffer = @clients[io]
|
92
|
+
return if buffer.bytesize < 8 # At least 4 bytes for the marshalled array
|
93
|
+
size = buffer[0,4].unpack('N').first
|
94
|
+
if size > MAXSIZE
|
95
|
+
delete_client(io)
|
96
|
+
return
|
97
|
+
end
|
98
|
+
return if buffer.bytesize < 4 + size
|
99
|
+
buffer.slice!(0, 4)
|
100
|
+
method, *args = Marshal.load(buffer.slice!(0, size))
|
94
101
|
case method
|
95
102
|
when :key?, :load, :delete, :increment, :create, :features
|
96
|
-
write(
|
103
|
+
io.write(pack @store.send(method, *args))
|
97
104
|
when :store, :clear
|
98
105
|
@store.send(method, *args)
|
99
|
-
|
106
|
+
io.write(@nil ||= pack(nil))
|
100
107
|
else
|
101
108
|
raise 'Invalid method call'
|
102
109
|
end
|
110
|
+
rescue IOError => ex
|
111
|
+
warn "Moneta::Server - #{ex.message}" unless ex.message =~ /closed/
|
112
|
+
delete_client(io)
|
113
|
+
rescue Exception => ex
|
114
|
+
warn "Moneta::Server - #{ex.message}"
|
115
|
+
io.write(pack Exception.new(ex.message))
|
116
|
+
end
|
117
|
+
|
118
|
+
def start(options)
|
119
|
+
if @socket = options[:socket]
|
120
|
+
begin
|
121
|
+
UNIXServer.open(@socket)
|
122
|
+
rescue Errno::EADDRINUSE
|
123
|
+
if client = (UNIXSocket.open(@socket) rescue nil)
|
124
|
+
client.close
|
125
|
+
raise
|
126
|
+
end
|
127
|
+
File.unlink(@socket)
|
128
|
+
tries ||= 0
|
129
|
+
(tries += 1) < 3 ? retry : raise
|
130
|
+
end
|
131
|
+
else
|
132
|
+
TCPServer.open(options[:host] || '127.0.0.1', options[:port] || 9000)
|
133
|
+
end
|
103
134
|
end
|
104
135
|
end
|
105
136
|
end
|