dalli 3.2.4 → 3.2.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e182f80ca3d5c567c59e32d7396f0c347ad79633672af15d6f231950909f12dd
4
- data.tar.gz: 92ddb5854da64ce59fb07c2eae7e1c1ce94d36868d26776c6415d20569dc0466
3
+ metadata.gz: d9a374b5939ef874ce8067059c88b088c9129e7ab09ff891b1ad1ca3cf13c3ce
4
+ data.tar.gz: d5937c697bcd86a6d3d4207d328ce7e73c854b93a1d19e402630c3f80caec2ec
5
5
  SHA512:
6
- metadata.gz: 89b2f797e3abe759ddb154c10c91cfe4126341c0bd95202637e8ff67845a02669e0be4cdfc486679e45322f31976b41a404f7223b03042107aab8db3011414c5
7
- data.tar.gz: 4bc8eb1c4b478b946e202709d9d20995ebcb894ab32b5be070a19f99cecdfbd5ff0219344fe7288710202159a1b33298c1408e878a39cf256086f892ea5c4d41
6
+ metadata.gz: 36010355440b325c1f8d5b922e882a8a8e199b8bd48dda92b1dcc4866f29e81b536ce41ff4896441c6c2c4f4e8e8faaf891ca6355e47de91733baf10bdfa9eee
7
+ data.tar.gz: 0c2b42e88960838ceef44c6c0f696b938925ade65da7c8791a07539ca36e18d6e874693dfde840a08e78ac9076f6810735a05d137c98d8c64387414f89d6f016
data/CHANGELOG.md CHANGED
@@ -4,11 +4,23 @@ Dalli Changelog
4
4
  Unreleased
5
5
  ==========
6
6
 
7
+ 3.2.6
8
+ ==========
9
+
10
+ - Rescue IO::TimeoutError raised by Ruby since 3.2.0 on blocking reads/writes (skaes)
11
+ - Fix rubydoc link (JuanitoFatas)
12
+
13
+ 3.2.5
14
+ ==========
15
+
16
+ - Better handle memcached requests being interrupted by Thread#raise or Thread#kill (byroot)
17
+ - Unexpected errors are no longer treated as `Dalli::NetworkError`, including errors raised by `Timeout.timeout` (byroot)
18
+
7
19
  3.2.4
8
20
  ==========
9
21
 
10
- - Cache PID calls for performance since glibc no longer caches in recent versions (casperisfine)
11
- - Preallocate the read buffer in Socket#readfull (casperisfine)
22
+ - Cache PID calls for performance since glibc no longer caches in recent versions (byroot)
23
+ - Preallocate the read buffer in Socket#readfull (byroot)
12
24
 
13
25
  3.2.3
14
26
  ==========
@@ -51,7 +63,7 @@ Unreleased
51
63
  3.1.4
52
64
  ==========
53
65
 
54
- - Improve response parsing performance (casperisfine)
66
+ - Improve response parsing performance (byroot)
55
67
  - Reorganize binary protocol parsing a bit (petergoldstein)
56
68
  - Fix handling of non-ASCII keys in get_multi (petergoldstein)
57
69
 
data/README.md CHANGED
@@ -23,7 +23,7 @@ The name is a variant of Salvador Dali for his famous painting [The Persistence
23
23
  * [Announcements](https://github.com/petergoldstein/dalli/discussions/categories/announcements) - Announcements of interest to the Dalli community will be posted here.
24
24
  * [Bug Reports](https://github.com/petergoldstein/dalli/issues) - If you discover a problem with Dalli, please submit a bug report in the tracker.
25
25
  * [Forum](https://github.com/petergoldstein/dalli/discussions/categories/q-a) - If you have questions about Dalli, please post them here.
26
- * [Client API](https://rubydoc.info/github/petergoldstein/dalli/Dalli/Client) - Ruby documentation for the `Dalli::Client` API
26
+ * [Client API](https://www.rubydoc.info/gems/dalli) - Ruby documentation for the `Dalli::Client` API
27
27
 
28
28
  ## Development
29
29
 
@@ -32,7 +32,13 @@ module Dalli
32
32
  verify_state(opkey)
33
33
 
34
34
  begin
35
- send(opkey, *args)
35
+ @connection_manager.start_request!
36
+ response = send(opkey, *args)
37
+
38
+ # pipelined_get emit query but doesn't read the response(s)
39
+ @connection_manager.finish_request! unless opkey == :pipelined_get
40
+
41
+ response
36
42
  rescue Dalli::MarshalError => e
37
43
  log_marshal_err(args.first, e)
38
44
  raise
@@ -40,7 +46,8 @@ module Dalli
40
46
  raise
41
47
  rescue StandardError => e
42
48
  log_unexpected_err(e)
43
- down!
49
+ close
50
+ raise
44
51
  end
45
52
  end
46
53
 
@@ -65,10 +72,9 @@ module Dalli
65
72
  #
66
73
  # Returns nothing.
67
74
  def pipeline_response_setup
68
- verify_state(:getkq)
75
+ verify_pipelined_state(:getkq)
69
76
  write_noop
70
77
  response_buffer.reset
71
- @connection_manager.start_request!
72
78
  end
73
79
 
74
80
  # Attempt to receive and parse as many key/value pairs as possible
@@ -100,7 +106,7 @@ module Dalli
100
106
  end
101
107
 
102
108
  values
103
- rescue SystemCallError, Timeout::Error, EOFError => e
109
+ rescue SystemCallError, *TIMEOUT_ERRORS, EOFError => e
104
110
  @connection_manager.error_on_request!(e)
105
111
  end
106
112
 
@@ -169,6 +175,11 @@ module Dalli
169
175
  raise_down_error unless ensure_connected!
170
176
  end
171
177
 
178
+ def verify_pipelined_state(_opkey)
179
+ @connection_manager.confirm_in_progress!
180
+ raise_down_error unless connected?
181
+ end
182
+
172
183
  # The socket connection to the underlying server is initialized as a side
173
184
  # effect of this call. In fact, this is the ONLY place where that
174
185
  # socket connection is initialized.
@@ -52,7 +52,7 @@ module Dalli
52
52
  bitflags = extra_len.positive? ? body.unpack1('N') : 0x0
53
53
  key = body.byteslice(extra_len, key_len).force_encoding(Encoding::UTF_8) if key_len.positive?
54
54
  value = body.byteslice((extra_len + key_len)..-1)
55
- value = parse_as_stored_value ? @value_marshaller.retrieve(value, bitflags) : value
55
+ value = @value_marshaller.retrieve(value, bitflags) if parse_as_stored_value
56
56
  [key, value]
57
57
  end
58
58
 
@@ -54,6 +54,7 @@ module Dalli
54
54
 
55
55
  @sock = memcached_socket
56
56
  @pid = PIDCache.pid
57
+ @request_in_progress = false
57
58
  rescue SystemCallError, Timeout::Error, EOFError, SocketError => e
58
59
  # SocketError = DNS resolution failure
59
60
  error_on_request!(e)
@@ -98,7 +99,13 @@ module Dalli
98
99
  end
99
100
 
100
101
  def confirm_ready!
101
- error_on_request!(RuntimeError.new('Already writing to socket')) if request_in_progress?
102
+ close if request_in_progress?
103
+ close_on_fork if fork_detected?
104
+ end
105
+
106
+ def confirm_in_progress!
107
+ raise '[Dalli] No request in progress. This may be a bug in Dalli.' unless request_in_progress?
108
+
102
109
  close_on_fork if fork_detected?
103
110
  end
104
111
 
@@ -124,10 +131,14 @@ module Dalli
124
131
  end
125
132
 
126
133
  def start_request!
134
+ raise '[Dalli] Request already in progress. This may be a bug in Dalli.' if @request_in_progress
135
+
127
136
  @request_in_progress = true
128
137
  end
129
138
 
130
139
  def finish_request!
140
+ raise '[Dalli] No request in progress. This may be a bug in Dalli.' unless @request_in_progress
141
+
131
142
  @request_in_progress = false
132
143
  end
133
144
 
@@ -136,36 +147,26 @@ module Dalli
136
147
  end
137
148
 
138
149
  def read_line
139
- start_request!
140
150
  data = @sock.gets("\r\n")
141
151
  error_on_request!('EOF in read_line') if data.nil?
142
- finish_request!
143
152
  data
144
- rescue SystemCallError, Timeout::Error, EOFError => e
153
+ rescue SystemCallError, *TIMEOUT_ERRORS, EOFError => e
145
154
  error_on_request!(e)
146
155
  end
147
156
 
148
157
  def read(count)
149
- start_request!
150
- data = @sock.readfull(count)
151
- finish_request!
152
- data
153
- rescue SystemCallError, Timeout::Error, EOFError => e
158
+ @sock.readfull(count)
159
+ rescue SystemCallError, *TIMEOUT_ERRORS, EOFError => e
154
160
  error_on_request!(e)
155
161
  end
156
162
 
157
163
  def write(bytes)
158
- start_request!
159
- result = @sock.write(bytes)
160
- finish_request!
161
- result
162
- rescue SystemCallError, Timeout::Error => e
164
+ @sock.write(bytes)
165
+ rescue SystemCallError, *TIMEOUT_ERRORS => e
163
166
  error_on_request!(e)
164
167
  end
165
168
 
166
- # Non-blocking read. Should only be used in the context
167
- # of a caller who has called start_request!, but not yet
168
- # called finish_request!. Here to support the operation
169
+ # Non-blocking read. Here to support the operation
169
170
  # of the get_multi operation
170
171
  def read_nonblock
171
172
  @sock.read_available
@@ -1,8 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'timeout'
4
+
3
5
  module Dalli
4
6
  module Protocol
5
7
  # Preserved for backwards compatibility. Should be removed in 4.0
6
8
  NOT_FOUND = ::Dalli::NOT_FOUND
9
+
10
+ # Ruby 3.2 raises IO::TimeoutError on blocking reads/writes, but
11
+ # it is not defined in earlier Ruby versions.
12
+ TIMEOUT_ERRORS =
13
+ if defined?(IO::TimeoutError)
14
+ [Timeout::Error, IO::TimeoutError]
15
+ else
16
+ [Timeout::Error]
17
+ end
7
18
  end
8
19
  end
data/lib/dalli/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dalli
4
- VERSION = '3.2.4'
4
+ VERSION = '3.2.6'
5
5
 
6
6
  MIN_SUPPORTED_MEMCACHED_VERSION = '1.4'
7
7
  end
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.2.4
4
+ version: 3.2.6
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: 2023-02-17 00:00:00.000000000 Z
12
+ date: 2023-09-26 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: High performance memcached client for Ruby
15
15
  email:
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  requirements: []
78
- rubygems_version: 3.4.5
78
+ rubygems_version: 3.4.19
79
79
  signing_key:
80
80
  specification_version: 4
81
81
  summary: High performance memcached client for Ruby