kataba 1.1.2 → 1.1.3

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kataba/fetcher.rb +33 -2
  3. data/lib/kataba.rb +17 -1
  4. metadata +12 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e2048c2adaac9976b8feb4fcea1da32d937a7d39955152a579f18d81e9fe3f2
4
- data.tar.gz: 806c80fff00c2a8dd637b42e1df485787e041a514ecc6372df5cb4902db8889e
3
+ metadata.gz: 0c1a21b706cc4e327925cd9d936247e6f5ce17ea3964853f1b442e5ee8ecae3b
4
+ data.tar.gz: 11ad87d5a2baede9403e4b83e2e5db01f5f2b8fe9702371228018cb96534ec22
5
5
  SHA512:
6
- metadata.gz: 15b1a25d1ed46d7510f829f4a6b51ca6516ed29edfa011b4a8395cee0bc36092e37d4ecb925e24791da6d4790435896059cabd8fb375b17278c724dff61540c9
7
- data.tar.gz: 64fa54356f4d0c0387a9c52898795462524363b6fccf6632259b635adb7d2c19544760c2e0b91256cf1e22b50a3e3836868ce5581c73499bda3184f32838b086
6
+ metadata.gz: e2bdb712cd9c063469ee35b6dd5c3f1321018fc490ed25cb095c63715aaf63829915db1b99bfac94d87e574c88e301145fde7359cc57139dd1a997d61954bddc
7
+ data.tar.gz: d21c6a7c83b2a93c89115305856cf2824a62cfa75e7aaa32bda7ea0f4d648bb4d8e6e4db3d4e45ea734a2bc495ea33d3737eb62bc85b3fd076958375d3d0e6fa
@@ -32,10 +32,25 @@ module Kataba
32
32
  '/mods/xml.xsd' => '/standards/mods/xml.xsd',
33
33
  }.freeze
34
34
 
35
+ # Seconds to wait for a schema host to accept the connection, and then to
36
+ # deliver the body. Net::HTTP's own defaults are 60s each, which is a
37
+ # fallback rather than a considered number: a schema is a small file from a
38
+ # public host, and both are paid per redirect hop and again on the
39
+ # alternate-scheme attempt, so an unbounded fetch can hold a caller's
40
+ # thread for many minutes.
41
+ DEFAULT_OPEN_TIMEOUT = 3
42
+ DEFAULT_READ_TIMEOUT = 10
43
+
35
44
  class FetchError < StandardError; end
36
45
 
37
- def initialize(uri)
46
+ # A subclass, so a consumer's `rescue FetchError` covers a timeout while
47
+ # one that wants to retry a timeout without retrying a 404 still can.
48
+ class FetchTimeout < FetchError; end
49
+
50
+ def initialize(uri, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT)
38
51
  @original_uri = uri
52
+ @open_timeout = open_timeout
53
+ @read_timeout = read_timeout
39
54
  end
40
55
 
41
56
  def fetch
@@ -75,7 +90,23 @@ module Kataba
75
90
  parsed = URI.parse(uri)
76
91
  http = Net::HTTP.new(parsed.host, parsed.port)
77
92
  http.use_ssl = (parsed.scheme == 'https')
78
- response = http.get(parsed.request_uri)
93
+ http.open_timeout = @open_timeout
94
+ http.read_timeout = @read_timeout
95
+ # Net::HTTP retries an idempotent request once on a read timeout, so the
96
+ # ceiling per hop would otherwise be twice read_timeout. Nothing here
97
+ # reuses a socket, so that retry can only re-wait a timeout that has
98
+ # already expired.
99
+ http.max_retries = 0
100
+
101
+ response =
102
+ begin
103
+ http.get(parsed.request_uri)
104
+ rescue Timeout::Error => e
105
+ # Both Net::OpenTimeout and Net::ReadTimeout are Timeout::Errors, and
106
+ # Timeout::Error is a RuntimeError — so an unwrapped timeout lands in
107
+ # a consumer's generic rescue rather than its fetch-failure branch.
108
+ raise FetchTimeout, "timed out fetching #{uri} (#{e.class}: #{e.message})"
109
+ end
79
110
 
80
111
  if response.is_a?(Net::HTTPRedirection)
81
112
  target = resolve_redirect(parsed, response['location'])
data/lib/kataba.rb CHANGED
@@ -46,9 +46,23 @@ module Kataba
46
46
  # Kataba.configuration.mirror_list = File.join(Rails.root, 'config', 'mirror.yml')
47
47
  attr_accessor :mirror_list
48
48
 
49
+ # Seconds Kataba waits for a schema host to accept a connection, and then
50
+ # to deliver the body. Raise them for a slow mirror; lower them when the
51
+ # caller is a request thread that must not be held. Both are paid per
52
+ # redirect hop and again on the alternate-scheme attempt, so the ceiling
53
+ # for one schema is a multiple of these, not either on its own.
54
+ #
55
+ # Example:
56
+ # Kataba.configuration.open_timeout = 5
57
+ # Kataba.configuration.read_timeout = 20
58
+ attr_accessor :open_timeout
59
+ attr_accessor :read_timeout
60
+
49
61
  # Default configuration values
50
62
  def initialize
51
63
  @offline_storage = "#{Dir.tmpdir}/kataba"
64
+ @open_timeout = Kataba::Fetcher::DEFAULT_OPEN_TIMEOUT
65
+ @read_timeout = Kataba::Fetcher::DEFAULT_READ_TIMEOUT
52
66
  end
53
67
  end
54
68
 
@@ -132,7 +146,9 @@ module Kataba
132
146
  fetch_uri = mirror unless mirror.to_s.empty?
133
147
  end
134
148
 
135
- body = Kataba::Fetcher.new(fetch_uri).fetch
149
+ body = Kataba::Fetcher.new(fetch_uri,
150
+ open_timeout: self.configuration.open_timeout,
151
+ read_timeout: self.configuration.read_timeout).fetch
136
152
 
137
153
  # Write to a .part file first; only rename to the final cache path
138
154
  # after we've confirmed the bytes parse as XML. Without this, a
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kataba
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cliff
@@ -14,56 +14,56 @@ dependencies:
14
14
  name: nokogiri
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.19'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.19'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: webmock
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  description: Kataba allows for mirroring and offline storage of XSD files, to enhance
@@ -85,16 +85,16 @@ require_paths:
85
85
  - lib
86
86
  required_ruby_version: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - ">="
88
+ - - '>='
89
89
  - !ruby/object:Gem::Version
90
90
  version: '3.2'
91
91
  required_rubygems_version: !ruby/object:Gem::Requirement
92
92
  requirements:
93
- - - ">="
93
+ - - '>='
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
96
  requirements: []
97
- rubygems_version: 3.2.33
97
+ rubygems_version: 3.0.9
98
98
  signing_key:
99
99
  specification_version: 4
100
100
  summary: XML Schema Definition (XSD) mirroring and offline validation for Nokogiri