fetch-api 0.4.2 → 0.5.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: 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