dalli 3.0.2 → 3.0.3
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.
- checksums.yaml +4 -4
- data/History.md +10 -0
- data/README.md +4 -6
- data/lib/dalli/client.rb +2 -1
- data/lib/dalli/protocol/binary.rb +8 -24
- data/lib/dalli/protocol/value_compressor.rb +85 -0
- data/lib/dalli/version.rb +1 -1
- data/lib/dalli.rb +1 -0
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4afe70ee94b027c2934fa368a16ca42bf41b7a844c0785c706e2035dba372f66
|
4
|
+
data.tar.gz: 340cf977e332834bfae268995e2d5c70158813f5405fbeee7764e3cc8fa1eb9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3f8a4ca2792149afa6c5b125edad177a69f2bfdaba5106632da7e1ff8c80d0549ea9f4077240d853115caa1711e10e0e966191b9fbb4a5f7103a95bd70629b2
|
7
|
+
data.tar.gz: 28b0926d7367973a0aa57b1d9c95b57f82bf3d7ffd1874259715285538eaa3ab07ab40b67d7c7444734d23da8b20c8f099b1c5c7664f43028aa01715efd48239
|
data/History.md
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
Dalli Changelog
|
2
2
|
=====================
|
3
3
|
|
4
|
+
3.0.3
|
5
|
+
==========
|
6
|
+
|
7
|
+
- Restore ability for `compress` to be disabled on a per request basis (petergoldstein)
|
8
|
+
- Fix broken image in README (deining)
|
9
|
+
- Use bundler-cache in CI (olleolleolle)
|
10
|
+
- Remove the OpenSSL extensions dependency (petergoldstein)
|
11
|
+
- Add Memcached 1.5.x to the CI matrix
|
12
|
+
- Updated compression documentation (petergoldstein)
|
13
|
+
|
4
14
|
3.0.2
|
5
15
|
==========
|
6
16
|
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ Dalli is a high performance pure Ruby client for accessing memcached servers. I
|
|
5
5
|
|
6
6
|
The name is a variant of Salvador Dali for his famous painting [The Persistence of Memory](http://en.wikipedia.org/wiki/The_Persistence_of_Memory).
|
7
7
|
|
8
|
-
![Persistence of Memory](
|
8
|
+
![Persistence of Memory](https://upload.wikimedia.org/wikipedia/en/d/dd/The_Persistence_of_Memory.jpg)
|
9
9
|
|
10
10
|
Dalli's initial development was sponsored by [CouchBase](http://www.couchbase.com/). Many thanks to them!
|
11
11
|
|
@@ -81,9 +81,9 @@ Dalli::Client accepts the following options. All times are in seconds.
|
|
81
81
|
**serializer**: The serializer to use for objects being stored (ex. JSON).
|
82
82
|
Default is Marshal.
|
83
83
|
|
84
|
-
**compress**: Boolean, if true Dalli will gzip-compress values larger than compression_min_size. Default is true.
|
84
|
+
**compress**: Boolean, if true Dalli will gzip-compress values larger than compression_min_size. Can be overridden on a per-request basis. Default is true.
|
85
85
|
|
86
|
-
**compression_min_size**: Minimum value byte size for which to attempt compression. Default is
|
86
|
+
**compression_min_size**: Minimum value byte size for which to attempt compression. Default is 4K.
|
87
87
|
|
88
88
|
**compressor**: The compressor to use for objects being stored.
|
89
89
|
Default is zlib, implemented under `Dalli::Compressor`.
|
@@ -101,8 +101,6 @@ If serving compressed data using nginx's HttpMemcachedModule, set `memcached_gzi
|
|
101
101
|
|
102
102
|
**value_max_bytes**: The maximum size of a value in memcached. Defaults to 1MB, this can be increased with memcached's -I parameter. You must also configure Dalli to allow the larger size here.
|
103
103
|
|
104
|
-
**error_when_over_max_size**: Boolean. If true, Dalli will throw a Dalli::ValueOverMaxSize exception when trying to store data larger than **value_max_bytes**. Defaults to false, meaning only a warning is logged.
|
105
|
-
|
106
104
|
**username**: The username to use for authenticating this client instance against a SASL-enabled memcached server. Heroku users should not need to use this normally.
|
107
105
|
|
108
106
|
**password**: The password to use for authenticating this client instance against a SASL-enabled memcached server. Heroku users should not need to use this normally.
|
@@ -135,7 +133,7 @@ Helping Out
|
|
135
133
|
|
136
134
|
If you have a fix you wish to provide, please fork the code, fix in your local project and then send a pull request on github. Please ensure that you include a test which verifies your fix and update `History.md` with a one sentence description of your fix so you get credit as a contributor.
|
137
135
|
|
138
|
-
We're not accepting new compressors. They are trivial to add in an initializer. See #385 (LZ4), #406 (Snappy)
|
136
|
+
We're not accepting new compressors. They are trivial to add in an initializer. See [#385](https://github.com/petergoldstein/dalli/pull/385) (LZ4), [#406](https://github.com/petergoldstein/dalli/pull/406) (Snappy)
|
139
137
|
|
140
138
|
Thanks
|
141
139
|
------------
|
data/lib/dalli/client.rb
CHANGED
@@ -25,7 +25,8 @@ module Dalli
|
|
25
25
|
# - :failover - if a server is down, look for and store values on another server in the ring. Default: true.
|
26
26
|
# - :threadsafe - ensure that only one thread is actively using a socket at a time. Default: true.
|
27
27
|
# - :expires_in - default TTL in seconds if you do not pass TTL as a parameter to an individual operation, defaults to 0 or forever
|
28
|
-
# - :compress -
|
28
|
+
# - :compress - if true Dalli will compress values larger than compression_min_size bytes before sending them to memcached. Default: true.
|
29
|
+
# - :compression_min_size - the minimum size (in bytes) for which Dalli will compress values sent to Memcached. Defaults to 4K.
|
29
30
|
# - :serializer - defaults to Marshal
|
30
31
|
# - :compressor - defaults to zlib
|
31
32
|
# - :cache_nils - defaults to false, if true Dalli will not treat cached nil values as 'not found' for #fetch operations.
|
@@ -26,10 +26,6 @@ module Dalli
|
|
26
26
|
socket_failure_delay: 0.1,
|
27
27
|
# max size of value in bytes (default is 1 MB, can be overriden with "memcached -I <size>")
|
28
28
|
value_max_bytes: 1024 * 1024,
|
29
|
-
compress: true,
|
30
|
-
compressor: Compressor,
|
31
|
-
# min byte size to attempt compression
|
32
|
-
compression_min_size: 4 * 1024,
|
33
29
|
serializer: Marshal,
|
34
30
|
username: nil,
|
35
31
|
password: nil,
|
@@ -46,6 +42,7 @@ module Dalli
|
|
46
42
|
@down_at = nil
|
47
43
|
@last_down_at = nil
|
48
44
|
@options = DEFAULTS.merge(options)
|
45
|
+
@value_compressor = ValueCompressor.new(@options)
|
49
46
|
@sock = nil
|
50
47
|
@msg = nil
|
51
48
|
@error = nil
|
@@ -117,10 +114,6 @@ module Dalli
|
|
117
114
|
@options[:serializer]
|
118
115
|
end
|
119
116
|
|
120
|
-
def compressor
|
121
|
-
@options[:compressor]
|
122
|
-
end
|
123
|
-
|
124
117
|
# Start reading key/value pairs from this connection. This is usually called
|
125
118
|
# after a series of GETKQ commands. A NOOP is sent, and the server begins
|
126
119
|
# flushing responses for kv pairs that were found.
|
@@ -408,11 +401,9 @@ module Dalli
|
|
408
401
|
generic_response(true, !!(options && options.is_a?(Hash) && options[:cache_nils]))
|
409
402
|
end
|
410
403
|
|
411
|
-
#
|
404
|
+
# https://www.hjp.at/zettel/m/memcached_flags.rxml
|
412
405
|
# Looks like most clients use bit 0 to indicate native language serialization
|
413
|
-
# and bit 1 to indicate gzip compression.
|
414
406
|
FLAG_SERIALIZED = 0x1
|
415
|
-
FLAG_COMPRESSED = 0x2
|
416
407
|
|
417
408
|
def serialize(key, value, options = nil)
|
418
409
|
marshalled = false
|
@@ -432,21 +423,16 @@ module Dalli
|
|
432
423
|
raise exc
|
433
424
|
end
|
434
425
|
end
|
435
|
-
compressed = false
|
436
|
-
set_compress_option = true if options && options[:compress]
|
437
|
-
if (@options[:compress] || set_compress_option) && value.bytesize >= @options[:compression_min_size]
|
438
|
-
value = compressor.compress(value)
|
439
|
-
compressed = true
|
440
|
-
end
|
441
426
|
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
427
|
+
bitflags = 0
|
428
|
+
value, bitflags = @value_compressor.store(value, options, bitflags)
|
429
|
+
|
430
|
+
bitflags |= FLAG_SERIALIZED if marshalled
|
431
|
+
[value, bitflags]
|
446
432
|
end
|
447
433
|
|
448
434
|
def deserialize(value, flags)
|
449
|
-
value =
|
435
|
+
value = @value_compressor.retrieve(value, flags)
|
450
436
|
value = serializer.load(value) if (flags & FLAG_SERIALIZED) != 0
|
451
437
|
value
|
452
438
|
rescue TypeError
|
@@ -458,8 +444,6 @@ module Dalli
|
|
458
444
|
rescue NameError
|
459
445
|
raise unless /uninitialized constant/.match?($!.message)
|
460
446
|
raise UnmarshalError, "Unable to unmarshal value: #{$!.message}"
|
461
|
-
rescue Zlib::Error
|
462
|
-
raise UnmarshalError, "Unable to uncompress value: #{$!.message}"
|
463
447
|
end
|
464
448
|
|
465
449
|
def data_cas_response
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'English'
|
4
|
+
|
5
|
+
module Dalli
|
6
|
+
module Protocol
|
7
|
+
##
|
8
|
+
# Dalli::Protocol::ValueCompressor compartmentalizes the logic for managing
|
9
|
+
# compression and decompression of stored values. It manages interpreting
|
10
|
+
# relevant options from both client and request, determining whether to
|
11
|
+
# compress/decompress on store/retrieve, and processes bitflags as necessary.
|
12
|
+
##
|
13
|
+
class ValueCompressor
|
14
|
+
DEFAULTS = {
|
15
|
+
compress: true,
|
16
|
+
compressor: ::Dalli::Compressor,
|
17
|
+
# min byte size to attempt compression
|
18
|
+
compression_min_size: 4 * 1024 # 4K
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
OPTIONS = DEFAULTS.keys.freeze
|
22
|
+
|
23
|
+
# https://www.hjp.at/zettel/m/memcached_flags.rxml
|
24
|
+
# Looks like most clients use bit 1 to indicate gzip compression.
|
25
|
+
FLAG_COMPRESSED = 0x2
|
26
|
+
|
27
|
+
def initialize(client_options)
|
28
|
+
# Support the deprecated compression option, but don't allow it to override
|
29
|
+
# an explicit compress
|
30
|
+
# Remove this with 4.0
|
31
|
+
if client_options.key?(:compression) && !client_options.key?(:compress)
|
32
|
+
Dalli.logger.warn "DEPRECATED: Dalli's :compression option is now just 'compress: true'. " \
|
33
|
+
'Please update your configuration.'
|
34
|
+
client_options[:compress] = client_options.delete(:compression)
|
35
|
+
end
|
36
|
+
|
37
|
+
@compression_options =
|
38
|
+
DEFAULTS.merge(client_options.select { |k, _| OPTIONS.include?(k) })
|
39
|
+
end
|
40
|
+
|
41
|
+
def store(value, req_options, bitflags)
|
42
|
+
do_compress = compress_value?(value, req_options)
|
43
|
+
store_value = do_compress ? compressor.compress(value) : value
|
44
|
+
bitflags |= FLAG_COMPRESSED if do_compress
|
45
|
+
|
46
|
+
[store_value, bitflags]
|
47
|
+
end
|
48
|
+
|
49
|
+
def retrieve(value, bitflags)
|
50
|
+
compressed = (bitflags & FLAG_COMPRESSED) != 0
|
51
|
+
compressed ? compressor.decompress(value) : value
|
52
|
+
|
53
|
+
# TODO: We likely want to move this rescue into the Dalli::Compressor / Dalli::GzipCompressor
|
54
|
+
# itself, since not all compressors necessarily use Zlib. For now keep it here, so the behavior
|
55
|
+
# of custom compressors doesn't change.
|
56
|
+
rescue Zlib::Error
|
57
|
+
raise UnmarshalError, "Unable to uncompress value: #{$ERROR_INFO.message}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def compress_by_default?
|
61
|
+
@compression_options[:compress]
|
62
|
+
end
|
63
|
+
|
64
|
+
def compressor
|
65
|
+
@compression_options[:compressor]
|
66
|
+
end
|
67
|
+
|
68
|
+
def compression_min_size
|
69
|
+
@compression_options[:compression_min_size]
|
70
|
+
end
|
71
|
+
|
72
|
+
# Checks whether we should apply compression when serializing a value
|
73
|
+
# based on the specified options. Returns false unless the value
|
74
|
+
# is greater than the minimum compression size. Otherwise returns
|
75
|
+
# based on a method-level option if specified, falling back to the
|
76
|
+
# server default.
|
77
|
+
def compress_value?(value, req_options)
|
78
|
+
return false unless value.bytesize >= compression_min_size
|
79
|
+
return compress_by_default? unless req_options && !req_options[:compress].nil?
|
80
|
+
|
81
|
+
req_options[:compress]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/dalli/version.rb
CHANGED
data/lib/dalli.rb
CHANGED
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: 3.0.
|
4
|
+
version: 3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter M. Goldstein
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-10-
|
12
|
+
date: 2021-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -39,20 +39,6 @@ dependencies:
|
|
39
39
|
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
|
-
- !ruby/object:Gem::Dependency
|
43
|
-
name: openssl-extensions
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
45
|
-
requirements:
|
46
|
-
- - ">="
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '0'
|
49
|
-
type: :development
|
50
|
-
prerelease: false
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - ">="
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: '0'
|
56
42
|
description: High performance memcached client for Ruby
|
57
43
|
email:
|
58
44
|
- peter.m.goldstein@gmail.com
|
@@ -72,6 +58,7 @@ files:
|
|
72
58
|
- lib/dalli/options.rb
|
73
59
|
- lib/dalli/protocol.rb
|
74
60
|
- lib/dalli/protocol/binary.rb
|
61
|
+
- lib/dalli/protocol/value_compressor.rb
|
75
62
|
- lib/dalli/ring.rb
|
76
63
|
- lib/dalli/server.rb
|
77
64
|
- lib/dalli/socket.rb
|