fetch-api 0.4.2 → 0.5.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: 4217a0ddb4ec43da71a630ba5de24d9a6a02af0f5cf2b39286702c1cc512c699
4
- data.tar.gz: 05abc4f266fab3577c2223de54957b8c6a84e7b3ccc24df428f40e771c1e311d
3
+ metadata.gz: 1f3850dbddc3e46b5c6e59efdde4538c5c94e0464e94fb3ddd615e93d48a4e4f
4
+ data.tar.gz: 5783d23d208526c9f009f6ad15317a136ad22ddbb58d403cad655e7c6909034a
5
5
  SHA512:
6
- metadata.gz: c7caa0c96f93f03ae799a121fc7f25410f401c9c192a7546f97627c760cb638627b79d01b0911ed8a4f2ebaacdaa619e86e84a2b88443a721f066a4a9fd4c1d9
7
- data.tar.gz: 826e3c4ff75b7b3c3f0886949a6fe141cdd360fd31da86b42b08aabde98b0a608ac6f51561b65819b65622a1a2f344f5e6784505bafb990d0aad300ac8f378b6
6
+ metadata.gz: 77c50b51b5e084f405e26a6222bc388e1b2843f3f856db2f4f242fe64491ec31b8dd2f00532ff7099ab915b44bcf21f5edca3ca66bb5d9a0218f0f00c26100a3
7
+ data.tar.gz: bd4668f688f2a9cf06bab9eec7f471a61b8e5bd3c2d0408521f46b6b2b61e2054cf7057f71ebaf53028d20b8363f9e01586fa75bfec8d5ef7c1ad3b9e49a3d9c
data/README.md CHANGED
@@ -110,8 +110,22 @@ These values can be configured as follows (in seconds):
110
110
 
111
111
  ``` ruby
112
112
  Fetch.configure do |config|
113
- config.max_idle_time = 10 # default
114
- config.keep_alive_timeout = 2 # default
113
+ config.connection_max_idle_time = 30 # default
114
+ end
115
+ ```
116
+
117
+ ### Customizing connection
118
+
119
+ If the lambda is set to `Fetch.config.on_connection_create`, it is called before the connection is initiated. The arguments are a Net::HTTP instance and a URI object. Note that `Net::HTTP#use_ssl` is automatically set according to the URL schema.
120
+
121
+ ``` ruby
122
+ Fetch.configure do |config|
123
+ config.on_connection_create = -> (conn, uri) {
124
+ if uri.host == 'example.com'
125
+ conn.open_timeout = 5
126
+ conn.read_timeout = 5
127
+ end
128
+ }
115
129
  end
116
130
  ```
117
131
 
data/lib/fetch/api.rb CHANGED
@@ -4,8 +4,8 @@ module Fetch
4
4
  module API
5
5
  module_function
6
6
 
7
- def fetch(...)
8
- Client.instance.fetch(...)
7
+ def fetch(resource, method: :get, headers: [], body: nil, redirect: :follow)
8
+ Client.instance.fetch(resource, method:, headers:, body:, redirect:)
9
9
  end
10
10
  end
11
11
  end
data/lib/fetch/client.rb CHANGED
@@ -15,7 +15,7 @@ module Fetch
15
15
  class Client
16
16
  include Singleton
17
17
 
18
- def fetch(resource, method: :get, headers: [], body: nil, redirect: :follow, _redirected: false)
18
+ def fetch(resource, method:, headers:, body:, redirect:, redirected: false)
19
19
  uri = URI.parse(resource)
20
20
  req = Net::HTTP.const_get(method.capitalize).new(uri)
21
21
 
@@ -51,16 +51,16 @@ module Fetch
51
51
  # @type var location: String
52
52
  location = res['Location']
53
53
 
54
- fetch(location, method:, headers:, body:, redirect:, _redirected: true) # steep:ignore ArgumentTypeMismatch
54
+ fetch(location, method:, headers:, body:, redirect:, redirected: true)
55
55
  when 'error'
56
56
  raise RedirectError, "redirected to #{res['Location']}"
57
57
  when 'manual'
58
- to_response(resource, res, _redirected)
58
+ to_response(resource, res, redirected)
59
59
  else
60
60
  raise ArgumentError, "invalid redirect option: #{redirect.inspect}"
61
61
  end
62
62
  else
63
- to_response(resource, res, _redirected)
63
+ to_response(resource, res, redirected)
64
64
  end
65
65
  end
66
66
 
data/lib/fetch/config.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fetch
2
- Config = Struct.new(:max_idle_time, :keep_alive_timeout)
2
+ Config = Struct.new(:connection_max_idle_time, :on_connection_create)
3
3
  end
@@ -4,76 +4,69 @@ require 'thread'
4
4
 
5
5
  module Fetch
6
6
  class ConnectionPool
7
- Entry = Struct.new(:connection, :in_use, :last_used, keyword_init: true)
8
-
9
7
  def initialize
10
8
  @connections = {}
11
9
  @mutex = Mutex.new
12
10
 
13
11
  @sweeper = Thread.new {
14
12
  loop do
15
- sleep 1
16
13
  sweep
17
14
 
18
- Thread.stop if @connections.empty?
15
+ if @connections.empty?
16
+ Thread.stop
17
+ else
18
+ sleep 1
19
+ end
19
20
  end
20
21
  }
21
22
  end
22
23
 
23
24
  def with_connection(uri, &block)
24
- conn = acquire(uri)
25
+ conn = checkout(uri)
25
26
 
26
27
  begin
27
28
  block.call(conn)
28
29
  ensure
29
- release uri
30
+ checkin uri, conn
30
31
  end
31
32
  end
32
33
 
33
34
  private
34
35
 
35
- def acquire(uri)
36
- @mutex.synchronize {
37
- entry = @connections[uri.origin]
38
-
39
- if entry
40
- entry.in_use = true
36
+ def checkout(uri)
37
+ if entry = @mutex.synchronize { @connections.delete(uri.origin) }
38
+ entry.first
39
+ else
40
+ # @type var host: String
41
+ host = uri.host
41
42
 
42
- entry.connection
43
- else
44
- # @type var host: String
45
- host = uri.host
43
+ Net::HTTP.new(host, uri.port).tap {|http|
44
+ http.use_ssl = uri.scheme == 'https'
46
45
 
47
- Net::HTTP.new(host, uri.port).tap {|http|
48
- http.use_ssl = uri.scheme == 'https'
49
- http.keep_alive_timeout = Fetch.config.keep_alive_timeout
46
+ Fetch.config.on_connection_create.call http, uri
50
47
 
51
- http.start
52
-
53
- @connections[uri.origin] = Entry.new(connection: http, in_use: true)
54
- }
55
- end
56
- }.tap {
57
- @sweeper.wakeup
58
- }
48
+ http.start
49
+ }
50
+ end
59
51
  end
60
52
 
61
- def release(uri)
53
+ def checkin(uri, conn)
62
54
  @mutex.synchronize do
63
- if entry = @connections[uri.origin]
64
- entry.in_use = false
65
- entry.last_used = Time.now
66
- end
55
+ @connections[uri.origin] = [conn, Time.now]
67
56
  end
57
+
58
+ @sweeper.wakeup
68
59
  end
69
60
 
70
61
  def sweep
71
62
  @mutex.synchronize do
72
- @connections.each do |origin, entry|
73
- next if entry.in_use
74
-
75
- if entry.last_used + Fetch.config.max_idle_time < Time.now
76
- entry.connection.finish
63
+ @connections.each do |origin, (conn, last_used)|
64
+ if last_used + Fetch.config.connection_max_idle_time < Time.now
65
+ begin
66
+ conn.finish
67
+ rescue IOError
68
+ # do nothing
69
+ end
77
70
 
78
71
  @connections.delete origin
79
72
  end
data/lib/fetch/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fetch
2
- VERSION = '0.4.2'
2
+ VERSION = '0.5.0'
3
3
  end
data/lib/fetch.rb CHANGED
@@ -10,7 +10,7 @@ module Fetch
10
10
  end
11
11
 
12
12
  configure do |config|
13
- config.max_idle_time = 10
14
- config.keep_alive_timeout = 2
13
+ config.connection_max_idle_time = 30
14
+ config.on_connection_create = -> (*) {}
15
15
  end
16
16
  end
data/sig/fetch/client.rbs CHANGED
@@ -4,11 +4,11 @@ module Fetch
4
4
 
5
5
  def fetch: (
6
6
  string,
7
- ?method: String | Symbol,
8
- ?headers: _Each[[_ToS, _ToS]],
9
- ?body: (String | FormData | URLSearchParams)?,
10
- ?redirect: 'follow' | 'error' | 'manual' | :follow | :error | :manual,
11
- ?_redirected: bool
7
+ method: String | Symbol,
8
+ headers: _Each[[_ToS, _ToS]],
9
+ body: (String | FormData | URLSearchParams)?,
10
+ redirect: 'follow' | 'error' | 'manual' | :follow | :error | :manual,
11
+ ?redirected: bool
12
12
  ) -> Response
13
13
 
14
14
  private
data/sig/fetch/config.rbs CHANGED
@@ -1,6 +1,6 @@
1
1
  module Fetch
2
2
  class Config
3
- attr_accessor max_idle_time: Integer
4
- attr_accessor keep_alive_timeout: Integer
3
+ attr_accessor connection_max_idle_time: Integer
4
+ attr_accessor on_connection_create: ^(Net::HTTP, URI::HTTP) -> void
5
5
  end
6
6
  end
@@ -1,20 +1,12 @@
1
1
  module Fetch
2
2
  class ConnectionPool
3
- class Entry
4
- attr_accessor connection: Net::HTTP
5
- attr_accessor in_use: bool
6
- attr_accessor last_used: Time
7
-
8
- def initialize: (connection: Net::HTTP, in_use: bool, ?last_used: Time) -> void
9
- end
10
-
11
3
  def initialize: () -> void
12
4
  def with_connection: [T] (URI::HTTP) { (Net::HTTP) -> T } -> T
13
5
 
14
6
  private
15
7
 
16
- def acquire: (URI::HTTP) -> Net::HTTP
17
- def release: (URI::HTTP) -> void
8
+ def checkout: (URI::HTTP) -> Net::HTTP
9
+ def checkin: (URI::HTTP, Net::HTTP) -> void
18
10
  def sweep: () -> void
19
11
  end
20
12
  end
@@ -0,0 +1,3 @@
1
+ module Fetch
2
+ VERSION: String
3
+ end
data/sig/fetch.rbs CHANGED
@@ -1,6 +1,4 @@
1
1
  module Fetch
2
- VERSION: String
3
-
4
2
  attr_accessor self.config: Config
5
3
 
6
4
  def self.configure: () { (Config) -> void } -> void
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fetch-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keita Urashima
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-08 00:00:00.000000000 Z
11
+ date: 2024-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: forwardable
@@ -139,6 +139,7 @@ files:
139
139
  - sig/fetch/headers.rbs
140
140
  - sig/fetch/response.rbs
141
141
  - sig/fetch/url_search_params.rbs
142
+ - sig/fetch/version.rbs
142
143
  homepage: https://github.com/ursm/fetch-api
143
144
  licenses:
144
145
  - MIT
@@ -160,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
161
  - !ruby/object:Gem::Version
161
162
  version: '0'
162
163
  requirements: []
163
- rubygems_version: 3.5.14
164
+ rubygems_version: 3.5.11
164
165
  signing_key:
165
166
  specification_version: 4
166
167
  summary: Something like the Fetch API for Ruby