dalli 2.6.0 → 2.6.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dalli might be problematic. Click here for more details.
- data/Gemfile +1 -0
- data/History.md +13 -0
- data/README.md +25 -12
- data/lib/dalli/client.rb +7 -4
- data/lib/dalli/ring.rb +53 -18
- data/lib/dalli/server.rb +13 -7
- data/lib/dalli/version.rb +1 -1
- data/test/test_active_support.rb +1 -1
- metadata +2 -2
data/Gemfile
CHANGED
data/History.md
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
Dalli Changelog
|
2
2
|
=====================
|
3
3
|
|
4
|
+
2.6.1
|
5
|
+
=======
|
6
|
+
|
7
|
+
- Add optional native C binary search for ring, add:
|
8
|
+
|
9
|
+
gem 'RubyInline'
|
10
|
+
|
11
|
+
to your Gemfile to get a 10% speedup when using many servers.
|
12
|
+
You will see no improvement if you are only using one server.
|
13
|
+
|
14
|
+
- More get_multi performance optimization [xaop, #315]
|
15
|
+
- Add lambda support for cache namespaces [joshwlewis, #311]
|
16
|
+
|
4
17
|
2.6.0
|
5
18
|
=======
|
6
19
|
|
data/README.md
CHANGED
@@ -55,12 +55,14 @@ On Ubuntu you can install it by running:
|
|
55
55
|
|
56
56
|
You can verify your installation using this piece of code:
|
57
57
|
|
58
|
-
|
58
|
+
```ruby
|
59
|
+
gem install dalli
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
require 'dalli'
|
62
|
+
dc = Dalli::Client.new('localhost:11211')
|
63
|
+
dc.set('abc', 123)
|
64
|
+
value = dc.get('abc')
|
65
|
+
```
|
64
66
|
|
65
67
|
The test suite requires memcached 1.4.3+ with SASL enabled (brew install memcached --enable-sasl ; mv /usr/bin/memcached /usr/bin/memcached.old). Currently only supports the PLAIN mechanism.
|
66
68
|
|
@@ -73,27 +75,37 @@ Usage with Rails 3.x
|
|
73
75
|
|
74
76
|
In your Gemfile:
|
75
77
|
|
76
|
-
|
78
|
+
```ruby
|
79
|
+
gem 'dalli'
|
80
|
+
```
|
77
81
|
|
78
82
|
In `config/environments/production.rb`:
|
79
83
|
|
80
|
-
|
84
|
+
```ruby
|
85
|
+
config.cache_store = :dalli_store
|
86
|
+
```
|
81
87
|
|
82
88
|
Here's a more comprehensive example that sets a reasonable default for maximum cache entry lifetime (one day), enables compression for large values and namespaces all entries for this rails app. Remove the namespace if you have multiple apps which share cached values.
|
83
89
|
|
84
|
-
|
85
|
-
|
90
|
+
```ruby
|
91
|
+
config.cache_store = :dalli_store, 'cache-1.example.com', 'cache-2.example.com',
|
92
|
+
{ :namespace => NAME_OF_RAILS_APP, :expires_in => 1.day, :compress => true }
|
93
|
+
```
|
86
94
|
|
87
95
|
To use Dalli for Rails session storage that times out after 20 minutes, in `config/initializers/session_store.rb`:
|
88
96
|
|
89
97
|
For Rails >= 3.2.4:
|
90
98
|
|
91
|
-
|
99
|
+
```ruby
|
100
|
+
Rails.application.config.session_store ActionDispatch::Session::CacheStore, :expire_after => 20.minutes
|
101
|
+
```
|
92
102
|
|
93
103
|
For Rails 3.x:
|
94
104
|
|
95
|
-
|
96
|
-
|
105
|
+
```ruby
|
106
|
+
require 'action_dispatch/middleware/session/dalli_store'
|
107
|
+
Rails.application.config.session_store :dalli_store, :memcache_server => ['host1', 'host2'], :namespace => 'sessions', :key => '_foundation_session', :expire_after => 20.minutes
|
108
|
+
```
|
97
109
|
|
98
110
|
Dalli does not support Rails 2.x.
|
99
111
|
|
@@ -146,6 +158,7 @@ socket.
|
|
146
158
|
|
147
159
|
Note that Dalli does not require ActiveSupport or Rails. You can safely use it in your own Ruby projects.
|
148
160
|
|
161
|
+
![View the API](http://www.ruby-doc.org/gems/docs/d/dalli-2.5.0/Dalli/Client.html)
|
149
162
|
|
150
163
|
Helping Out
|
151
164
|
-------------
|
data/lib/dalli/client.rb
CHANGED
@@ -340,19 +340,22 @@ module Dalli
|
|
340
340
|
raise ArgumentError, "key cannot be blank" if !key || key.length == 0
|
341
341
|
key = key_with_namespace(key)
|
342
342
|
if key.length > 250
|
343
|
-
|
344
|
-
max_length_before_namespace = 212 - namespace_length
|
343
|
+
max_length_before_namespace = 212 - (namespace || '').size
|
345
344
|
key = "#{key[0, max_length_before_namespace]}:md5:#{Digest::MD5.hexdigest(key)}"
|
346
345
|
end
|
347
346
|
return key
|
348
347
|
end
|
349
348
|
|
350
349
|
def key_with_namespace(key)
|
351
|
-
|
350
|
+
(ns = namespace) ? "#{ns}:#{key}" : key
|
352
351
|
end
|
353
352
|
|
354
353
|
def key_without_namespace(key)
|
355
|
-
|
354
|
+
(ns = namespace) ? key.sub(%r(\A#{ns}:), '') : key
|
355
|
+
end
|
356
|
+
|
357
|
+
def namespace
|
358
|
+
@options[:namespace].is_a?(Proc) ? @options[:namespace].call : @options[:namespace]
|
356
359
|
end
|
357
360
|
|
358
361
|
def normalize_options(opts)
|
data/lib/dalli/ring.rb
CHANGED
@@ -31,7 +31,7 @@ module Dalli
|
|
31
31
|
if @continuum
|
32
32
|
hkey = hash_for(key)
|
33
33
|
20.times do |try|
|
34
|
-
entryidx =
|
34
|
+
entryidx = binary_search(@continuum, hkey)
|
35
35
|
server = @continuum[entryidx].server
|
36
36
|
return server if server.alive?
|
37
37
|
break unless @failover
|
@@ -70,25 +70,60 @@ module Dalli
|
|
70
70
|
((total_servers * POINTS_PER_SERVER * server.weight) / Float(total_weight)).floor
|
71
71
|
end
|
72
72
|
|
73
|
-
#
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
73
|
+
# Native extension to perform the binary search within the continuum
|
74
|
+
# space. Fallback to a pure Ruby version if the compilation doesn't work.
|
75
|
+
# optional for performance and only necessary if you are using multiple
|
76
|
+
# memcached servers.
|
77
|
+
begin
|
78
|
+
require 'inline'
|
79
|
+
inline do |builder|
|
80
|
+
builder.c <<-EOM
|
81
|
+
int binary_search(VALUE ary, unsigned int r) {
|
82
|
+
int upper = RARRAY_LEN(ary) - 1;
|
83
|
+
int lower = 0;
|
84
|
+
int idx = 0;
|
85
|
+
ID value = rb_intern("value");
|
86
|
+
|
87
|
+
while (lower <= upper) {
|
88
|
+
idx = (lower + upper) / 2;
|
89
|
+
|
90
|
+
VALUE continuumValue = rb_funcall(RARRAY_PTR(ary)[idx], value, 0);
|
91
|
+
unsigned int l = NUM2UINT(continuumValue);
|
92
|
+
if (l == r) {
|
93
|
+
return idx;
|
94
|
+
}
|
95
|
+
else if (l > r) {
|
96
|
+
upper = idx - 1;
|
97
|
+
}
|
98
|
+
else {
|
99
|
+
lower = idx + 1;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
return upper;
|
103
|
+
}
|
104
|
+
EOM
|
105
|
+
end
|
106
|
+
rescue
|
107
|
+
# Find the closest index in the Ring with value <= the given value
|
108
|
+
def binary_search(ary, value)
|
109
|
+
upper = ary.size - 1
|
110
|
+
lower = 0
|
111
|
+
idx = 0
|
112
|
+
|
113
|
+
while (lower <= upper) do
|
114
|
+
idx = (lower + upper) / 2
|
115
|
+
comp = ary[idx].value <=> value
|
116
|
+
|
117
|
+
if comp == 0
|
118
|
+
return idx
|
119
|
+
elsif comp > 0
|
120
|
+
upper = idx - 1
|
121
|
+
else
|
122
|
+
lower = idx + 1
|
123
|
+
end
|
89
124
|
end
|
125
|
+
return upper
|
90
126
|
end
|
91
|
-
return upper
|
92
127
|
end
|
93
128
|
|
94
129
|
class Entry
|
data/lib/dalli/server.rb
CHANGED
@@ -116,6 +116,7 @@ module Dalli
|
|
116
116
|
verify_state
|
117
117
|
write_noop
|
118
118
|
@multi_buffer = ''
|
119
|
+
@position = 0
|
119
120
|
@inprogress = true
|
120
121
|
end
|
121
122
|
|
@@ -135,23 +136,26 @@ module Dalli
|
|
135
136
|
|
136
137
|
@multi_buffer << @sock.read_available
|
137
138
|
buf = @multi_buffer
|
139
|
+
pos = @position
|
138
140
|
values = {}
|
139
141
|
|
140
|
-
while buf.bytesize >= 24
|
141
|
-
header = buf.slice(
|
142
|
+
while buf.bytesize - pos >= 24
|
143
|
+
header = buf.slice(pos, 24)
|
142
144
|
(key_length, _, body_length) = header.unpack(KV_HEADER)
|
143
145
|
|
144
146
|
if key_length == 0
|
145
147
|
# all done!
|
146
148
|
@multi_buffer = nil
|
149
|
+
@position = nil
|
147
150
|
@inprogress = false
|
148
151
|
break
|
149
152
|
|
150
|
-
elsif buf.bytesize >=
|
151
|
-
buf.slice
|
152
|
-
|
153
|
-
|
154
|
-
|
153
|
+
elsif buf.bytesize - pos >= 24 + body_length
|
154
|
+
flags = buf.slice(pos + 24, 4).unpack('N')[0]
|
155
|
+
key = buf.slice(pos + 24 + 4, key_length)
|
156
|
+
value = buf.slice(pos + 24 + 4 + key_length, body_length - key_length - 4) if body_length - key_length - 4 > 0
|
157
|
+
|
158
|
+
pos = pos + 24 + body_length
|
155
159
|
|
156
160
|
begin
|
157
161
|
values[key] = deserialize(value, flags)
|
@@ -163,6 +167,7 @@ module Dalli
|
|
163
167
|
break
|
164
168
|
end
|
165
169
|
end
|
170
|
+
@position = pos
|
166
171
|
|
167
172
|
values
|
168
173
|
rescue SystemCallError, Timeout::Error, EOFError
|
@@ -176,6 +181,7 @@ module Dalli
|
|
176
181
|
# Returns nothing.
|
177
182
|
def multi_response_abort
|
178
183
|
@multi_buffer = nil
|
184
|
+
@position = nil
|
179
185
|
@inprogress = false
|
180
186
|
failure!
|
181
187
|
rescue NetworkError
|
data/lib/dalli/version.rb
CHANGED
data/test/test_active_support.rb
CHANGED
@@ -329,7 +329,7 @@ describe 'ActiveSupport' do
|
|
329
329
|
end
|
330
330
|
|
331
331
|
def connect
|
332
|
-
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:19122', :expires_in => 10.seconds, :namespace =>
|
332
|
+
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:19122', :expires_in => 10.seconds, :namespace => lambda{33.to_s(36)})
|
333
333
|
@dalli.clear
|
334
334
|
end
|
335
335
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dalli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.6.
|
4
|
+
version: 2.6.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mini_shoulda
|