async-http-faraday 0.18.0 → 0.20.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/examples/topics.rb +4 -4
- data/lib/async/http/faraday/adapter.rb +79 -19
- data/lib/async/http/faraday/clients.rb +5 -5
- data/lib/async/http/faraday/default.rb +1 -1
- data/lib/async/http/faraday/version.rb +1 -1
- data/license.md +2 -2
- data/readme.md +23 -2
- data/releases.md +83 -0
- data.tar.gz.sig +0 -0
- metadata +8 -12
- metadata.gz.sig +0 -0
- data/changes.md +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c35355716bc9483c9f0dcd3070e31cfa0570e49e20d25f96fa429c06d55fef5f
|
4
|
+
data.tar.gz: 8781699d3bef67478a25bee464f7ccd9bb7cfcf39dae30879f7ad2c09b767e9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 785d20de694024d75fd214bdfbf0680d7de1e0cb8fb695434186b51c829b2b04c9c957a6cab120ce64b75b7daa57c9fa26cd19940e22296015183793ec2bbac3
|
7
|
+
data.tar.gz: 4f3cf8059b823e6db1b2be08eb76cd49d8383deb1685e8bafb31796d8c23a0f67672062c6739097a71dd944f48e346c74b9ca1c01a34ebbf0736c39fe049bebc
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/examples/topics.rb
CHANGED
@@ -6,14 +6,14 @@
|
|
6
6
|
|
7
7
|
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
8
8
|
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
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 =
|
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
|
@@ -8,16 +8,18 @@
|
|
8
8
|
# Copyright, 2023, by Genki Takiuchi.
|
9
9
|
# Copyright, 2023, by Flavio Fernandes.
|
10
10
|
# Copyright, 2024, by Jacob Frautschi.
|
11
|
-
# Copyright,
|
11
|
+
# Copyright, 2025, by Nikolaos Anastopoulos.
|
12
12
|
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require 'kernel/sync'
|
13
|
+
require "faraday"
|
14
|
+
require "faraday/adapter"
|
16
15
|
|
17
|
-
require
|
18
|
-
require
|
16
|
+
require "async/barrier"
|
17
|
+
require "kernel/sync"
|
19
18
|
|
20
|
-
|
19
|
+
require "async/http/client"
|
20
|
+
require "async/http/proxy"
|
21
|
+
|
22
|
+
require_relative "clients"
|
21
23
|
|
22
24
|
module Async
|
23
25
|
module HTTP
|
@@ -48,8 +50,53 @@ module Async
|
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
53
|
+
# Implement the Faraday parallel manager interface, using Async.
|
54
|
+
class ParallelManager
|
55
|
+
# Create a new parallel manager.
|
56
|
+
def initialize(options = {})
|
57
|
+
@options = options
|
58
|
+
@barrier = nil
|
59
|
+
end
|
60
|
+
|
61
|
+
# @deprecated Please update your Faraday version!
|
62
|
+
def run
|
63
|
+
if $VERBOSE
|
64
|
+
warn "Please update your Faraday version!", uplevel: 2
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Run the given block asynchronously, using the barrier if available.
|
69
|
+
def async(&block)
|
70
|
+
if @barrier
|
71
|
+
@barrier.async(&block)
|
72
|
+
else
|
73
|
+
Sync(&block)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Execute the given block which can perform multiple concurrent requests, waiting for them all to complete.
|
78
|
+
def execute(&block)
|
79
|
+
Sync do
|
80
|
+
@barrier = Async::Barrier.new
|
81
|
+
|
82
|
+
yield
|
83
|
+
|
84
|
+
@barrier.wait
|
85
|
+
ensure
|
86
|
+
@barrier&.stop
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
51
91
|
# An adapter that allows Faraday to use Async::HTTP as the underlying HTTP client.
|
52
92
|
class Adapter < ::Faraday::Adapter
|
93
|
+
self.supports_parallel = true
|
94
|
+
|
95
|
+
# Create a new parallel manager, which is used to handle multiple concurrent requests.
|
96
|
+
def self.setup_parallel_manager(**options)
|
97
|
+
ParallelManager.new(options)
|
98
|
+
end
|
99
|
+
|
53
100
|
# The exceptions that are considered connection errors and result in a `Faraday::ConnectionFailed` exception.
|
54
101
|
CONNECTION_EXCEPTIONS = [
|
55
102
|
Errno::EADDRNOTAVAIL,
|
@@ -96,8 +143,23 @@ module Async
|
|
96
143
|
super
|
97
144
|
|
98
145
|
# For compatibility with the default adapter:
|
99
|
-
env.url.path =
|
146
|
+
env.url.path = "/" if env.url.path.empty?
|
147
|
+
|
148
|
+
if parallel_manager = env.parallel_manager
|
149
|
+
parallel_manager.async do
|
150
|
+
perform_request(env)
|
151
|
+
env.response.finish(env)
|
152
|
+
end
|
153
|
+
else
|
154
|
+
perform_request(env)
|
155
|
+
end
|
100
156
|
|
157
|
+
@app.call(env)
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def perform_request(env)
|
101
163
|
with_client(env) do |endpoint, client|
|
102
164
|
if body = env.body
|
103
165
|
# We need to ensure the body is wrapped in a Readable object so that it can be read in chunks:
|
@@ -124,19 +186,19 @@ module Async
|
|
124
186
|
response = env.stream_response do |&on_data|
|
125
187
|
response = client.call(request)
|
126
188
|
|
189
|
+
save_response(env, response.status, nil, response.headers, finished: false)
|
190
|
+
|
127
191
|
response.each do |chunk|
|
128
192
|
on_data.call(chunk)
|
129
193
|
end
|
130
194
|
|
131
195
|
response
|
132
196
|
end
|
133
|
-
|
134
|
-
save_response(env, response.status, nil, response.headers)
|
135
197
|
else
|
136
198
|
response = client.call(request)
|
137
|
-
|
138
|
-
save_response(env, response.status, encoded_body(response), response.headers)
|
139
199
|
end
|
200
|
+
|
201
|
+
save_response(env, response.status, encoded_body(response), response.headers)
|
140
202
|
end
|
141
203
|
end
|
142
204
|
|
@@ -149,8 +211,6 @@ module Async
|
|
149
211
|
raise ::Faraday::ConnectionFailed, e
|
150
212
|
end
|
151
213
|
|
152
|
-
private
|
153
|
-
|
154
214
|
def with_client(env)
|
155
215
|
Sync do
|
156
216
|
endpoint = Endpoint.new(env.url)
|
@@ -181,11 +241,11 @@ module Async
|
|
181
241
|
|
182
242
|
def encoded_body(response)
|
183
243
|
body = response.read
|
184
|
-
return
|
185
|
-
content_type = response.headers[
|
244
|
+
return +"" if body.nil?
|
245
|
+
content_type = response.headers["content-type"]
|
186
246
|
return body unless content_type
|
187
247
|
params = extract_type_parameters(content_type)
|
188
|
-
if charset = params[
|
248
|
+
if charset = params["charset"]
|
189
249
|
body = body.dup if body.frozen?
|
190
250
|
body.force_encoding(charset)
|
191
251
|
end
|
@@ -196,10 +256,10 @@ module Async
|
|
196
256
|
|
197
257
|
def extract_type_parameters(content_type)
|
198
258
|
result = {}
|
199
|
-
list = content_type.split(
|
259
|
+
list = content_type.split(";")
|
200
260
|
list.shift
|
201
261
|
list.each do |param|
|
202
|
-
key, value = *param.split(
|
262
|
+
key, value = *param.split("=", 2)
|
203
263
|
result[key.strip] = value.strip
|
204
264
|
end
|
205
265
|
result
|
@@ -3,12 +3,12 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
6
|
+
require "faraday"
|
7
|
+
require "faraday/adapter"
|
8
|
+
require "kernel/sync"
|
9
9
|
|
10
|
-
require
|
11
|
-
require
|
10
|
+
require "async/http/client"
|
11
|
+
require "async/http/proxy"
|
12
12
|
|
13
13
|
module Async
|
14
14
|
module HTTP
|
data/license.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# MIT License
|
2
2
|
|
3
|
-
Copyright, 2018-
|
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,
|
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
@@ -9,9 +9,30 @@ Provides an adaptor for [Faraday](https://github.com/lostisland/faraday) to perf
|
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
|
-
Please see the [project documentation](https://socketry.github.io/async-http/) for more details.
|
12
|
+
Please see the [project documentation](https://socketry.github.io/async-http-faraday/) for more details.
|
13
13
|
|
14
|
-
- [Getting Started](https://socketry.github.io/async-http/guides/getting-started/index) - This guide explains how to use use `Async::HTTP::Faraday` as a drop-in replacement for improved concurrency.
|
14
|
+
- [Getting Started](https://socketry.github.io/async-http-faraday/guides/getting-started/index) - This guide explains how to use use `Async::HTTP::Faraday` as a drop-in replacement for improved concurrency.
|
15
|
+
|
16
|
+
## Releases
|
17
|
+
|
18
|
+
Please see the [project releases](https://socketry.github.io/async-http-faraday/releases/index) for all releases.
|
19
|
+
|
20
|
+
### v0.20.0
|
21
|
+
|
22
|
+
- Implement the new response streaming interface, which provides the initial response status code and headers before streaming the response body.
|
23
|
+
- An empty response now sets the response body to an empty string rather than `nil` as required by the Faraday specification.
|
24
|
+
|
25
|
+
### v0.19.0
|
26
|
+
|
27
|
+
- [Support `in_parallel`](https://socketry.github.io/async-http-faraday/releases/index#support-in_parallel)
|
28
|
+
|
29
|
+
### v0.18.0
|
30
|
+
|
31
|
+
- [Config Block](https://socketry.github.io/async-http-faraday/releases/index#config-block)
|
32
|
+
|
33
|
+
### v0.17.0
|
34
|
+
|
35
|
+
- [Per-thread Client Cache](https://socketry.github.io/async-http-faraday/releases/index#per-thread-client-cache)
|
15
36
|
|
16
37
|
## Contributing
|
17
38
|
|
data/releases.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# Releases
|
2
|
+
|
3
|
+
## v0.20.0
|
4
|
+
|
5
|
+
- Implement the new response streaming interface, which provides the initial response status code and headers before streaming the response body.
|
6
|
+
- An empty response now sets the response body to an empty string rather than `nil` as required by the Faraday specification.
|
7
|
+
|
8
|
+
## v0.19.0
|
9
|
+
|
10
|
+
### Support `in_parallel`
|
11
|
+
|
12
|
+
The adapter now supports the `in_parallel` method, which allows multiple requests to be made concurrently.
|
13
|
+
|
14
|
+
``` ruby
|
15
|
+
adapter = Faraday.new(bound_url) do |builder|
|
16
|
+
builder.adapter :async_http
|
17
|
+
end
|
18
|
+
|
19
|
+
response1 = response2 = response3 = nil
|
20
|
+
|
21
|
+
adapter.in_parallel do
|
22
|
+
response1 = adapter.get("/index")
|
23
|
+
response2 = adapter.get("/index")
|
24
|
+
response3 = adapter.get("/index")
|
25
|
+
end
|
26
|
+
|
27
|
+
puts response1.body # => "Hello World"
|
28
|
+
puts response2.body # => "Hello World"
|
29
|
+
puts response3.body # => "Hello World"
|
30
|
+
```
|
31
|
+
|
32
|
+
This is primarily for compatibility with existing code. If you are designing a new library, you should just use `Async` directly:
|
33
|
+
|
34
|
+
``` ruby
|
35
|
+
Async do
|
36
|
+
response1 = Async{adapter.get("/index")}
|
37
|
+
response2 = Async{adapter.get("/index")}
|
38
|
+
response3 = Async{adapter.get("/index")}
|
39
|
+
|
40
|
+
puts response1.wait.body # => "Hello World"
|
41
|
+
puts response2.wait.body # => "Hello World"
|
42
|
+
puts response3.wait.body # => "Hello World"
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
## v0.18.0
|
47
|
+
|
48
|
+
### Config Block
|
49
|
+
|
50
|
+
The `config_block` provided to the adapter must now return `nil`, `client` or a middleware wrapper around `client`.
|
51
|
+
|
52
|
+
``` ruby
|
53
|
+
Faraday.new do |builder|
|
54
|
+
builder.adapter :async_http do |client|
|
55
|
+
# Option 1 (same as returning `nil`), use client as is:
|
56
|
+
client # Use `client` as is.
|
57
|
+
|
58
|
+
# Option 2, wrap client in a middleware:
|
59
|
+
Async::HTTP::Middleware::LocationRedirector.new(client)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
## v0.17.0
|
65
|
+
|
66
|
+
### Per-thread Client Cache
|
67
|
+
|
68
|
+
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.
|
69
|
+
|
70
|
+
``` ruby
|
71
|
+
adapter = Faraday.new do |builder|
|
72
|
+
builder.adapter :async_http
|
73
|
+
end
|
74
|
+
|
75
|
+
3.times do
|
76
|
+
Thread.new do
|
77
|
+
Async do
|
78
|
+
# Each thread has it's own client cache.
|
79
|
+
adapter.get('http://example.com')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
```
|
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.
|
4
|
+
version: 0.20.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:
|
48
|
+
date: 2025-01-23 00:00:00.000000000 Z
|
50
49
|
dependencies:
|
51
50
|
- !ruby/object:Gem::Dependency
|
52
51
|
name: async-http
|
@@ -76,13 +75,10 @@ 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
|
@@ -91,13 +87,14 @@ files:
|
|
91
87
|
- lib/async/http/faraday/version.rb
|
92
88
|
- license.md
|
93
89
|
- readme.md
|
94
|
-
|
90
|
+
- releases.md
|
91
|
+
homepage: https://github.com/socketry/async-http-faraday
|
95
92
|
licenses:
|
96
93
|
- MIT
|
97
94
|
metadata:
|
98
|
-
documentation_uri: https://socketry.github.io/async-http/
|
95
|
+
documentation_uri: https://socketry.github.io/async-http-faraday/
|
96
|
+
funding_uri: https://github.com/sponsors/ioquatix
|
99
97
|
source_code_uri: https://github.com/socketry/async-http.git
|
100
|
-
post_install_message:
|
101
98
|
rdoc_options: []
|
102
99
|
require_paths:
|
103
100
|
- lib
|
@@ -112,8 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
109
|
- !ruby/object:Gem::Version
|
113
110
|
version: '0'
|
114
111
|
requirements: []
|
115
|
-
rubygems_version: 3.
|
116
|
-
signing_key:
|
112
|
+
rubygems_version: 3.6.2
|
117
113
|
specification_version: 4
|
118
114
|
summary: Provides an adaptor between async-http and faraday.
|
119
115
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|
data/changes.md
DELETED
@@ -1,17 +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
|
-
```
|