excon 0.104.0 → 0.105.0

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: d5178f794971246bbfa44097a97594cb9480a13ff11b9884c1fa1ac79e94c0a6
4
- data.tar.gz: c5ea1c85e77eddba09b655f18ad415f03eb824481e562ee88c0c756850c61463
3
+ metadata.gz: bf1521a5cb2831330da53ba05456633a8219047e6a0d0f7892b32c8d49a074c0
4
+ data.tar.gz: 242837bbe9feba5985fc5fbe969a8d22cc9ab36bc4bd80479377d1a9596e2d05
5
5
  SHA512:
6
- metadata.gz: 210b6c6ca9be3b3668f9f24c509f95e6a41533c9f0290ccd4a967f92fed1f335f837ce8ff52b8bcc3d5fb3d21d236ed179a67d70df2c8c0202a3772a282c5840
7
- data.tar.gz: a1cf5fdb74468a879741b482bef3734e74b4c390551cbfbad7762b06bb892877a30255d872c27404ee0e0f137ad208c7fa73b167fb64fdddaffe063e8a3eb5bb
6
+ metadata.gz: ba2f9e23944c16efbbc8edb7515af65629b1d763b7e20bea60180d4c8e995ec3829b3152c48308f760c2ac79e39851de069046b614bc6c725f3e2210f4d9d77f
7
+ data.tar.gz: e399f1c89cf8fa3eb1f03f2ff8430272d0db3ebc95c9d9cd23362cd46c0b6d7a4515ffd181aaf8d51fa3b0218915bc762e42090c8c5048d7f9750d23cf21039b
data/README.md CHANGED
@@ -179,6 +179,10 @@ connection.request(:read_timeout => 360)
179
179
  # set longer write_timeout (default is 60 seconds)
180
180
  connection.request(:write_timeout => 360)
181
181
 
182
+ # set a request timeout in seconds (default is no timeout).
183
+ # the timeout may be an integer or a float to support sub-second granularity (e.g., 1, 60, 0.005 and 3.5).
184
+ connection.request(:timeout => 0.1) # timeout if the entire request takes longer than 100 milliseconds
185
+
182
186
  # Enable the socket option TCP_NODELAY on the underlying socket.
183
187
  #
184
188
  # This can improve response time when sending frequent short
@@ -230,6 +230,13 @@ module Excon
230
230
  def request(params={}, &block)
231
231
  # @data has defaults, merge in new params to override
232
232
  datum = @data.merge(params)
233
+
234
+ # Set the deadline for the current request in order to determine when we have run out of time.
235
+ # Only set when a request timeout has been defined.
236
+ if datum[:timeout]
237
+ datum[:deadline] = Process.clock_gettime(Process::CLOCK_MONOTONIC) + datum[:timeout]
238
+ end
239
+
233
240
  datum[:headers] = @data[:headers].merge(datum[:headers] || {})
234
241
 
235
242
  validate_params(:request, params, datum[:middlewares])
@@ -62,6 +62,7 @@ module Excon
62
62
  :resolv_resolver,
63
63
  :response_block,
64
64
  :stubs,
65
+ :timeout,
65
66
  :user,
66
67
  :versions,
67
68
  :write_timeout
@@ -171,6 +172,7 @@ module Excon
171
172
  :stubs => :global,
172
173
  :tcp_nodelay => false,
173
174
  :thread_safe_sockets => true,
175
+ :timeout => nil,
174
176
  :uri_parser => URI,
175
177
  :versions => VERSIONS,
176
178
  :write_timeout => 60
data/lib/excon/socket.rb CHANGED
@@ -25,6 +25,13 @@ module Excon
25
25
  else # Ruby <= 2.0
26
26
  [Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable]
27
27
  end
28
+ # Maps a socket operation to a timeout property.
29
+ OPERATION_TO_TIMEOUT = {
30
+ :connect_read => :connect_timeout,
31
+ :connect_write => :connect_timeout,
32
+ :read => :read_timeout,
33
+ :write => :write_timeout
34
+ }.freeze
28
35
 
29
36
  def params
30
37
  Excon.display_warning('Excon::Socket#params is deprecated use Excon::Socket#data instead.')
@@ -304,17 +311,33 @@ module Excon
304
311
  end
305
312
 
306
313
  def select_with_timeout(socket, type)
314
+ timeout_kind = type
315
+ timeout = @data[OPERATION_TO_TIMEOUT[type]]
316
+
317
+ # Check whether the request has a timeout configured.
318
+ if @data.include?(:deadline)
319
+ request_timeout = request_time_remaining
320
+
321
+ # If the time remaining until the request times out is less than the timeout for the type of select,
322
+ # use the time remaining as the timeout instead.
323
+ if request_timeout < timeout
324
+ timeout_kind = :request
325
+ timeout = request_timeout
326
+ end
327
+ end
328
+
307
329
  select = case type
308
330
  when :connect_read
309
- IO.select([socket], nil, nil, @data[:connect_timeout])
331
+ IO.select([socket], nil, nil, timeout)
310
332
  when :connect_write
311
- IO.select(nil, [socket], nil, @data[:connect_timeout])
333
+ IO.select(nil, [socket], nil, timeout)
312
334
  when :read
313
- IO.select([socket], nil, nil, @data[:read_timeout])
335
+ IO.select([socket], nil, nil, timeout)
314
336
  when :write
315
- IO.select(nil, [socket], nil, @data[:write_timeout])
337
+ IO.select(nil, [socket], nil, timeout)
316
338
  end
317
- select || raise(Excon::Errors::Timeout.new("#{type} timeout reached"))
339
+
340
+ select || raise(Excon::Errors::Timeout.new("#{timeout_kind} timeout reached"))
318
341
  end
319
342
 
320
343
  def unpacked_sockaddr
@@ -324,5 +347,16 @@ module Excon
324
347
  raise
325
348
  end
326
349
  end
350
+
351
+ # Returns the remaining time in seconds until we reach the deadline for the request timeout.
352
+ # Raises an exception if we have exceeded the request timeout's deadline.
353
+ def request_time_remaining
354
+ now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
355
+ deadline = @data[:deadline]
356
+
357
+ raise(Excon::Errors::Timeout.new('request timeout reached')) if now >= deadline
358
+
359
+ deadline - now
360
+ end
327
361
  end
328
362
  end
data/lib/excon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Excon
4
- VERSION = '0.104.0'
4
+ VERSION = '0.105.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: excon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.104.0
4
+ version: 0.105.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dpiddy (Dan Peterson)
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-09-29 00:00:00.000000000 Z
13
+ date: 2023-11-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec