fetch-api 0.4.1 → 0.4.3

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: ff43ec8ec36d621acb463b7327146e89df97446714df7747626276bb51ff4c18
4
- data.tar.gz: de99e42e871912c41df6a5afabb1200f662d5aeba7b6659a4483434c8ddca3c7
3
+ metadata.gz: eb43f07388e02a5f1ec3ccf700a634962896b68e8de60c402aacfe078499dc06
4
+ data.tar.gz: 228e63fa8ba87bdb73f4ed82dd92af70724bb5e3c0a10c2be1849bba3752b846
5
5
  SHA512:
6
- metadata.gz: 7b56ad7b6ac2788343928c4686f48de71e1dc57491e9e13efa5cc479f4f7f57af9d4efad3e7a79cf75fd287d683bb21ec053b69de0c66cdd39a0aef571f86c7b
7
- data.tar.gz: 8895b9835e6637a9d4cd845708e2a133b2f6239baab1729478f16ae9f25ea3df927d678c41ebfbcc26cb3482a43c5fb616779df89a21a8a1aa634f0e18ebe392
6
+ metadata.gz: 99785c3983dbf1e311e3e845ad92a41791af9089b1ecf349973e5a3a14159b1ec855b07c16f46980248b1f8375d3761fd6696cebde999763053a178117257510
7
+ data.tar.gz: 6c969cd4edfc77256e960cab56d7fe9db4a345f754e811e278b18d27900c393625ead267a566abb4334e743270b181ac9921fdfdc51f45f715da8f8701ed28cb
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Fetch API for Ruby
1
+ # Fetch::API
2
2
 
3
3
  Ruby's Net::HTTP is very powerful, but has a complicated API. OpenURI is easy to use, but has limited functionality. Third-party HTTP clients each have different APIs, and it can sometimes be difficult to learn how to use them.
4
4
 
5
- There is one HTTP client that we can all use. It is the browser's Fetch API. This is an HTTP client for Ruby that can be used in a way that is similar to the Fetch API.
5
+ There is one HTTP client that we can all use. It is the browser's Fetch API. Fetch::API is an HTTP client for Ruby that can be used in a way that is similar to the Fetch API.
6
6
 
7
7
  This is not intended to be a complete copy of the Fetch API. For example, responses are returned synchronously rather than asynchronously, as that is more familiar behavior for Ruby programmers. It is only "like" the Fetch API.
8
8
 
@@ -102,16 +102,16 @@ res = fetch('http://example.com', **{
102
102
  })
103
103
  ```
104
104
 
105
- ## Connection pooling
105
+ ### Connection pooling
106
106
 
107
- Fetch API automatically pools and reuses connections to the same origin. Connections are closed after a certain amount of time has passed since the last use, and a new connection is used the next time. Different connections are returned for different threads (in other words, Fetch API is thread-safe).
107
+ Fetch::API automatically pools and reuses connections to the same origin. Connections are closed after a certain amount of time has passed since the last use, and a new connection is used the next time. Different connections are returned for different threads (in other words, Fetch::API is thread-safe).
108
108
 
109
- These values (in seconds) can be configured as follows:
109
+ These values can be configured as follows (in seconds):
110
110
 
111
111
  ``` ruby
112
112
  Fetch.configure do |config|
113
- config.connection_max_idle_time = 10 # default
114
- config.keep_alive_timeout = 2 # default
113
+ config.max_idle_time = 30 # default
114
+ config.keep_alive_timeout = 15 # default
115
115
  end
116
116
  ```
117
117
 
data/lib/fetch/client.rb CHANGED
@@ -48,7 +48,10 @@ module Fetch
48
48
  when Net::HTTPRedirection
49
49
  case redirect.to_s
50
50
  when 'follow'
51
- fetch(res['Location'], method:, headers:, body:, redirect:, _redirected: true) # steep:ignore ArgumentTypeMismatch
51
+ # @type var location: String
52
+ location = res['Location']
53
+
54
+ fetch(location, method:, headers:, body:, redirect:, _redirected: true)
52
55
  when 'error'
53
56
  raise RedirectError, "redirected to #{res['Location']}"
54
57
  when 'manual'
@@ -67,7 +70,7 @@ module Fetch
67
70
  if pool = Thread.current.thread_variable_get(:fetch_connection_pool)
68
71
  pool
69
72
  else
70
- Thread.current.thread_variable_set :fetch_connection_pool, ConnectionPool.new
73
+ Thread.current.thread_variable_set(:fetch_connection_pool, ConnectionPool.new)
71
74
  end
72
75
  end
73
76
 
data/lib/fetch/config.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fetch
2
- Config = Struct.new(:connection_max_idle_time, :keep_alive_timeout)
2
+ Config = Struct.new(:max_idle_time, :keep_alive_timeout)
3
3
  end
@@ -4,74 +4,67 @@ 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
-
17
13
  sweep
18
14
 
19
- Thread.stop if @connections.empty?
15
+ if @connections.empty?
16
+ Thread.stop
17
+ else
18
+ sleep 1
19
+ end
20
20
  end
21
21
  }
22
22
  end
23
23
 
24
24
  def with_connection(uri, &block)
25
- conn = acquire(uri)
25
+ conn = checkout(uri)
26
26
 
27
27
  begin
28
28
  block.call(conn)
29
29
  ensure
30
- release uri
30
+ checkin uri, conn
31
31
  end
32
32
  end
33
33
 
34
34
  private
35
35
 
36
- def acquire(uri)
37
- @mutex.synchronize {
38
- entry = @connections[uri.origin]
39
-
40
- if entry
41
- entry.in_use = true
42
-
43
- entry.connection
44
- else
45
- Net::HTTP.new(uri.host, uri.port).tap {|http| # steep:ignore ArgumentTypeMismatch
46
- http.use_ssl = uri.scheme == 'https'
47
- http.keep_alive_timeout = Fetch.config.keep_alive_timeout
48
-
49
- @connections[uri.origin] = Entry.new(connection: http, in_use: true)
50
-
51
- http.start
52
- }
53
- end
54
- }.tap {
55
- @sweeper.wakeup
56
- }
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
42
+
43
+ Net::HTTP.new(host, uri.port).tap {|http|
44
+ http.use_ssl = uri.scheme == 'https'
45
+ http.keep_alive_timeout = Fetch.config.keep_alive_timeout
46
+ http.start
47
+ }
48
+ end
57
49
  end
58
50
 
59
- def release(uri)
51
+ def checkin(uri, conn)
60
52
  @mutex.synchronize do
61
- if entry = @connections[uri.origin]
62
- entry.in_use = false
63
- entry.last_used = Time.now
64
- end
53
+ @connections[uri.origin] = [conn, Time.now]
65
54
  end
55
+
56
+ @sweeper.wakeup
66
57
  end
67
58
 
68
59
  def sweep
69
60
  @mutex.synchronize do
70
- @connections.each do |origin, entry|
71
- next if entry.in_use
72
-
73
- if entry.last_used + Fetch.config.connection_max_idle_time < Time.now
74
- entry.connection.finish
61
+ @connections.each do |origin, (conn, last_used)|
62
+ if last_used + Fetch.config.max_idle_time < Time.now
63
+ begin
64
+ conn.finish
65
+ rescue IOError
66
+ # do nothing
67
+ end
75
68
 
76
69
  @connections.delete origin
77
70
  end
data/lib/fetch/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fetch
2
- VERSION = '0.4.1'
2
+ VERSION = '0.4.3'
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.connection_max_idle_time = 10
14
- config.keep_alive_timeout = 2
13
+ config.max_idle_time = 30
14
+ config.keep_alive_timeout = 15
15
15
  end
16
16
  end
data/sig/fetch/config.rbs CHANGED
@@ -1,6 +1,6 @@
1
1
  module Fetch
2
2
  class Config
3
- attr_accessor connection_max_idle_time: Integer
3
+ attr_accessor max_idle_time: Integer
4
4
  attr_accessor keep_alive_timeout: Integer
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.1
4
+ version: 0.4.3
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-10 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