binary42-remix-stash 0.9.4 → 0.9.5
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/VERSION +1 -1
- data/benchmarks/get_set.rb +9 -3
- data/benchmarks/payload.rb +10 -10
- data/lib/remix/stash/cluster.rb +13 -27
- data/lib/remix/stash/protocol.rb +12 -15
- data/lib/remix/stash.rb +23 -22
- data/remix-stash.gemspec +2 -2
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.5
|
data/benchmarks/get_set.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'benchmark'
|
2
2
|
require File.dirname(__FILE__) + '/../harness'
|
3
3
|
|
4
|
-
LARGE_NUMBER =
|
4
|
+
LARGE_NUMBER = 50_000
|
5
5
|
|
6
6
|
Benchmark.bmbm do |b|
|
7
7
|
b.report('get/set remix-stash') do
|
@@ -10,11 +10,17 @@ Benchmark.bmbm do |b|
|
|
10
10
|
stash[:abcxyz123]
|
11
11
|
}
|
12
12
|
end
|
13
|
+
b.report('get/set remix-stash named') do
|
14
|
+
LARGE_NUMBER.times {|n|
|
15
|
+
stash(:stuff)[:abcxyz123] = n
|
16
|
+
stash(:stuff)[:abcxyz123]
|
17
|
+
}
|
18
|
+
end
|
13
19
|
if defined?(CCache)
|
14
20
|
b.report('get/set memcached') do
|
15
21
|
LARGE_NUMBER.times {|n|
|
16
|
-
CCache.set('abcxyz123', n)
|
17
|
-
CCache.get('abcxyz123')
|
22
|
+
CCache.set('abcxyz123', n, 0 , true)
|
23
|
+
CCache.get('abcxyz123', true)
|
18
24
|
}
|
19
25
|
end
|
20
26
|
end
|
data/benchmarks/payload.rb
CHANGED
@@ -21,8 +21,8 @@ Benchmark.bmbm do |b|
|
|
21
21
|
if defined?(CCache)
|
22
22
|
b.report('100k memcached') do
|
23
23
|
LARGE_NUMBER.times {
|
24
|
-
CCache.set(KEY, huge_value, 0,
|
25
|
-
CCache.get(KEY,
|
24
|
+
CCache.set(KEY, huge_value, 0, false)
|
25
|
+
CCache.get(KEY, false)
|
26
26
|
}
|
27
27
|
end
|
28
28
|
end
|
@@ -43,8 +43,8 @@ Benchmark.bmbm do |b|
|
|
43
43
|
if defined?(CCache)
|
44
44
|
b.report('20k memcached') do
|
45
45
|
LARGE_NUMBER.times {
|
46
|
-
CCache.set(KEY, large_value, 0,
|
47
|
-
CCache.get(KEY,
|
46
|
+
CCache.set(KEY, large_value, 0, false)
|
47
|
+
CCache.get(KEY, false)
|
48
48
|
}
|
49
49
|
end
|
50
50
|
end
|
@@ -65,8 +65,8 @@ Benchmark.bmbm do |b|
|
|
65
65
|
if defined?(CCache)
|
66
66
|
b.report('2k memcached') do
|
67
67
|
LARGE_NUMBER.times {
|
68
|
-
CCache.set(KEY, med_value, 0,
|
69
|
-
CCache.get(KEY,
|
68
|
+
CCache.set(KEY, med_value, 0, false)
|
69
|
+
CCache.get(KEY, false)
|
70
70
|
}
|
71
71
|
end
|
72
72
|
end
|
@@ -87,8 +87,8 @@ Benchmark.bmbm do |b|
|
|
87
87
|
if defined?(CCache)
|
88
88
|
b.report('100b memcached') do
|
89
89
|
LARGE_NUMBER.times {
|
90
|
-
CCache.set(KEY, small_value, 0,
|
91
|
-
CCache.get(KEY,
|
90
|
+
CCache.set(KEY, small_value, 0, false)
|
91
|
+
CCache.get(KEY, false)
|
92
92
|
}
|
93
93
|
end
|
94
94
|
end
|
@@ -109,8 +109,8 @@ Benchmark.bmbm do |b|
|
|
109
109
|
if defined?(CCache)
|
110
110
|
b.report('1b memcached') do
|
111
111
|
LARGE_NUMBER.times {
|
112
|
-
CCache.set(KEY, tiny_value, 0,
|
113
|
-
CCache.get(KEY,
|
112
|
+
CCache.set(KEY, tiny_value, 0, false)
|
113
|
+
CCache.get(KEY, false)
|
114
114
|
}
|
115
115
|
end
|
116
116
|
end
|
data/lib/remix/stash/cluster.rb
CHANGED
@@ -20,10 +20,10 @@ class Remix::Stash::Cluster
|
|
20
20
|
begin
|
21
21
|
io = host_to_io(*h)
|
22
22
|
break yield(io)
|
23
|
-
rescue Errno::EPIPE, Errno::ECONNRESET
|
23
|
+
rescue Errno::EPIPE, Errno::ECONNRESET, Remix::Stash::ProtocolError
|
24
24
|
io.close
|
25
25
|
retry
|
26
|
-
rescue
|
26
|
+
rescue Errno::EAGAIN, Errno::ECONNREFUSED
|
27
27
|
next
|
28
28
|
end
|
29
29
|
end
|
@@ -43,38 +43,24 @@ class Remix::Stash::Cluster
|
|
43
43
|
count.times do |try|
|
44
44
|
begin
|
45
45
|
io = host_to_io(*@hosts[(hash + try) % count])
|
46
|
-
|
47
|
-
rescue Errno::EPIPE, Errno::ECONNRESET
|
46
|
+
return yield(io)
|
47
|
+
rescue Errno::EPIPE, Errno::ECONNRESET, Remix::Stash::ProtocolError
|
48
48
|
io.close
|
49
49
|
retry
|
50
|
-
rescue
|
50
|
+
rescue Errno::EAGAIN, Errno::ECONNREFUSED
|
51
51
|
next
|
52
52
|
end
|
53
|
-
raise Remix::Stash::ClusterError,
|
54
|
-
"Unable to find suitable host to communicate with for #{key.inspect} (MD5-32=#{hash})"
|
55
53
|
end
|
54
|
+
raise Remix::Stash::ClusterError,
|
55
|
+
"Unable to find suitable host to communicate with for #{key.inspect} (MD5-32=#{hash})"
|
56
56
|
end
|
57
57
|
|
58
58
|
private
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
set_timeout(socket)
|
65
|
-
socket
|
66
|
-
end
|
67
|
-
|
68
|
-
else
|
69
|
-
|
70
|
-
def connect(host, port)
|
71
|
-
address = Socket.getaddrinfo(host, nil).first
|
72
|
-
socket = Socket.new(Socket.const_get(address[0]), SOCK_STREAM, 0)
|
73
|
-
set_timeout(socket)
|
74
|
-
socket.connect(Socket.pack_sockaddr_in(port, address[3]))
|
75
|
-
socket
|
76
|
-
end
|
77
|
-
|
60
|
+
def connect(host, port)
|
61
|
+
socket = TCPSocket.new(host, port)
|
62
|
+
set_timeout(socket, 2)
|
63
|
+
socket
|
78
64
|
end
|
79
65
|
|
80
66
|
def host_to_io(key, host, port)
|
@@ -84,8 +70,8 @@ private
|
|
84
70
|
host_to_io(key, host, port)
|
85
71
|
end
|
86
72
|
|
87
|
-
def set_timeout(socket)
|
88
|
-
timeout = [
|
73
|
+
def set_timeout(socket, seconds)
|
74
|
+
timeout = [seconds, 0].pack('l_2') # 2 seconds
|
89
75
|
socket.setsockopt(SOL_SOCKET, SO_SNDTIMEO, timeout)
|
90
76
|
socket.setsockopt(SOL_SOCKET, SO_RCVTIMEO, timeout)
|
91
77
|
end
|
data/lib/remix/stash/protocol.rb
CHANGED
@@ -86,11 +86,12 @@ module Remix::Stash::Protocol
|
|
86
86
|
end
|
87
87
|
|
88
88
|
GET_PACKET = HEADER_FORMAT + 'a*'
|
89
|
+
GET_BODY = 4..-1
|
89
90
|
def get(io, key)
|
90
91
|
header = [REQUEST, GET, key.size, 0, 0, 0, key.size, 0, 0, key].pack(GET_PACKET)
|
91
92
|
io.write(header)
|
92
93
|
resp = read_resp(io)
|
93
|
-
resp[:status] == NO_ERROR ?
|
94
|
+
resp[:status] == NO_ERROR ? resp[:body][GET_BODY] : nil
|
94
95
|
end
|
95
96
|
|
96
97
|
INCR_PACKET = HEADER_FORMAT + 'NNQNa*'
|
@@ -114,25 +115,21 @@ module Remix::Stash::Protocol
|
|
114
115
|
|
115
116
|
private
|
116
117
|
|
117
|
-
|
118
|
-
extra, value = body.unpack('Na*')
|
119
|
-
{:extra => extra, :value => value}
|
120
|
-
end
|
121
|
-
|
118
|
+
COUNTER_SPLIT = 'NN'
|
122
119
|
def parse_counter(body)
|
123
|
-
a, b = body.unpack(
|
120
|
+
a, b = body.unpack(COUNTER_SPLIT)
|
124
121
|
b | (a << 32)
|
125
122
|
end
|
126
123
|
|
124
|
+
RESP_HEADER = '@6nN'
|
127
125
|
def read_resp(io)
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
:
|
134
|
-
|
135
|
-
resp
|
126
|
+
header = io.read(24)
|
127
|
+
header or raise Remix::Stash::ProtocolError,
|
128
|
+
"No data in response header"
|
129
|
+
status, body_length = *header.unpack(RESP_HEADER)
|
130
|
+
body_length.zero? ?
|
131
|
+
{:status => status} :
|
132
|
+
{:status => status, :body => io.read(body_length)}
|
136
133
|
end
|
137
134
|
|
138
135
|
def split64(n)
|
data/lib/remix/stash.rb
CHANGED
@@ -32,7 +32,7 @@ class Remix::Stash
|
|
32
32
|
def initialize(name)
|
33
33
|
@name = name
|
34
34
|
@scope = nil
|
35
|
-
@opts = name == :root ? {:coherency => :action, :ttl => 0} : {}
|
35
|
+
@opts = name == :root ? {:coherency => :action, :ttl => 0, :cluster => :default} : {}
|
36
36
|
end
|
37
37
|
|
38
38
|
def add(*keys)
|
@@ -79,11 +79,15 @@ class Remix::Stash
|
|
79
79
|
cluster(opts).select(key) {|io| Protocol.decr(io, key, step)}
|
80
80
|
end
|
81
81
|
|
82
|
-
def default(opts =
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
82
|
+
def default(opts = nil)
|
83
|
+
if opts
|
84
|
+
base = @opts.merge!(opts)
|
85
|
+
if opts.has_key? :coherency
|
86
|
+
[:dynamic, :action, :transaction].include?(opts[:coherency]) or raise ArgumentError,
|
87
|
+
"Invalid coherency setting used (#{opts[:coherency].inspect})"
|
88
|
+
end
|
89
|
+
else
|
90
|
+
base = @opts
|
87
91
|
end
|
88
92
|
root = @@instances[:root] || Stash.new(:root)
|
89
93
|
self == root ?
|
@@ -178,19 +182,22 @@ class Remix::Stash
|
|
178
182
|
private
|
179
183
|
|
180
184
|
KEY_SEPARATOR = '/'
|
181
|
-
def canonical_key(keys, opts
|
182
|
-
|
185
|
+
def canonical_key(keys, opts)
|
186
|
+
v = vector(opts)
|
187
|
+
if @scope
|
188
|
+
"#{implicit_scope}#{keys.join(KEY_SEPARATOR)}#{vector(opts)}"
|
189
|
+
elsif v
|
190
|
+
keys.join(KEY_SEPARATOR) << v
|
191
|
+
else
|
192
|
+
keys.join(KEY_SEPARATOR)
|
193
|
+
end
|
183
194
|
end
|
184
195
|
|
185
196
|
def cluster(opts = {})
|
186
|
-
@@clusters[opts[:cluster]
|
197
|
+
@@clusters[opts[:cluster]]
|
187
198
|
end
|
188
199
|
|
189
|
-
def
|
190
|
-
default[:coherency]
|
191
|
-
end
|
192
|
-
|
193
|
-
def default_opts(params = {})
|
200
|
+
def default_opts(params)
|
194
201
|
params.last.is_a?(Hash) ? default.merge(params.pop) : default
|
195
202
|
end
|
196
203
|
|
@@ -198,14 +205,8 @@ private
|
|
198
205
|
Marshal.dump(value)
|
199
206
|
end
|
200
207
|
|
201
|
-
EMPTY_SCOPE = ''
|
202
208
|
def implicit_scope
|
203
|
-
if @scope
|
204
|
-
scope = @scope.call(self)
|
205
|
-
scope ? "#{scope}/" : EMPTY_SCOPE
|
206
|
-
else
|
207
|
-
EMPTY_SCOPE
|
208
|
-
end
|
209
|
+
@scope.call(self) if @scope
|
209
210
|
end
|
210
211
|
|
211
212
|
def load_value(data)
|
@@ -218,7 +219,7 @@ private
|
|
218
219
|
|
219
220
|
def vector(opts)
|
220
221
|
return if @name == :root
|
221
|
-
return @vector if @vector && coherency != :dynamic
|
222
|
+
return @vector if @vector && opts[:coherency] != :dynamic
|
222
223
|
vk = vector_key
|
223
224
|
cluster(opts).select(vk) do |io|
|
224
225
|
@vector = Protocol.get(io, vk)
|
data/remix-stash.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{remix-stash}
|
8
|
-
s.version = "0.9.
|
8
|
+
s.version = "0.9.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Mitchell"]
|
12
|
-
s.date = %q{2009-09-
|
12
|
+
s.date = %q{2009-09-21}
|
13
13
|
s.email = %q{binary42@gmail.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: binary42-remix-stash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Mitchell
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-21 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|