binary42-remix-stash 0.9.2 → 0.9.3

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 CHANGED
@@ -1 +1 @@
1
- 0.9.2
1
+ 0.9.3
@@ -1,20 +1,29 @@
1
1
  require 'benchmark'
2
2
  require File.dirname(__FILE__) + '/../harness'
3
- require File.dirname(__FILE__) + '/../harness_cache'
4
3
 
5
- LARGE_NUMBER = 200_000
4
+ LARGE_NUMBER = 20_000
6
5
 
7
6
  Benchmark.bmbm do |b|
8
- b.report('get/set stash') do
7
+ b.report('get/set remix-stash') do
9
8
  LARGE_NUMBER.times {|n|
10
9
  stash[:abcxyz123] = n
11
10
  stash[:abcxyz123]
12
11
  }
13
12
  end
14
- b.report('get/set cache') do
15
- LARGE_NUMBER.times {|n|
16
- Cache.set('abcxyz123', n)
17
- Cache.get('abcxyz123')
18
- }
13
+ if defined?(CCache)
14
+ b.report('get/set memcached') do
15
+ LARGE_NUMBER.times {|n|
16
+ CCache.set('abcxyz123', n)
17
+ CCache.get('abcxyz123')
18
+ }
19
+ end
20
+ end
21
+ if defined?(RCache)
22
+ b.report('get/set memcache-client') do
23
+ LARGE_NUMBER.times {|n|
24
+ RCache.set('abcxyz123', n)
25
+ RCache.get('abcxyz123')
26
+ }
27
+ end
19
28
  end
20
29
  end
@@ -1,40 +1,82 @@
1
1
  require 'benchmark'
2
2
  require File.dirname(__FILE__) + '/../harness'
3
- require File.dirname(__FILE__) + '/../harness_cache'
4
3
 
5
4
  LARGE_NUMBER = 20_000
6
5
 
7
- large_value = 'a' * 100_000
8
- med_value = 'b' * 2_000
9
- small_value = 'c' * 100
10
- tiny_value = 'd'
6
+ huge_value = 'a' * 100_000
7
+ large_value = 'b' * 20_000
8
+ med_value = 'c' * 2_000
9
+ small_value = 'd' * 100
10
+ tiny_value = 'e'
11
11
 
12
12
  KEY = 'abc123xyz'
13
13
 
14
14
  Benchmark.bmbm do |b|
15
- b.report('100k stash') do
15
+ b.report('100k remix-stash') do
16
16
  LARGE_NUMBER.times {
17
- stash.write(KEY, large_value)
17
+ stash.write(KEY, huge_value)
18
18
  stash.read(KEY)
19
19
  }
20
20
  end
21
- b.report('100k cache') do
21
+ if defined?(CCache)
22
+ b.report('100k memcached') do
23
+ LARGE_NUMBER.times {
24
+ CCache.set(KEY, huge_value, 0, true)
25
+ CCache.get(KEY, true)
26
+ }
27
+ end
28
+ end
29
+ if defined?(RCache)
30
+ b.report('100k memcache-client') do
31
+ LARGE_NUMBER.times {
32
+ RCache.set(KEY, huge_value, 0, true)
33
+ RCache.get(KEY, true)
34
+ }
35
+ end
36
+ end
37
+ b.report('20k remix-stash') do
22
38
  LARGE_NUMBER.times {
23
- Cache.set(KEY, large_value, 0, true)
24
- Cache.get(KEY, true)
39
+ stash.write(KEY, large_value)
40
+ stash.read(KEY)
25
41
  }
26
42
  end
43
+ if defined?(CCache)
44
+ b.report('20k memcached') do
45
+ LARGE_NUMBER.times {
46
+ CCache.set(KEY, large_value, 0, true)
47
+ CCache.get(KEY, true)
48
+ }
49
+ end
50
+ end
51
+ if defined?(RCache)
52
+ b.report('20k memcache-client') do
53
+ LARGE_NUMBER.times {
54
+ RCache.set(KEY, large_value, 0, true)
55
+ RCache.get(KEY, true)
56
+ }
57
+ end
58
+ end
27
59
  b.report('2k stash') do
28
60
  LARGE_NUMBER.times {
29
61
  stash.write(KEY, med_value)
30
62
  stash.read(KEY)
31
63
  }
32
64
  end
33
- b.report('2k cache') do
34
- LARGE_NUMBER.times {
35
- Cache.set(KEY, med_value, 0, true)
36
- Cache.get(KEY, true)
37
- }
65
+ if defined?(CCache)
66
+ b.report('2k memcached') do
67
+ LARGE_NUMBER.times {
68
+ CCache.set(KEY, med_value, 0, true)
69
+ CCache.get(KEY, true)
70
+ }
71
+ end
72
+ end
73
+ if defined?(RCache)
74
+ b.report('2k memcache-client') do
75
+ LARGE_NUMBER.times {
76
+ RCache.set(KEY, med_value, 0, true)
77
+ RCache.get(KEY, true)
78
+ }
79
+ end
38
80
  end
39
81
  b.report('100b stash') do
40
82
  LARGE_NUMBER.times {
@@ -42,11 +84,21 @@ Benchmark.bmbm do |b|
42
84
  stash.read(KEY)
43
85
  }
44
86
  end
45
- b.report('100b cache') do
46
- LARGE_NUMBER.times {
47
- Cache.set(KEY, small_value, 0, true)
48
- Cache.get(KEY, true)
49
- }
87
+ if defined?(CCache)
88
+ b.report('100b memcached') do
89
+ LARGE_NUMBER.times {
90
+ CCache.set(KEY, small_value, 0, true)
91
+ CCache.get(KEY, true)
92
+ }
93
+ end
94
+ end
95
+ if defined?(RCache)
96
+ b.report('100b memcache-client') do
97
+ LARGE_NUMBER.times {
98
+ RCache.set(KEY, small_value, 0, true)
99
+ RCache.get(KEY, true)
100
+ }
101
+ end
50
102
  end
51
103
  b.report('1b stash') do
52
104
  LARGE_NUMBER.times {
@@ -54,10 +106,20 @@ Benchmark.bmbm do |b|
54
106
  stash.read(KEY)
55
107
  }
56
108
  end
57
- b.report('1b cache') do
58
- LARGE_NUMBER.times {
59
- Cache.set(KEY, tiny_value, 0, true)
60
- Cache.get(KEY, true)
61
- }
109
+ if defined?(CCache)
110
+ b.report('1b memcached') do
111
+ LARGE_NUMBER.times {
112
+ CCache.set(KEY, tiny_value, 0, true)
113
+ CCache.get(KEY, true)
114
+ }
115
+ end
116
+ end
117
+ if defined?(RCache)
118
+ b.report('1b memcache-client') do
119
+ LARGE_NUMBER.times {
120
+ RCache.set(KEY, tiny_value, 0, true)
121
+ RCache.get(KEY, true)
122
+ }
123
+ end
62
124
  end
63
125
  end
data/examples/eval.rb CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../harness'
2
2
 
3
3
  stuff = stash(:stuff)
4
4
 
5
- stuff.eval(:answer) {42}
6
- p stuff.get(:answer)
5
+ stuff.eval(:ans) {42}
6
+ p stuff.get(:ans)
7
7
 
8
- stuff.eval(:asnwer) {fail 'Cache miss'}
8
+ stuff.eval(:ans) {fail 'Cache miss'}
data/harness.rb CHANGED
@@ -1,4 +1,19 @@
1
- $LOAD_PATH << File.dirname(__FILE__) + '/lib'
1
+ require 'rubygems'
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
2
3
  require 'remix/stash'
3
4
 
5
+ begin
6
+ require 'memcached'
7
+ CCache = Memcached.new('localhost:11211')
8
+ rescue
9
+ puts "memcached not found (skipping)"
10
+ end
11
+
12
+ begin
13
+ require 'memcache'
14
+ RCache = MemCache.new('localhost:11211')
15
+ rescue
16
+ puts "memcached-client not found (skipping)"
17
+ end
18
+
4
19
  stash.clear
@@ -1,7 +1,7 @@
1
1
  require 'socket'
2
2
  require 'digest/md5'
3
3
 
4
- class Stash::Cluster
4
+ class Remix::Stash::Cluster
5
5
  include Socket::Constants
6
6
 
7
7
  @@connections = {}
@@ -17,7 +17,15 @@ class Stash::Cluster
17
17
 
18
18
  def each
19
19
  @hosts.each do |h|
20
- yield(host_to_io(*h))
20
+ begin
21
+ io = host_to_io(*h)
22
+ break yield(io)
23
+ rescue Errno::EPIPE, Errno::ECONNRESET
24
+ io.close
25
+ retry
26
+ rescue Stash::ProtocolError, Errno::EAGAIN
27
+ next
28
+ end
21
29
  end
22
30
  end
23
31
 
@@ -34,8 +42,12 @@ class Stash::Cluster
34
42
  end
35
43
  count.times do |try|
36
44
  begin
37
- break yield(host_to_io(*@hosts[(hash + try) % count]))
38
- rescue Stash::ProtocolError
45
+ io = host_to_io(*@hosts[(hash + try) % count])
46
+ break yield(io)
47
+ rescue Errno::EPIPE, Errno::ECONNRESET
48
+ io.close
49
+ retry
50
+ rescue Stash::ProtocolError, Errno::EAGAIN
39
51
  next
40
52
  end
41
53
  raise Stash::ClusterError,
@@ -68,7 +80,10 @@ private
68
80
  end
69
81
 
70
82
  def host_to_io(key, host, port)
71
- @@connections[key] ||= connect(host, port)
83
+ socket = @@connections[key] ||= connect(host, port)
84
+ return socket unless socket.closed?
85
+ @@connections.delete(key)
86
+ host_to_io(key, host, port)
72
87
  end
73
88
 
74
89
  end
@@ -1,8 +1,7 @@
1
- module Stash::Extension
2
- extend self
1
+ module Remix::Stash::Extension
3
2
 
4
3
  def stash(name = :root)
5
- Stash.new(name)
4
+ Remix::Stash.new(name)
6
5
  end
7
6
 
8
7
  end
@@ -1,4 +1,4 @@
1
- module Stash::Protocol
1
+ module Remix::Stash::Protocol
2
2
  extend self
3
3
 
4
4
  HEADER_FORMAT = "CCnCCnNNQ"
@@ -93,10 +93,6 @@ module Stash::Protocol
93
93
  resp[:status] == NO_ERROR ? parse_get(resp[:body])[:value] : nil
94
94
  end
95
95
 
96
- def get_value(io, key)
97
- load_ruby_value(get(io, key))
98
- end
99
-
100
96
  INCR_PACKET = HEADER_FORMAT + 'NNQNa*'
101
97
  def incr(io, key, step)
102
98
  low, high = split64(step)
@@ -116,18 +112,8 @@ module Stash::Protocol
116
112
  resp[:status] == NO_ERROR
117
113
  end
118
114
 
119
- def set_value(io, key, value, ttl = 0)
120
- set(io, key, Marshal.dump(value), ttl)
121
- end
122
-
123
115
  private
124
116
 
125
- def load_ruby_value(data)
126
- return unless data
127
- # TODO: Catch errors and try to fix them
128
- Marshal.load(data)
129
- end
130
-
131
117
  def parse_get(body)
132
118
  extra, value = body.unpack('Na*')
133
119
  {:extra => extra, :value => value}
data/lib/remix/stash.rb CHANGED
@@ -1,4 +1,6 @@
1
- class Stash
1
+ module Remix; end
2
+
3
+ class Remix::Stash
2
4
  require 'remix/stash/extension'
3
5
  require 'remix/stash/cluster'
4
6
  require 'remix/stash/protocol'
@@ -96,12 +98,14 @@ class Stash
96
98
  opts = default_opts(keys)
97
99
  key = canonical_key(keys)
98
100
  cluster.select(key) {|io|
99
- value = Protocol.get_value(io, key)
100
- unless value
101
+ value = Protocol.get(io, key)
102
+ if value
103
+ Marshal.load(value)
104
+ else
101
105
  value = yield(*keys)
102
- Protocol.set_value(io, key, value, opts[:ttl])
106
+ Protocol.set(io, key, dump_value(value), opts[:ttl])
107
+ value
103
108
  end
104
- value
105
109
  }
106
110
  end
107
111
 
@@ -119,7 +123,7 @@ class Stash
119
123
 
120
124
  def get(*keys)
121
125
  key = canonical_key(keys)
122
- cluster.select(key) {|io| Protocol.get_value(io, key)}
126
+ cluster.select(key) {|io| load_value(Protocol.get(io, key))}
123
127
  end
124
128
  alias [] get
125
129
 
@@ -147,7 +151,7 @@ class Stash
147
151
  opts = default_opts(keys)
148
152
  value = keys.pop
149
153
  key = canonical_key(keys)
150
- cluster.select(key) {|io| Protocol.set_value(io, key, value, opts[:ttl])}
154
+ cluster.select(key) {|io| Protocol.set(io, key, dump_value(value), opts[:ttl])}
151
155
  end
152
156
  alias []= set
153
157
 
@@ -179,10 +183,14 @@ private
179
183
  default[:coherency]
180
184
  end
181
185
 
182
- def default_opts(params)
186
+ def default_opts(params = {})
183
187
  params.last.is_a?(Hash) ? default.merge(params.pop) : default
184
188
  end
185
189
 
190
+ def dump_value(value)
191
+ Marshal.dump(value)
192
+ end
193
+
186
194
  EMPTY_SCOPE = ''
187
195
  def implicit_scope
188
196
  if @scope
@@ -193,9 +201,17 @@ private
193
201
  end
194
202
  end
195
203
 
204
+ def load_value(data)
205
+ Marshal.load(data) if data
206
+ rescue TypeError, ArgumentError
207
+ logger = default_opts[:logger]
208
+ logger && logger.error("[stash] Unable to load marshal stream: #{data.inspect}")
209
+ nil
210
+ end
211
+
196
212
  def vector
197
- return 'static' if @name == :root
198
- return @vector.to_s if @vector && coherency != :dynamic
213
+ return if @name == :root
214
+ return @vector if @vector && coherency != :dynamic
199
215
  vk = vector_key
200
216
  cluster.select(vk) do |io|
201
217
  @vector = Protocol.get(io, vk)
@@ -216,4 +232,5 @@ private
216
232
 
217
233
  end
218
234
 
219
- class Object; include Stash::Extension end
235
+ class Object; include Remix::Stash::Extension end
236
+ module Remix; extend Remix::Stash::Extension end
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.2"
8
+ s.version = "0.9.3"
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-09}
12
+ s.date = %q{2009-09-16}
13
13
  s.email = %q{binary42@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
@@ -26,11 +26,9 @@ Gem::Specification.new do |s|
26
26
  "examples/eval.rb",
27
27
  "examples/gate.rb",
28
28
  "examples/getset.rb",
29
- "examples/getset_cache.rb",
30
29
  "examples/scope.rb",
31
30
  "examples/stash.rb",
32
31
  "harness.rb",
33
- "harness_cache.rb",
34
32
  "lib/remix/stash.rb",
35
33
  "lib/remix/stash/cluster.rb",
36
34
  "lib/remix/stash/extension.rb",
@@ -53,7 +51,6 @@ Gem::Specification.new do |s|
53
51
  "examples/eval.rb",
54
52
  "examples/gate.rb",
55
53
  "examples/getset.rb",
56
- "examples/getset_cache.rb",
57
54
  "examples/scope.rb",
58
55
  "examples/stash.rb"
59
56
  ]
@@ -22,4 +22,16 @@ class ExtensionSpec < Spec
22
22
 
23
23
  end
24
24
 
25
+ context 'modules' do
26
+
27
+ should 'be mixed into Object' do
28
+ assert Object.respond_to?(:stash)
29
+ end
30
+
31
+ should 'be mixed into Remix' do
32
+ assert Remix.respond_to?(:stash)
33
+ end
34
+
35
+ end
36
+
25
37
  end
data/spec/spec.rb CHANGED
@@ -6,3 +6,5 @@ $LOAD_PATH << File.dirname(__FILE__) + '/../lib'
6
6
  require 'remix/stash'
7
7
 
8
8
  Spec = Test::Unit::TestCase
9
+
10
+ include Remix
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.2
4
+ version: 0.9.3
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-09 00:00:00 -07:00
12
+ date: 2009-09-16 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -33,11 +33,9 @@ files:
33
33
  - examples/eval.rb
34
34
  - examples/gate.rb
35
35
  - examples/getset.rb
36
- - examples/getset_cache.rb
37
36
  - examples/scope.rb
38
37
  - examples/stash.rb
39
38
  - harness.rb
40
- - harness_cache.rb
41
39
  - lib/remix/stash.rb
42
40
  - lib/remix/stash/cluster.rb
43
41
  - lib/remix/stash/extension.rb
@@ -48,6 +46,7 @@ files:
48
46
  - spec/stash_spec.rb
49
47
  has_rdoc: true
50
48
  homepage: http://github.com/binary42/remix-stash
49
+ licenses:
51
50
  post_install_message:
52
51
  rdoc_options:
53
52
  - --charset=UTF-8
@@ -68,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
67
  requirements: []
69
68
 
70
69
  rubyforge_project:
71
- rubygems_version: 1.2.0
70
+ rubygems_version: 1.3.5
72
71
  signing_key:
73
72
  specification_version: 2
74
73
  summary: Remix your memcache
@@ -79,6 +78,5 @@ test_files:
79
78
  - examples/eval.rb
80
79
  - examples/gate.rb
81
80
  - examples/getset.rb
82
- - examples/getset_cache.rb
83
81
  - examples/scope.rb
84
82
  - examples/stash.rb
@@ -1,5 +0,0 @@
1
- require File.dirname(__FILE__) + '/../harness_cache'
2
-
3
- # Simple get and set
4
- Cache.set('answer', 42)
5
- p Cache.get('answer')
data/harness_cache.rb DELETED
@@ -1,5 +0,0 @@
1
- require 'rubygems'
2
- require 'memcache'
3
-
4
- Cache = MemCache.new(%[localhost:11211])
5
- Cache.flush_all