async-http-faraday 0.19.0 → 0.21.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: 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
- ```