async-http-faraday 0.19.0 → 0.21.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: 405bbaf8e19d542be2efd5e6ba29e5dabaa0fedbbad6c392f70b70dac5295f21
4
- data.tar.gz: 2ae52a3a031dea0f6c715e7144f9e0ed2872b0e9b2c8a07043ce1be49f8640a5
3
+ metadata.gz: 61ec5bb845598b4ed1282944e5ecce5ed41fd0abcac72c4bcdaedcf40b707e89
4
+ data.tar.gz: b16fe2a762a49b3cc20cc5c8f7e674d764ef81f1ab1cd8f95fa41f11e5bc057e
5
5
  SHA512:
6
- metadata.gz: 8808afa0006650011169d8a9ea52d7029e8e7032d84eceec7e2fa2046b58e66297c3a5b0166ed623b81198161e5a5830309b4db21e30e9174d69f21927bb0a6f
7
- data.tar.gz: '064528fe335006b4b00ba6719c119bf583c0cfb20ebdf67d74324d98c74d1c95c3bd9d00359ae1bf80d1fdaca796203526c95473a1d392128eff66b392770dba'
6
+ metadata.gz: 330032d445badaf1eace0bf580012c573b24a83128c3cb7bd6b479d8710b65558450d892000cbf21aacda704428d28e63dba834f7456c5bc53b7c473f6cd511b
7
+ data.tar.gz: 584dd4a49d4af9d088a386f8a6130f199396ba6b93ee79af3a9fc15a6ebfcf66f0cddc7d95cfabb1d9d9acc18291e2128b0e003845e7c6241ec1fc7cc3ba2d2a
checksums.yaml.gz.sig CHANGED
Binary file
data/examples/topics.rb CHANGED
@@ -2,18 +2,18 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Released under the MIT License.
5
- # Copyright, 2020-2024, by Samuel Williams.
5
+ # Copyright, 2020-2025, by Samuel Williams.
6
6
 
7
7
  $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
8
8
 
9
- require 'async'
10
- require 'faraday'
11
- require 'async/http/faraday'
9
+ require "async"
10
+ require "faraday"
11
+ require "async/http/faraday"
12
12
 
13
13
  # Async.logger.debug!
14
14
 
15
15
  module TestAsync
16
- URL = 'https://www.google.com/search'
16
+ URL = "https://www.google.com/search"
17
17
  TOPICS = %W{ruby python lisp javascript cobol}
18
18
 
19
19
  def self.fetch_topics_async
@@ -1,25 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2024, by Samuel Williams.
4
+ # Copyright, 2018-2025, by Samuel Williams.
5
5
  # Copyright, 2018, by Andreas Garnaes.
6
6
  # Copyright, 2019, by Denis Talakevich.
7
7
  # Copyright, 2019-2020, by Igor Sidorov.
8
8
  # Copyright, 2023, by Genki Takiuchi.
9
9
  # Copyright, 2023, by Flavio Fernandes.
10
10
  # Copyright, 2024, by Jacob Frautschi.
11
- # Copyright, 2024, by Korbin Hoffman.
11
+ # Copyright, 2025, by Nikolaos Anastopoulos.
12
12
 
13
- require 'faraday'
14
- require 'faraday/adapter'
13
+ require "faraday"
14
+ require "faraday/adapter"
15
15
 
16
- require 'async/barrier'
17
- require 'kernel/sync'
16
+ require "async/barrier"
17
+ require "kernel/sync"
18
18
 
19
- require 'async/http/client'
20
- require 'async/http/proxy'
19
+ require "async/http/client"
20
+ require "async/http/proxy"
21
21
 
22
- require_relative 'clients'
22
+ require_relative "clients"
23
23
 
24
24
  module Async
25
25
  module HTTP
@@ -50,18 +50,22 @@ module Async
50
50
  end
51
51
  end
52
52
 
53
+ # Implement the Faraday parallel manager interface, using Async.
53
54
  class ParallelManager
55
+ # Create a new parallel manager.
54
56
  def initialize(options = {})
55
57
  @options = options
56
58
  @barrier = nil
57
59
  end
58
60
 
61
+ # @deprecated Please update your Faraday version!
59
62
  def run
60
63
  if $VERBOSE
61
64
  warn "Please update your Faraday version!", uplevel: 2
62
65
  end
63
66
  end
64
67
 
68
+ # Run the given block asynchronously, using the barrier if available.
65
69
  def async(&block)
66
70
  if @barrier
67
71
  @barrier.async(&block)
@@ -70,6 +74,7 @@ module Async
70
74
  end
71
75
  end
72
76
 
77
+ # Execute the given block which can perform multiple concurrent requests, waiting for them all to complete.
73
78
  def execute(&block)
74
79
  Sync do
75
80
  @barrier = Async::Barrier.new
@@ -87,6 +92,7 @@ module Async
87
92
  class Adapter < ::Faraday::Adapter
88
93
  self.supports_parallel = true
89
94
 
95
+ # Create a new parallel manager, which is used to handle multiple concurrent requests.
90
96
  def self.setup_parallel_manager(**options)
91
97
  ParallelManager.new(options)
92
98
  end
@@ -113,6 +119,7 @@ module Async
113
119
  super
114
120
 
115
121
  @timeout = @connection_options.delete(:timeout)
122
+ @read_timeout = @connection_options.delete(:read_timeout)
116
123
 
117
124
  if clients = @connection_options.delete(:clients)
118
125
  @clients = clients.call(**@connection_options, &@config_block)
@@ -121,6 +128,12 @@ module Async
121
128
  end
122
129
  end
123
130
 
131
+ # @attribute [Numeric | Nil] The maximum time to send a request and wait for a response.
132
+ attr :timeout
133
+
134
+ # @attribute [Numeric | Nil] The maximum time to wait for an individual IO operation.
135
+ attr :read_timeout
136
+
124
137
  # Close all clients.
125
138
  def close
126
139
  # The order of operations here is to avoid a race condition between iterating over clients (#close may yield) and creating new clients.
@@ -137,7 +150,7 @@ module Async
137
150
  super
138
151
 
139
152
  # For compatibility with the default adapter:
140
- env.url.path = '/' if env.url.path.empty?
153
+ env.url.path = "/" if env.url.path.empty?
141
154
 
142
155
  if parallel_manager = env.parallel_manager
143
156
  parallel_manager.async do
@@ -175,39 +188,39 @@ module Async
175
188
 
176
189
  request = ::Protocol::HTTP::Request.new(endpoint.scheme, endpoint.authority, method, endpoint.path, nil, headers, body)
177
190
 
178
- with_timeout do
191
+ with_timeout(env.request.timeout || @timeout) do
179
192
  if env.stream_response?
180
193
  response = env.stream_response do |&on_data|
181
194
  response = client.call(request)
182
195
 
196
+ save_response(env, response.status, nil, response.headers, finished: false)
197
+
183
198
  response.each do |chunk|
184
199
  on_data.call(chunk)
185
200
  end
186
201
 
187
202
  response
188
203
  end
189
-
190
- save_response(env, response.status, nil, response.headers)
191
204
  else
192
205
  response = client.call(request)
193
-
194
- save_response(env, response.status, encoded_body(response), response.headers)
195
206
  end
207
+
208
+ save_response(env, response.status, encoded_body(response), response.headers)
196
209
  end
197
210
  end
198
211
 
199
212
  return @app.call(env)
200
- rescue Errno::ETIMEDOUT, Async::TimeoutError => e
201
- raise ::Faraday::TimeoutError, e
202
- rescue OpenSSL::SSL::SSLError => e
203
- raise ::Faraday::SSLError, e
204
- rescue *CONNECTION_EXCEPTIONS => e
205
- raise ::Faraday::ConnectionFailed, e
213
+ rescue Errno::ETIMEDOUT, Async::TimeoutError => error
214
+ raise ::Faraday::TimeoutError, error
215
+ rescue OpenSSL::SSL::SSLError => error
216
+ raise ::Faraday::SSLError, error
217
+ rescue *CONNECTION_EXCEPTIONS => error
218
+ raise ::Faraday::ConnectionFailed, error
206
219
  end
207
220
 
208
221
  def with_client(env)
209
222
  Sync do
210
- endpoint = Endpoint.new(env.url)
223
+ endpoint = Endpoint.new(env.url, timeout: @read_timeout)
211
224
 
212
225
  if proxy = env.request.proxy
213
226
  proxy_endpoint = Endpoint.new(proxy.uri)
@@ -223,9 +236,9 @@ module Async
223
236
  end
224
237
  end
225
238
 
226
- def with_timeout(task: Async::Task.current)
227
- if @timeout
228
- task.with_timeout(@timeout, ::Faraday::TimeoutError) do
239
+ def with_timeout(timeout = @timeout, task: Async::Task.current)
240
+ if timeout
241
+ task.with_timeout(timeout, ::Faraday::TimeoutError) do
229
242
  yield
230
243
  end
231
244
  else
@@ -235,11 +248,11 @@ module Async
235
248
 
236
249
  def encoded_body(response)
237
250
  body = response.read
238
- return body if body.nil?
239
- content_type = response.headers['content-type']
251
+ return "" if body.nil?
252
+ content_type = response.headers["content-type"]
240
253
  return body unless content_type
241
254
  params = extract_type_parameters(content_type)
242
- if charset = params['charset']
255
+ if charset = params["charset"]
243
256
  body = body.dup if body.frozen?
244
257
  body.force_encoding(charset)
245
258
  end
@@ -250,10 +263,10 @@ module Async
250
263
 
251
264
  def extract_type_parameters(content_type)
252
265
  result = {}
253
- list = content_type.split(';')
266
+ list = content_type.split(";")
254
267
  list.shift
255
268
  list.each do |param|
256
- key, value = *param.split('=', 2)
269
+ key, value = *param.split("=", 2)
257
270
  result[key.strip] = value.strip
258
271
  end
259
272
  result
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2024, by Samuel Williams.
4
+ # Copyright, 2024-2025, by Samuel Williams.
5
5
 
6
- require 'faraday'
7
- require 'faraday/adapter'
8
- require 'kernel/sync'
6
+ require "faraday"
7
+ require "faraday/adapter"
8
+ require "kernel/sync"
9
9
 
10
- require 'async/http/client'
11
- require 'async/http/proxy'
10
+ require "async/http/client"
11
+ require "async/http/proxy"
12
12
 
13
13
  module Async
14
14
  module HTTP
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2020-2024, by Samuel Williams.
4
+ # Copyright, 2020-2025, by Samuel Williams.
5
5
 
6
- require_relative 'adapter'
6
+ require_relative "register"
7
7
 
8
8
  # Set the default adapter to use Async::HTTP.
9
9
  ::Faraday.default_adapter = :async_http
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Samuel Williams.
5
+
6
+ require_relative "adapter"
7
+
8
+ Faraday::Adapter.register_middleware :async_http => Async::HTTP::Faraday::Adapter
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2024, by Samuel Williams.
4
+ # Copyright, 2018-2025, by Samuel Williams.
5
5
 
6
6
  module Async
7
7
  module HTTP
8
8
  module Faraday
9
- VERSION = "0.19.0"
9
+ VERSION = "0.21.0"
10
10
  end
11
11
  end
12
12
  end
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2024, by Samuel Williams.
4
+ # Copyright, 2018-2025, by Samuel Williams.
5
5
 
6
6
  require_relative "faraday/version"
7
- require_relative "faraday/adapter"
8
-
9
- Faraday::Adapter.register_middleware :async_http => Async::HTTP::Faraday::Adapter
7
+ require_relative "faraday/register"
10
8
 
11
9
  # @namespace
12
10
  module Async
data/license.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright, 2018-2024, by Samuel Williams.
3
+ Copyright, 2018-2025, by Samuel Williams.
4
4
  Copyright, 2018, by Andreas Garnaes.
5
5
  Copyright, 2019, by Denis Talakevich.
6
6
  Copyright, 2019-2020, by Igor Sidorov.
@@ -9,7 +9,7 @@ Copyright, 2020, by Benoit Daloze.
9
9
  Copyright, 2023, by Genki Takiuchi.
10
10
  Copyright, 2023, by Flavio Fernandes.
11
11
  Copyright, 2024, by Jacob Frautschi.
12
- Copyright, 2024, by Korbin Hoffman.
12
+ Copyright, 2025, by Nikolaos Anastopoulos.
13
13
 
14
14
  Permission is hereby granted, free of charge, to any person obtaining a copy
15
15
  of this software and associated documentation files (the "Software"), to deal
data/readme.md CHANGED
@@ -15,15 +15,28 @@ Please see the [project documentation](https://socketry.github.io/async-http-far
15
15
 
16
16
  ## Releases
17
17
 
18
- Please see the [project changes](https://socketry.github.io/async-http-faraday//changes/index) for all releases.
18
+ Please see the [project releases](https://socketry.github.io/async-http-faraday/releases/index) for all releases.
19
+
20
+ ### v0.21.0
21
+
22
+ - [Improved support for `timeout` and `read_timeout`.](https://socketry.github.io/async-http-faraday/releases/index#improved-support-for-timeout-and-read_timeout.)
23
+
24
+ ### v0.20.0
25
+
26
+ - Implement the new response streaming interface, which provides the initial response status code and headers before streaming the response body.
27
+ - An empty response now sets the response body to an empty string rather than `nil` as required by the Faraday specification.
28
+
29
+ ### v0.19.0
30
+
31
+ - [Support `in_parallel`.](https://socketry.github.io/async-http-faraday/releases/index#support-in_parallel.)
19
32
 
20
33
  ### v0.18.0
21
34
 
22
- - [Config Block](https://socketry.github.io/async-http-faraday/changes/index#config-block)
35
+ - [Support for `config_block` returning a middleware wrapper.](https://socketry.github.io/async-http-faraday/releases/index#support-for-config_block-returning-a-middleware-wrapper.)
23
36
 
24
37
  ### v0.17.0
25
38
 
26
- - [Per-thread Client Cache](https://socketry.github.io/async-http-faraday/changes/index#per-thread-client-cache)
39
+ - [Introduced a per-thread `Client` cache.](https://socketry.github.io/async-http-faraday/releases/index#introduced-a-per-thread-client-cache.)
27
40
 
28
41
  ## Contributing
29
42
 
data/releases.md ADDED
@@ -0,0 +1,94 @@
1
+ # Releases
2
+
3
+ ## v0.21.0
4
+
5
+ ### Improved support for `timeout` and `read_timeout`.
6
+
7
+ Previously, only a per-connection `timeout` was supported, but now:
8
+
9
+ 1. `timeout` can be set per request too.
10
+ 2. `read_timeout` can be set per adapter and is assigned to `IO#timeout` if available.
11
+
12
+ This improves compatibility with existing code that uses `timeout` and `read_timeout`.
13
+
14
+ ## v0.20.0
15
+
16
+ - Implement the new response streaming interface, which provides the initial response status code and headers before streaming the response body.
17
+ - An empty response now sets the response body to an empty string rather than `nil` as required by the Faraday specification.
18
+
19
+ ## v0.19.0
20
+
21
+ ### Support `in_parallel`.
22
+
23
+ The adapter now supports the `in_parallel` method, which allows multiple requests to be made concurrently.
24
+
25
+ ``` ruby
26
+ adapter = Faraday.new(bound_url) do |builder|
27
+ builder.adapter :async_http
28
+ end
29
+
30
+ response1 = response2 = response3 = nil
31
+
32
+ adapter.in_parallel do
33
+ response1 = adapter.get("/index")
34
+ response2 = adapter.get("/index")
35
+ response3 = adapter.get("/index")
36
+ end
37
+
38
+ puts response1.body # => "Hello World"
39
+ puts response2.body # => "Hello World"
40
+ puts response3.body # => "Hello World"
41
+ ```
42
+
43
+ This is primarily for compatibility with existing code. If you are designing a new library, you should just use `Async` directly:
44
+
45
+ ``` ruby
46
+ Async do
47
+ response1 = Async{adapter.get("/index")}
48
+ response2 = Async{adapter.get("/index")}
49
+ response3 = Async{adapter.get("/index")}
50
+
51
+ puts response1.wait.body # => "Hello World"
52
+ puts response2.wait.body # => "Hello World"
53
+ puts response3.wait.body # => "Hello World"
54
+ end
55
+ ```
56
+
57
+ ## v0.18.0
58
+
59
+ ### Support for `config_block` returning a middleware wrapper.
60
+
61
+ The `config_block` provided to the adapter must now return `nil`, `client` or a middleware wrapper around `client`.
62
+
63
+ ``` ruby
64
+ Faraday.new do |builder|
65
+ builder.adapter :async_http do |client|
66
+ # Option 1 (same as returning `nil`), use client as is:
67
+ client # Use `client` as is.
68
+
69
+ # Option 2, wrap client in a middleware:
70
+ Async::HTTP::Middleware::LocationRedirector.new(client)
71
+ end
72
+ end
73
+ ```
74
+
75
+ ## v0.17.0
76
+
77
+ ### Introduced a per-thread `Client` cache.
78
+
79
+ The default adapter now uses a per-thread client cache internally, to improve compatibility with existing code that shares a single `Faraday::Connection` instance across multiple threads.
80
+
81
+ ``` ruby
82
+ adapter = Faraday.new do |builder|
83
+ builder.adapter :async_http
84
+ end
85
+
86
+ 3.times do
87
+ Thread.new do
88
+ Async do
89
+ # Each thread has it's own client cache.
90
+ adapter.get('http://example.com')
91
+ end
92
+ end
93
+ end
94
+ ```
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,20 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-http-faraday
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  - Igor Sidorov
9
9
  - Andreas Garnaes
10
10
  - Genki Takiuchi
11
+ - Nikolaos Anastopoulos
11
12
  - Olle Jonsson
12
13
  - Benoit Daloze
13
14
  - Denis Talakevich
14
15
  - Flavio Fernandes
15
16
  - Jacob Frautschi
16
- - Korbin Hoffman
17
- autorequire:
18
17
  bindir: bin
19
18
  cert_chain:
20
19
  - |
@@ -46,7 +45,7 @@ cert_chain:
46
45
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
47
46
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
48
47
  -----END CERTIFICATE-----
49
- date: 2024-08-22 00:00:00.000000000 Z
48
+ date: 2025-02-15 00:00:00.000000000 Z
50
49
  dependencies:
51
50
  - !ruby/object:Gem::Dependency
52
51
  name: async-http
@@ -76,21 +75,20 @@ dependencies:
76
75
  - - ">="
77
76
  - !ruby/object:Gem::Version
78
77
  version: '0'
79
- description:
80
- email:
81
78
  executables: []
82
79
  extensions: []
83
80
  extra_rdoc_files: []
84
81
  files:
85
- - changes.md
86
82
  - examples/topics.rb
87
83
  - lib/async/http/faraday.rb
88
84
  - lib/async/http/faraday/adapter.rb
89
85
  - lib/async/http/faraday/clients.rb
90
86
  - lib/async/http/faraday/default.rb
87
+ - lib/async/http/faraday/register.rb
91
88
  - lib/async/http/faraday/version.rb
92
89
  - license.md
93
90
  - readme.md
91
+ - releases.md
94
92
  homepage: https://github.com/socketry/async-http-faraday
95
93
  licenses:
96
94
  - MIT
@@ -98,7 +96,6 @@ metadata:
98
96
  documentation_uri: https://socketry.github.io/async-http-faraday/
99
97
  funding_uri: https://github.com/sponsors/ioquatix
100
98
  source_code_uri: https://github.com/socketry/async-http.git
101
- post_install_message:
102
99
  rdoc_options: []
103
100
  require_paths:
104
101
  - lib
@@ -113,8 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
110
  - !ruby/object:Gem::Version
114
111
  version: '0'
115
112
  requirements: []
116
- rubygems_version: 3.5.11
117
- signing_key:
113
+ rubygems_version: 3.6.2
118
114
  specification_version: 4
119
115
  summary: Provides an adaptor between async-http and faraday.
120
116
  test_files: []
metadata.gz.sig CHANGED
Binary file
data/changes.md DELETED
@@ -1,38 +0,0 @@
1
- # v0.18.0
2
-
3
- ## Config Block
4
-
5
- The `config_block` provided to the adapter must now return `nil`, `client` or a middleware wrapper around `client`.
6
-
7
- ```ruby
8
- Faraday.new do |builder|
9
- builder.adapter :async_http do |client|
10
- # Option 1 (same as returning `nil`), use client as is:
11
- client # Use `client` as is.
12
-
13
- # Option 2, wrap client in a middleware:
14
- Async::HTTP::Middleware::LocationRedirector.new(client)
15
- end
16
- end
17
- ```
18
-
19
- # v0.17.0
20
-
21
- ## Per-thread Client Cache
22
-
23
- The default adapter now uses a per-thread client cache internally, to improve compatibility with existing code that shares a single `Faraday::Connection` instance across multiple threads.
24
-
25
- ```ruby
26
- adapter = Faraday.new do |builder|
27
- builder.adapter :async_http
28
- end
29
-
30
- 3.times do
31
- Thread.new do
32
- Async do
33
- # Each thread has it's own client cache.
34
- adapter.get('http://example.com')
35
- end
36
- end
37
- end
38
- ```