excon 0.104.0 → 0.105.0

Sign up to get free protection for your applications and to get access to all the features.
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